【问题标题】:What's the use case for D's compile time evaluationD的编译时评估的用例是什么
【发布时间】:2012-07-12 13:22:49
【问题描述】:

我在我最喜欢的语言 OCaml 中集成了这个功能,我知道这是 D 中的性感功能,但是除了一些优化之外,编译时评估的用例是什么? 越多越好,极客越好:-)

【问题讨论】:

  • 您将这个功能“集成到”您“最喜欢的编程语言 OCaml”中是什么意思?在没有用例的情况下为什么要这样做?
  • 这是我其他项目的副作用。正如我所说,优化是一个用例。但我认为应该有更多
  • @bobzhang,看看 MetaOCaml,它更有趣(并且比使用 D 限制元编程可以做的任何事情都更灵活)。而且,与任何元编程工具一样,用例是有效地实施 eDSL。
  • @SK-logic 我以前玩过它。但它没有赶上最新的 ocaml :-(。我的集成是一个还支持整个语言编译时评估的库,所以没有补丁编译器问题。恕我直言,如果你有编译时评估,还有很多事情要探索以一种非常方便的方式:-)

标签: compiler-construction ocaml d


【解决方案1】:

当然,优化是一个很大的用例。 ctRegex 之类的东西比它们的运行时编译的正则表达式等效(通常)执行得更好。解析器生成器也很有趣(参见Pegged)并且将受到越来越多的关注。人们才刚刚开始了解可以做的事情。

您可以执行mixin(import_c("header.h")) 之类的操作来为任意 C 标头解析和构建 D 接口文件(当然,您需要为 C 中的 C 编写解析器来执行此操作)。

可以非常快速地进行字符串格式化,因为格式字符串(例如,"%0.2f")通常在编译时是已知的。您可以读取格式字符串,只生成格式化所需的代码,去掉各种不必要的部分。

vibe.d 实际上支持编译时模板。模板文件(基于 Jade/HAML)可以包含 D 代码。它读取它并生成一个自定义的 D 代码块(将其想象为“”~标题~“...”)。我不相信作者做过基准测试,但它应该非常快。

您基本上可以在保持高水平的同时获得专门的手动优化代码的好处。很难回答您的问题,因为我们只是不知道它的用途。它让我想起了 C++ 模板。他们的设计者没有预料到它支持的高级元编程技术。

【讨论】:

  • 我发现 D 编译时评估的一个重要限制是所有源代码都应该出现在一个文件中,这使得编写非常强大的编译时评估函数非常困难,因为那时你不能使用任何库。你怎么看
  • 这基本上与 C++ 模板面临的限制相同。没有简单的解决方法。有些人想在库对象文件中嵌入源代码来解决这个问题,但还没有人尝试过。
【解决方案2】:

一些建议:

  • 解析一个 PEG 语法,组装一个 PEG 解析器,然后使用该解析器,全部在编译时怎么样?这是Pegged 项目。
  • 大型静态查找表的构造。
  • 为正则表达式生成最佳本机代码:std.regex.StaticRegex
  • 从定义文件实现 protobufs。
  • 许多函数,如果它们的输入在编译时是已知的,则可以在那时而不是在运行时进行评估——所有这些都无需更改函数的实现。

【讨论】:

  • 感谢您的建议。我对D不熟悉,如果编译时评估返回自定义的数据结构,D如何处理?你能解释一下吗?
  • 或更准确地说,D 对使用编译时评估的函数有什么限制?
【解决方案3】:

当与mixin 一起使用时,它可以提供很大的灵活性。

考虑以下示例:

template StructFromFile(string fileName){
    string makeStructMembersCode(string[] s){
        if(0==s.length){
            return null;
        }
        string memberName=s[0].strip;
        return q{
            string }~memberName~q{;
            }~makeStructMembersCode(s[1..$]);
    }
    struct StructFromFile{
        mixin(makeStructMembersCode(import(fileName).splitLines));
    }
}

这将创建一个结构,它的成员是文本文件的行。现在,假设您在数据库中有一个表,并且您想创建一个 D 结构来存储该表中的行。您可以编写一个 shell 脚本来读取该表的架构并将其写入文件,然后使用 StructFromFile 自动创建一个可以保存该表行的结构。如果更改架构,则不会更改结构的代码。但是,您确实必须更改任何依赖于旧模式的代码 - 但这是一件好事,因为它会将运行时错误转化为编译错误。

当然,您也可以使用此方法添加 getter+setter 属性,并将其用于 XML DTD 和 Web 服务。

【讨论】:

    【解决方案4】:

    这是我能想到的最极客的编译时评估应用程序:以函数string f(string code) 的形式为您自己的编程语言编写一个编译器,该函数将您的编程语言的源代码作为参数并输出 D 代码。然后写类似

    mixin( f( import("my_code_file") ) );
    

    进入您的main.d 文件。这样您就可以滥用 D 编译器及其后端为您生成可执行文件。如果您愿意,您可以编写一个 shell 脚本(或类似的脚本)来创建 main.d 文件并在其上运行 D 编译器。这样,您就可以为您的语言获得一半的编译器。至少你不需要关心后端。 ;)

    除此之外,我已经阅读了 D 中的编译时光线追踪器。

    【讨论】:

      猜你喜欢
      • 2020-10-01
      • 2014-06-16
      • 2011-09-27
      • 2014-12-21
      • 2021-09-04
      • 2016-08-30
      • 1970-01-01
      • 2018-07-28
      • 2012-06-26
      相关资源
      最近更新 更多