让d用户定义效果系统
std.conv.octal中还有字面.
不应删除,内置二进制字面.cgi.d比vibe.d更快.
模板化druntime,简单调用dom.d,就够了.
如果可以在库代码中定义@nogc,pure甚至像@vibe_fiber_safe等等,而不是在编译器中添加,会怎么样?
我反对@nogc的(许多)批评之一是,它是你想要不解决就能避免的特例,类似情况下还会出现类似问题.我一直认为某种用户定义系统会很好,这样它可能会检查多个因素,甚至组合成集合,不必在每个函数上重复十几个属性.AA曾经提出函数的复杂度注解.
D的内置注解倾向于以禁止列表形式出现.如@nogc函数禁止调用可能调用GC函数的内容,及禁止纯函数读取静态变量.
可以想象,标记函数允许及禁止做的事情的系统.内置语言会有一些core.attribute神奇注解说明它们的作用,但也可自定义.
四种类型的注解:@effect!(...),@denied_effect!(...),@exclusively_allowed_effect!(...)和@allowed_hidden_effect!(...).
用D符号标记效果.这允许通过正常模块系统来消歧名空间等.如下:
// 这是用户定义效果
enum writes_to_console;
// 函数上声明用户定义效果
void writeln(string s) @effect!writes_to_console { ... }
// 从编译器访问效果
import core.effects : gc_allocates;
// 内置的nogc注解因此可成为库别名
alias nogc = denied_effect!gc_allocates;
import std.typecons : AliasSeq;
// 也可以声明组合
alias no_combined = AliasSeq!(denied_effect!gc_allocates, denied_effect!writes_to_console);
void cant_write_to_console_nor_gc_allocate() @no_combined {
/*
编译错误:
writeln具有writes_to_console效果,但拒绝该效果
*/
writeln("hi");
}
如果用矛盾东西来标记函数,则是编译错误.
enum thing;
// 错误!
void contradiction() @denied_effect!thing @exclusively_allowed_effect!thing {}
可用@allowed_hidden_effect来模拟类似内置受信任的东西.
enum thing;
void foo() @effect!thing {}
//由于调用了`foo()`,它也有与`foo()`相同效果
void inferred_effect() {
foo();
}
//函数调用`foo`,但由于它是允许隐藏的效果`effect!thing`是隐藏的!
void baz() @allowed_hidden_effect!thing {
foo();
}
void error() @denied_effect!thing {
/*
这是拒绝效果,但在`推导效果`
(从调用foo一层深的调用)
*/
inferred_effect();
}
void bar() @denied_effect!thing {
/*
无误,bar允许隐藏效果
*/
baz();
}
允许和拒绝效果必须与继承一起使用.子类可以拒绝父母允许的事情,但不能允许父母拒绝的事情,就像可添加@nogc到覆盖,但不能删除它一样.
就像内置属性,也希望参数有某种依赖效果.
//用相对`正常`语法转发效果,神奇的是,它不是在`声明`时静态确定的,而是在`使用`时确定的.
void map(void delegate() dg) @effect!(__traits(getEffectsOfArgument, dg)) {
dg();
}
价值在:
alias fiber_compatible = @denied_effect!blocking
主要思想是,如果用户可定义它的,则可做任何需要做的事情.
浙公网安备 33010602011771号