gpt4 book ai didi

common-lisp - ecase 宏中的子句采用包前缀

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

我正在尝试学习 Practical Common Lisp。我是一个 Lisp 初学者。

我使用“quicklisp”定义了一个包,我使用 (ql:quickload :spam filter) 加载该包

这个包中的函数之一如下所示:

    (defun increment-count (feature type)
(ecase type
(ham (incf (ham-count feature)))
(spam (incf (spam-count feature)))))

当我尝试调用一个在 slime 中调用该函数的函数时,case 语句失败。我认为它失败了,因为编译器已将包名称添加为子句的前缀。

这是我看到的错误:

HAM fell through ECASE expression. Wanted one of (HAM SPAM). [Condition of type SB-KERNEL:CASE-FAILURE]

Restarts: 0: [RETRY] Retry SLIME REPL evaluation request. 1: [*ABORT] Return to SLIME's top level. 2: [ABORT] Abort thread (#)

Backtrace: 0: (SB-KERNEL:CASE-FAILURE ECASE HAM (SPAMFILTER::HAM SPAMFILTER::SPAM)) 1: (SPAMFILTER:INCREMENT-COUNT # HAM) 2: (SPAMFILTER:TRAIN "From [email protected] Mon Sep 23 12:06:27 2002 ..) 3: (SPAMFILTER::TRAIN-FROM-CORPUS #>((#P"/Users/jh/src/lisp/spamfilter/mail/easy_ham/1205.f9d66868c52039f7a147d9e2b4b05e1f" HAM) (#P"/Users/jh/src/lisp/spamfilter/mail/easy_ham/0090.314ec4268af7a3a1974d5e.. 4: (SPAMFILTER:TEST-CLASSIFIER #((#P"/Users/jh/src/lisp/spamfilter/mail/easy_ham/0001.ea7e79d3153e7469e7a9c3e0af6a357e" HAM) (#P"/Users/jh/src/lisp/spamfilter/mail/easy_ham/0002.b3120c4bcbf3101e661161ee7.. 5: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SPAMFILTER:TEST-CLASSIFIER SPAMFILTER:CORPUS 0.1) #) 6: (EVAL (SPAMFILTER:TEST-CLASSIFIER SPAMFILTER:CORPUS 0.1)) --more--

我的猜测是编译器在 Backtrace 0 上添加了前缀:

0: (SB-KERNEL:CASE-FAILURE ECASE HAM (SPAMFILTER::HAM SPAMFILTER::SPAM))

我确信我遗漏了一些明显的东西。

谢谢。

最佳答案

此 REPL 转录本可能具有指导意义。这与编译器添加任何东西没有任何关系,但不同包中的符号不​​一定相同。

首先,使用 spam-filter 包中的符号定义一个包和一些函数:

CL-USER> (defpackage #:spam-filter
(:use "COMMON-LISP"))
#<PACKAGE "SPAM-FILTER">
CL-USER> (in-package #:spam-filter)
#<PACKAGE "SPAM-FILTER">
SPAM-FILTER> (defun test (x)
(ecase x
(ham "ham")
(spam "spam")))
TEST

让我们检查一下它是否有效:

SPAM-FILTER> (test 'spam)
"spam"

好的,现在让我们回到 CL-USER:

SPAM-FILTER> (in-package "CL-USER")
#<PACKAGE "COMMON-LISP-USER">

现在让我们尝试调用spam-filter::test:

CL-USER> (spam-filter::test 'spam)
; Evaluation aborted on #<SB-KERNEL:CASE-FAILURE expected-type:
(MEMBER SPAM-FILTER::HAM SPAM-FILTER::SPAM)
datum: SPAM>.

我们收到错误,因为当前包是 CL-USER,因此读取器读取字符 spam 并实习生“SPAM”以获取符号 cl-user::spam,与 spam-filter::spam相同。让我们尝试使用 spam-filter::spam 调用它:

CL-USER> (spam-filter::test 'spam-filter::spam)
"spam"

毫无疑问,它仍然有效。有关此处发生的更多信息,您可能会喜欢 Ron Garret 的 The Complete Idiot’s Guide to Common Lisp Packages .

关于common-lisp - ecase 宏中的子句采用包前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27049598/

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