【问题标题】:Common Lisp The Language 2 outdated?Common Lisp The Language 2 过时了吗?
【发布时间】:2019-11-23 15:45:12
【问题描述】:

在 CLTL2 中有一个结构示例 ice-cream-factoryfollows,据称它会创建两个构造函数。这是结构定义:

(defstruct (ice-cream-factory 
             (:constructor fabricate-factory 
               (&key (capacity 5) 
                  location 
                  (local-flavors 
                    (case location 
                      ((hawaii) '(pineapple macadamia guava)) 
                      ((massachusetts) '(lobster baked-bean)) 
                      ((california) '(ginger lotus avocado 
                                      bean-sprout garlic)) 
                      ((texas) '(jalapeno barbecue)))) 
                  (flavors (subseq (append local-flavors 
                                           '(vanilla 
                                             chocolate 
                                             strawberry 
                                             pistachio 
                                             maple-walnut 
                                             peppermint)) 
                                   0 capacity))))) 
  (capacity 3) 
  (flavors '(vanilla chocolate strawberry mango)))

CLTL2 状态:

结构类型 ice-cream-factory 有两个构造函数。标准构造函数 make-ice-cream-factory 接受两个名为 :capacity 和 :flavors 的关键字参数。对于这个构造函数,容量槽的默认值为 3,默认的口味列表是美国最喜欢的三人组和一匹黑马(不是死马)。

然而,评估标准构造函数会遇到未定义的函数错误:

(make-ice-cream-factory)

函数 COMMON-LISP-USER::MAKE-ICE-CREAM-FACTORY 是 未定义。

这是因为本书的部分内容不符合defstructs 上的最新标准吗? 指定:constructor 选项我只有一个构造函数fabricate-factory

【问题讨论】:

  • 嗨,你能edit 包含链接中的关键信息的问题吗?这样一来,每个人都不必点击并查找相关信息,并确保在链接页面发生更改或将来停止工作时问题仍然有用。
  • CLtL2 已过时,不能用作可靠的参考。请改用CLHS

标签: struct common-lisp


【解决方案1】:

CLtL2 不仅过时了,而且根本没有真正指定 CL。 CLtL 指定了语言的一个版本,而 CLtL2 只是标准化过程中发生的事情的一些快照。这在当时广为人知,但似乎从那以后被部分遗忘了。

话虽如此,您所指的部分并不是这本书过时的例子:这只是书中的一个错误。 CLtL2 的第 19.6 节“按位置构造函数”以以下文本开头:

如果:constructor 选项作为(:constructor name <arglist>) 给出,那么defstruct 将定义一个“位置”构造函数,而不是创建一个关键字驱动的构造函数,接受其含义由参数的位置而不是通过关键字。

(我已将斜体替换为上面的<angles>。)

但是,您正在查看的示例只是弄错了。不仅是内部不一致:文本讨论了一个函数make-ice-cream-factory,而且示例代码包含make-factory

使示例代码正确的defstruct 形式是

(defstruct (ice-cream-factory 
             (:constructor fabricate-factory 
               (&key (capacity 5) 
                  location 
                  (local-flavors 
                    (case location 
                      ((hawaii) '(pineapple macadamia guava)) 
                      ((massachusetts) '(lobster baked-bean)) 
                      ((california) '(ginger lotus avocado 
                                      bean-sprout garlic)) 
                      ((texas) '(jalapeno barbecue)))) 
                  (flavors (subseq (append local-flavors 
                                           '(vanilla 
                                             chocolate 
                                             strawberry 
                                             pistachio 
                                             maple-walnut 
                                             peppermint)) 
                                   0 capacity))))
             (:constructor make-factory))
  (capacity 3) 
  (flavors '(vanilla chocolate strawberry mango)))

而使文本正确的一个是

(defstruct (ice-cream-factory 
             (:constructor fabricate-factory 
               (&key (capacity 5) 
                  location 
                  (local-flavors 
                    (case location 
                      ((hawaii) '(pineapple macadamia guava)) 
                      ((massachusetts) '(lobster baked-bean)) 
                      ((california) '(ginger lotus avocado 
                                      bean-sprout garlic)) 
                      ((texas) '(jalapeno barbecue)))) 
                  (flavors (subseq (append local-flavors 
                                           '(vanilla 
                                             chocolate 
                                             strawberry 
                                             pistachio 
                                             maple-walnut 
                                             peppermint)) 
                                   0 capacity))))
             (:constructor))
  (capacity 3) 
  (flavors '(vanilla chocolate strawberry mango)))

所有这些都按照 CltL2 在符合 ANSI 的实现中指定。

【讨论】:

    【解决方案2】:

    只有一个构造函数。如果它提到两个,那就是一个错误。

    有关标准 Common Lisp 的详细信息,请查看 ANSI CL 标准和派生文档,例如 HyperSpec 中的 DEFSTRUCT 条目:

    defstruct 仅在没有明确指定 :constructor 选项或指定 :constructor 选项而没有指定名称参数时才创建默认命名的关键字构造函数。

    自从

    (defstruct (ice-cream-factory 
                (:constructor fabricate-factory 
                 (&key (capacity 5) 
                       location 
                       (local-flavors 
                        (case location 
                          ((hawaii) '(pineapple macadamia guava)) 
                          ((massachusetts) '(lobster baked-bean)) 
                          ((california) '(ginger lotus avocado 
                                                 bean-sprout garlic)) 
                          ((texas) '(jalapeno barbecue)))) 
                       (flavors (subseq (append local-flavors 
                                                '(vanilla 
                                                  chocolate 
                                                  strawberry 
                                                  pistachio 
                                                  maple-walnut 
                                                  peppermint)) 
                                        0 capacity))))) 
      (capacity 3) 
      (flavors '(vanilla chocolate strawberry mango)))
    

    有一个名为fabricate-factory的构造函数,不会创建默认名称构造函数。

    【讨论】:

    • 谢谢,我的问题是如果那是 CLTL2 中的不准确信息。
    猜你喜欢
    • 2011-10-17
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 2012-08-06
    • 2014-10-24
    • 2022-11-17
    • 2010-12-15
    相关资源
    最近更新 更多