2008-10-29 55 views
22

什么是最酷的有点实用元编程黑客你已经完成或看到在D编程语言完成?比较实用的方法是排除编译时光线追踪器等。D模板:最酷的破解

回答

8

在彻底最酷的方面,我有要说Kirk McDonald's PyD(以及其他类似的绑定),因为它们在检测和处理大量不同类型以及复杂代码生成方面做了大量工作。

也就是说,PyD只赢了,因为BLADE在技术上使用CTFE,而不是模板。

更为个人的观点,D模板在我的一个研究项目中得到了广泛的应用。这是一个模拟框架,模块可以定义他们自己的私有数据类型。向框架公开新的用户类型需要一行代码,该代码为该类型创建XML解析器以及相关的网络序列化/反序列化代码。

8

DParse在猪肉饼的工具是一个模板解析器生成。但是,ldc是唯一一个运行编译时GC的D编译器(但即使如此,它也有几个奇怪的随机崩溃)。我已经玩了一下,你可以做一些有趣的事情,如配置文件解析和东西,但直到编译时GC完全运行,你不能做大事情。

+5

给它一个D大小的语法(~200个生产)“仅”需要7分钟和700MB来编译。 (完全披露,我写了dparse) – BCS 2008-11-04 18:42:01

6

我最喜欢的是ElemType和关键字类型从tools.base:

template ElemType(T) { 
    alias typeof((function() { 
    foreach (elem; Init!(T)) return elem; assert(false); 
    })()) ElemType; 
} 

template KeyType(T) { 
    alias typeof((function() { 
    foreach (key, elem; Init!(T)) return key; assert(false); 
    })()) KeyType; 
} 
5

我会回答我自己的问题,因为这个问题在我问到时不存在。我给垃圾收集器写了一个补丁,它使用模板并编译时间自省来为任意复杂的用户定义类型生成指针偏移量信息,以便进行精确的堆扫描,而不是在编译器中完成。

4

我写了一个memoize的()函数,它的标题是这样的(代码是有点长了粘贴在这里):

汽车memoize的(TFunc)(TFunc FUNC);它的作用是给它一个函数的地址,它返回一个强类型委托(与原函数相同的签名和返回类型),它缓存原函数的返回值,以便调用它两次使用相同的参数只调用一次底层函数。例如,这是斐波那契数列的“递归”定义,它以线性而不是指数时间执行:

uint fib(uint n) {return n> 0? n> 1?(n - 1)+ memoize(& fib)(n - 2):1:0;记忆(& fib) }

您可以正常调用它,如:fib(1000);


编辑:我发布的链接的前代码相当可怕; this version is much more elegant

+1

将代码发布到github并分享它。那么,如果你想。 – 2010-12-14 16:41:37

6

一个例子是D的标准库中的bitfields工具,它生成从用户指定的布局开始的位字段操作代码。

Tuple facility是另一个例子。它根据用户提供的类型和可选名称生成一个元组。除了注入已命名的字段外,没有太多生成的umph,但我认为这是一个说明性示例。

不知道兰伯特的利用我只是说memoize的到标准库 - 参见here的文档,here的代码,并here对相关新闻组讨论。

我工作的另一个工具是一个高阶函数,它将积分或实值函数列表(例如提供快速指数)。这还没有准备好发布。

一旦在编译过程中允许创建对象,将很容易创建例如正则表达式引擎,在编译过程中执行所有自动机生成。

2

混入阅读并从Stream对象编写简单的结构:

template TStructReader() { 
     private alias typeof(*this) T; 
     static T opCall(Stream stream) { 
       assert(stream.readable); 
       T ret; stream.readExact(&ret, T.sizeof); 
       return ret; 
     } 
} 

template TStructWriter() { 
     private alias typeof(*this) T; 
     void write(Stream stream) { 
       assert(stream.writeable); 
       stream.writeExact(this, T.sizeof); 
     } 
} 

使用方法如下:

align (1) struct MyStruct { 
     ... definitions here ... 
     mixin TStructReader; 
     mixin TStructWriter; 
} 

auto ms = MyStruct(stream); 
ms.write(stream); 
2

LuaD也广泛使用元编程与Lua的无缝交互。 您可以使用单个命令注册整个班级。