Red的5种功能类型之间的差异,以及为什么它们区分它们?

问题描述 投票:3回答:3

在Red中,有数据类型function!op!native!routine!action!的函数。它们之间有什么区别?据我所知,function!用于用户定义函数,op!用于中缀运算符,routine!用于Red/System中定义的函数,但为什么还需要另外两个?

rebol red
3个回答
5
投票

function!

正如您自己猜测的那样,function!s是用户定义的函数,支持优化和类型检查,还可以包含嵌入式文档字符串。

通常,function!值是用funcfunctiondoeshas构造函数创建的,并利用所谓的spec方言;但是,理论上,没有什么能阻止你制作自己的构造函数或设计自己的规范格式。

值得注意的是,function!s完全支持反思。

op!

op!s是在其他4种函数之上的中缀包装器 - 它们在左侧取一个值,在右侧取一个表达式的结果,并且它们在评估期间也优先于其他函数。

op!值仅限于两个参数,不支持细化,并且对反射的支持有限(例如,您无法使用body-of检查其身体)。

routine!

routines!存在于红色和红色/系统领域(低级方言,在其上构建红色运行时)。他们的规格是用规范方言写的,但是他们的身体包含红色/系统代码。哦,他们支持反思。

通常它们用于库绑定(比如你提到的SQL库),与运行时的交互,或性能瓶颈(Red / System是一种编译语言,所以重写性能 - 应用程序的批评部分作为一组routine!s将以强制性编译为代价,给你一个显着的提升。

native!

native!s是用Red / System编写的函数(出于性能,简单或可行性的原因)并编译为本机代码(因此得名)。除了实施细节之外,还不确定还能说些什么。 native!不是非常面向用户,因此如果您有任何疑问,可能需要学习Red的源代码。

action!

action!s是一个用Red / System编写的标准化函数集(就像native!s一样),每个数据类型实现(或继承)作为其“方法”。 action!在某种意义上是多态的,他们派遣他们的第一个论点:

>> add 1 2%
== 1.02
>> add 2% 1
== 102%
>> append [1] "2"
== [1 "2"]
>> append "1" [2]
== "12"

在主流语言中,这通常看起来像"1".append([2])或类似的东西。

action!s和native!s之间的区别归结为设计选择:

  • 你可以拥有尽可能多的native!,但是为了提高效率,action!s有一个固定大小的调度表(这意味着每个数据类型的最大action!s数量是有限的;最小数量是2:make [创造价值]和mold [将值序列化为string!])。
  • 从逻辑上讲,action!s是围绕它们所属的数据类型组织在一个文件中,而native!s并不真正关心数据类型,并实现控制流,三角函数,集合上的操作等。

巧合的是,就在最近我们在社区聊天中有关于similar discussions和action!s的native!,您可能想要阅读。我还建议通过Rudolf Meijer的Red specification选秀,当然还有official reference documentation

至于你的问题中的“为什么” - 5种类型之间的区别只是一个实现细节,继承自Rebol。从逻辑上讲,它们都从概念的角度实现了你可能称之为“功能”的东西,然后落入any-function!阵营。


3
投票

对于调用者而言,它可能看起来类似于运行一个身体为BLOCK的函数!代码实现为本机指令...实现必须沿着不同的分支。

我不确切知道Red在编译案例中做了什么,Rebol2和Red的翻译案例类似。这些不同的类型实际上是一个大的switch()语句的一部分。如果它在描述“function”的单元格中查找并找到TYPE_NATIVE,则它知道将单元格的内容解释为包含本机函数指针。如果它找到TYPE_FUNCTION,它知道将单元格拆分为包含指向要执行的代码块的指针:

https://github.com/red/red/blob/cb39b45f90585c8f6392dc4ccfc82ebaa2e312f7/runtime/interpreter.reds#L752

现在我自己会同意你的质疑。例如这是否泄漏了用户的实施细节 - 谁不应该关注类型系统中的这个方面?

但是对于它的价值,有一个名为ANY-FUNCTION的全能排版!:

>> any-function!
== make typeset! [native! action! op! function! routine!]

你可能会认为这是“任何遵循类似函数的界面来调用”的东西。然而,有一些复杂性,如OP!从左边得到它的第一个参数......所以从接口的角度来看,这确实是一个值得关注的问题。

无论如何......天真! (正文是作为本机代码构建到可执行文件中)与功能! (正文是由解释或编译运行的红色代码块)只是一个区别。一个常规!是一个与DLL /库a la FFI交互而构建的外观,它没有Red的先验知识。一种行为!对于其他语言Generics所谓的非常简单的尝试。一个OP!从左边得到它的第一个参数。

重点是每个人可能对调用者感觉相同(除了OP!),但实现必须做一些不同的事情。它知道做不同事情的方式是通过值单元格中的类型字节。这就是Rebol2如何做到的 - 而且Red跟着Rebol2非常接近 - 所以这就是它如何做到的。这意味着任何提供函数背后的实现的新概念都需要一种新的数据类型,而这可能不是最好的想法。


0
投票

Red基于Rebol,因此具有相同的类型。

  • 功能!是用红色定义的用户定义函数
  • 本机!是机器码中的一个功能
  • 运!是一个用机器码编写的中缀运算符
  • 行动!是机器码中的多态函数
  • 常规!是从动态库导入的函数
© www.soinside.com 2019 - 2024. All rights reserved.