d递归和属性推导

原文
我遇见歧义了.

float recurse()(float val, float till)
{
    return val < till? recurse(val * 2, till): val;
}

@safe void main()
{
    import std;

    writeln(recurse(1.5, 40.0));
    writeln(typeid(&recurse!()));
}
//编译并打印:
48
float function(float, float) pure nothrow @nogc @safe*

规范说,不会按@安全或纯及不抛推导递归函数.
实现规范,哪个对?

我倾向实现是正确的,因为代码并没有违反内存安全.
丹尼斯正在研究使@安全推导对递归函数也是正确的,所以未来可能会完全取消该限制.

函数直接调用自身时,忽略对该调用的属性检查.
然而,当两者间有多个函数时,推导就会变成"我正在调用现在不能完成属性推导函数,所以保守地假设不能按@安全推导所有属性.",似乎规范已修改为记录实现的该缺点.

我希望可简单地假定已推导所有属性,使如下工作:

void fun1()() { fun2(); }
void fun2()() { fun1(); }

void main() @safe pure nothrow @nogc
{
    fun1(); // 当前失败
}

但这里有个更麻烦情况:

@system void systemFunc();

void fun1()()
{
    alias T = typeof(fun2());
    systemFunc();
}

void fun2()()
{
    fun1();
}

void main0() @system
{
    fun1();
}

void main() @safe
{
    fun2(); // 非系统!
}

编译器分析fun1,然后fun2,然后需要决定调用fun1是否是安全的.
如果它假定为是的,安全.则稍后当它看到调用系统函数(systemFunc)()时,需要返回并标记函数2()@系统,并重新分析,T现在是@系统fun1.
DMD不适合做该回溯,会非常慢,所以一般不会修复.

但是,在缺少typeof()其他函数类型依赖关系时,可维护每个函数被调列表,以通过简单函数调用来解决最常见相互函数依赖关系.

我同意.我认为不应该有回溯,因为即使对所有约束有一致的方法,它也一般不会终止.
这里,如果在推导属性的同时,被迫决定属性,那么没有明显的默认值会很烦人.我想可在继承类型``推迟解析它们,并适当地耦合推导,但不知道是否值得,似乎用模板实例化难以正确+高效,因为可能以后会改参数类型.

posted @   zjh6  阅读(13)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示