在Julia中,是否有一个宏来确定一个表达式是否可以在解析时被求值?

6
在许多情况下,我希望能够断言一个值在运行时没有被评估。例如,在构造一些参数化结构Foo{A} where {A}时,我想确保A在解析时已知,并且不能通过动态调度确定。例如:Foo{@isstatic A}()
有办法强制执行吗?
更新 1:
也许我想要的是检查类型是否为Core.Compiler.Const(例如通过类型断言)?但我怀疑这是否是正确的做法。
更新2:
也许另一种表达方式是:在Julia中是否有类似于C++中用于除了Base之外的代码的constexpr

在Julia中,几乎所有需要在编译时根据类型处理某些内容的情况都可以使用@generated宏来解决。您想要实现什么? - Przemyslaw Szufel
如果我有一些“硬编码”的常量作为某些结构体的参数(例如静态数组的长度),那么我想使用这样的东西的一个例子是什么。在cpp中,我可以非常明确地定义一些constexpr k在我的函数内,并在各种地方使用它作为模板参数。在Julia中,如果我定义一个变量k,并将其用作某个构造函数或函数调用的参数,如果编译器无法确定它是编译时常量,则可能会意外地使事情不稳定。值类型可能是一个选择,但它们很麻烦。 - lassepe
请查看StaticArrays.jl的API和源代码,以及它们如何处理编码到类型中的常量。关于类型稳定性和编译器效率,Julia的美妙之处在于您不必在每个地方都放置那种类型的信息。然而,编写类型稳定的代码有时很困难。@code_warntype宏是您的好朋友。但最好的阅读材料是https://docs.julialang.org/en/v1/manual/performance-tips/index.html 希望这可以帮助您。 - Przemyslaw Szufel
1个回答

1

无法强制编译器执行此操作。然而,解析器中没有任何计算(如类型等常量的传播发生在稍后的阶段),因此这也很简单,只需将其设置为始终返回false

与其他一些语言不同,Julia不会将优化器失败(例如无法对某些内容进行常量折叠)作为编译器错误。它也没有不同的编译时类型。语言中的所有内容都可在运行时使用,因此您不必遵从某个编译器标准来定义什么是在编译时有效的,以及哪些内容将无法通过类型检查。

不要将此视为问题,而应接受这样一个事实:在Julia中,Foo{@isstatic A}()只需写成Foo{A}()!您不需要进行任何扭曲!如果某个值在编译时可用,则编译器将找出并使用该值。如果未知,则运行时仍将使用该值以获得相同的答案。


1
谢谢你的回答。我很感激这个事实,即我不必放置注释,因为编译器会(希望)自己解决。但是,来自C++背景的我可以非常明确地表达这些事情,这使我变得(过度)保守。我写的Julia代码越多,查看的@code_warntype输出越多,我对编译器的信任就越大。然而,在一些真正性能关键的内部循环中,如果需要在运行时解决类似问题,我想看到一个错误。但也许这主要是过早优化。 - lassepe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接