gpt4 book ai didi

common-lisp - 为什么符号宏会获得同名的周围 let 绑定(bind)的类型?

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

SBCL 中的 Macroexpand-all 给了我以下扩展:

(SB-CLTL2:MACROEXPAND-ALL
'(LAMBDA (A B)
(DECLARE ((SIGNED-BYTE 4) A))
(+ A B
(SYMBOL-MACROLET ((A 1) (B 2))
(+ A
B)))))
=>
(LAMBDA (A B)
(DECLARE ((SIGNED-BYTE 4) A))
(+ A B
(SYMBOL-MACROLET ((A 1) (B 2))
(+ (THE (SIGNED-BYTE 4) 1)
2))))

为什么 A扩展到 (THE (SIGNED-BYTE 4) 1)而不仅仅是 1 ?

我知道这来自 (DECLARE ((SIGNED-BYTE 4) A)) ,
但这是否会影响 SYMBOL-MACROLET有吗?

它甚至不应该是有效的
扩展到不是 (SIGNED-BYTE 4) 的内容?

最佳答案

免责声明 我不知道这是否真的回答了这个问题。欢迎评论和编辑。

一个开放的问题

正如 Dirk 在评论中所说,在 Common Lisp 中,据说该语言(专用于 declare 形式的部分(link)):

There are certain aspects peculiar to symbol-macrolet. [..] a type declaration of a name defined by symbol-macrolet is equivalent in effect to wrapping a the form mentioning that type around the expansion of the defined symbol.



据我所知,这个问题有些争议,例如 这似乎是一个悬而未决的问题 . 是强制的还是不强制的? 在这里阅读:

Issue SYMBOL-MACROLET-TYPE-DECLARATION Writeup

[..] must (or might) the value returned by MACROEXPAND or MACROEXPAND-1 include a THE form if there are type declarations that apply to the symbol-macro being expanded?



有四个建议, , , 可能 , 和 可能 .在我上面链接的文章中阅读它们。这四个提案中的每一个都有一个基本原理。

SBCL 这样做。我认为这是实现者的选择。

为什么?嗯, 的基本原理是给出一个理由。

有一些优点(?)

例如,对于编译器来说,代码的优化可能更“容易”一些。检查这个。

没有声明,没有 the在扩展中:

拿着这个:
(SB-CLTL2:MACROEXPAND-ALL
'(LAMBDA (A B)
(+ A B
(SYMBOL-MACROLET ((A 1) (B 2))
(+ A B)))))

结果很简单:
(LAMBDA (A B)
(+ A B
(SYMBOL-MACROLET ((A 1) (B 2))
(+ 1 2))))

如果你把后者放在一个你非常想优化的文件中,可以这样说:
(declaim (optimize (speed 3) (debug 0) (safety 0)))

然后你编译它,SBCL 会给你一堆这样的警告:
; note: forced to do GENERIC-+ (cost 10)
; unable to do inline fixnum arithmetic (cost 1) because:
; The first argument is a NUMBER, not a FIXNUM.
; The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &REST T).
; unable to do inline fixnum arithmetic (cost 2) because:
; The first argument is a NUMBER, not a FIXNUM.
; The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &REST T).
; etc.

SBCL 声明 the在扩展中:

现在试试这个:
(SB-CLTL2:MACROEXPAND-ALL
'(LAMBDA (A B)
(DECLARE ((SIGNED-BYTE 4) A))
(declare ((signed-byte 4) B))
(+ A B
(SYMBOL-MACROLET ((A 1) (B 2))
(+ A B)))))

这是扩展:
(LAMBDA (A B)
(DECLARE ((SIGNED-BYTE 4) A))
(DECLARE ((SIGNED-BYTE 4) B))
(+ A B
(SYMBOL-MACROLET ((A 1) (B 2))
(+ (THE (SIGNED-BYTE 4) 1) (THE (SIGNED-BYTE 4) 2)))))

将后者放在一个文件中,放入声明进行优化,编译。你猜怎么了?没有警告。 SBCL 不再提示无法对您的代码进行一些核心优化。它可以做到。因为 (THE (SIGNED-BYTE 4) 1)部分。

More about the the special form

所以也许 这是一种确保您的类型声明也会影响宏形式中的变量,提供类型检查并强制编译器优化代码的能力的方法?

关于common-lisp - 为什么符号宏会获得同名的周围 let 绑定(bind)的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12041136/

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