加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala宏:类型化(又称typechecked)与无类型树之间有什么区别?

发布时间:2020-12-16 09:13:46 所属栏目:安全 来源:网络整理
导读:我正在开始使用 scala宏,它们非常棒,但我遇到了类型(又称typechecked)和无类型树之间的区别. 例如,由于某些原因,您不能使用类型检查的树来调用c.eval.我在scala宏文档中找不到关于这个“typechecked”的文档(我知道他们仍在努力,这可能是某些需要添加的东西)
我正在开始使用 scala宏,它们非常棒,但我遇到了类型(又称typechecked)和无类型树之间的区别.

例如,由于某些原因,您不能使用类型检查的树来调用c.eval.我在scala宏文档中找不到关于这个“typechecked”的文档(我知道他们仍在努力,这可能是某些需要添加的东西).

对树进行类型检查是什么意思?为什么它们如此不同,显然c.eval无法处理类型检查的树(相反会对我更有意义).

我猜这可能是编译器101,但是我没有采取这个方法:(
任何解释或指向文章/文件将不胜感激!

解决方法

理论部分

一旦我们在2.10的编译时/运行时反映中暴露了内部编译器数据结构,这就是scalac的架构特性,开始泄露到公共API中.

粗略地说,scalac的前端由一个解析器和一个打击者组成,它们都与树木一起工作并产生树木.然而,这些树的属性是完全不同的,它来自于解析器产生的树是未归属的(其符号字段设置为NoSymbol,并且它们的tpe字段设置为null),而由typer生成的树被归因.

现在你可能想知道这可以做出什么样的区别,因为它只是符号和tpe,对吧?然而,在scalac中,它不仅仅是这样.为了做好自己的工作,老板改变了它正在处理的AST的结构,摧毁了一些原始的树,并生产了一些合成树.不幸的是,有时这些转换是不可逆转的,这意味着如果一个类型检查树,然后擦除所有分配的属性,则生成的树不再有意义了(https://issues.scala-lang.org/browse/SI-5464).

好的,但为什么会想要删除(或者在scalac的说法,重置,如resetLocalAttrs或resetAllAttrs)属性的类型检查树?那么这个必要性来源于另一个实现细节 – 符号及其所有者链.就在几天之前,我已经写了关于scala内部的内容的一些细节:https://groups.google.com/d/msg/scala-internals/rIyJ4yHdPDU/qS-7DreEbCwJ,但是简而言之,你不能在一些词汇上下文中键入一个树,然后简单地在不同的词汇语境中使用它(这就是基本上需要c.eval).

所以,总结一下在scalac树管理中的最新技术:

>非类型树(也称为解析器树或未归因树)与类型树(也称为树木树,类型树或属性树)观察不同,
>这两种树风味有两个主要区别:a)类型树具有类型检查器设置的符号和类型,b)类型树具有不同的形状.
>通常,如果一些编译器API需要一个树,那么无类型和类型的树都会这样做.然而,在某些情况下(我上面列出的其中一个),只有无类型或只有类型的树是适当的.
>可以通过调用Context.typecheck(编译时反射)或ToolBox.typecheck(运行时反射)从一个无类型的树到一个类型化的树,但是通过resetLocalAttrs或resetAllAttrs从一个类型的树到一个无类型的树是不可靠的因为https://issues.scala-lang.org/browse/SI-5464.

所以,你可以看到,我们的树是相当反复无常的,这给Scala的元编程带来了很大的复杂性.

然而,好消息是,这种复杂性并不是源于编译器101的一些根本的好原因所在.所有的复杂性都是偶然的,我们计划逐步驱逐它,直到完全消失. https://groups.google.com/forum/#!topic/scala-internals/TtCTPlj_qcQ(也发布了几天前)是朝这个方向迈出的第一步.敬请关注今年也可能到达的其他美食!

实际部分

通过详细阐述所有的细节,并暗示无神秘的情况,当没有任何工作完全吓倒你之后,我想注意到,通常一个人不需要知道这种东西,当使用宏.很多时候,两种无类型的树(手动构造的AST,quasiquotes)和键入的树(宏参数)工作正常.

在这种情况下,当scalac想要一个特定的树风味时,它会告诉你像c.eval或有时在你的脸上崩溃(RefChecks,LambdaLift和GenICode崩溃是巨大的指标,树在宏扩展期间混合 – 在这些情况下使用resetLocalAttrs如https://groups.google.com/forum/#!msg/scala-internals/rIyJ4yHdPDU/qS-7DreEbCwJ所述).解决这个问题是我的首要任务,我正在努力工作.这可能会发生,修复将使它成为2.11.0,这个答案将很快过时:)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读