gpt4 book ai didi

lisp - Clozure Common Lisp 中的 Sharpsign 点宏

转载 作者:行者123 更新时间:2023-12-04 01:02:26 24 4
gpt4 key购买 nike

我想按照“Common Lisp Recipes”一书的建议,在 case 宏中使用常量变量。

  • 10-2。在 CASE 宏中使用常量变量作为键

不幸的是,它在 Clozure CL 中不起作用。

(defpackage #:foo
(:use #:cl))

(in-package #:foo)

(defconstant +one+ 1)
(defconstant +two+ 2)

(defun lol (gg)
(ecase gg
(#.+one+ :one)
(#.+two+ :two)))

此代码加载失败。

 Unbound variable: FOO::+ONE+
[Condition of type UNBOUND-VARIABLE]

Restarts:
0: [CONTINUE] Retry getting the value of FOO::+ONE+.
1: [USE-VALUE] Specify a value of FOO::+ONE+ to use this time.
2: [STORE-VALUE] Specify a value of FOO::+ONE+ to store and use.

该代码在 SBCL 中运行良好。为什么它在 CCL 中不起作用?

我在 macOS 上使用 64 位 Clozure CL 1.12。

最佳答案

CCL 会很乐意为我加载此文件的,我相信任何 CL 都应该这样做。

它不会做什么,如果有任何 CL 会做,我会感到惊讶的是,编译它。它不会编译它,因为 defconstant 没有在编译时定义常量。这意味着,当编译 lol 时,会引用一个尚 undefined variable 。

如果你想像这样处理常量,你需要确保变量在编译时定义的。有两种方法可以做到这一点:

首先,您可以添加合适的eval-whenery,之后相关的源代码块将是:

(eval-when (:compile-toplevel :load-toplevel :execute)
(defconstant +one+ 1)
(defconstant +two+ 2))

(defun lol (gg)
(ecase gg
(#.+one+ :one)
(#.+two+ :two)))

第二种是将常量放在它们自己的文件中,该文件在使用前并加载。通常,这是使用 ASDF 等系统定义工具进行管理的。


注意:我相信任何 CL 都应该能够加载源代码,因为我认为,在加载源代码文件时,甚至需要仅编译器的实现,一次将它们视为一种形式:我不认为换句话说,将 (load "foo.lisp") 转换为 (load (compile-file "foo.lisp")) 是合法的。然而,我对此可能是错误的:我已经有很长一段时间没有以取证的方式阅读规范了。

关于lisp - Clozure Common Lisp 中的 Sharpsign 点宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67839802/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com