Julia 是否对递归多态类型执行代码单态化?

2024-01-03

我注意到,在执行代码单态化的语言(例如:C++、Rust 等)中实现多态递归类型即使不是不可能,也是非常困难的。这通常是因为编译器需要为该类型的每个可能的实例化生成代码,这通常会导致无限递归。

支持此功能的语言通常使用类型擦除。编译器不会尝试实例化下一个递归调用,因为它已经知道类型的布局。

Julia 执行代码单态化,但它支持多态递归。我的猜测是,它是通过延迟实例化泛型类型或函数直到实际调用它来实现这一点的。但是,我认为这可能最终会使用大量内存,特别是当递归非常深时。所以我的问题是,Julia 是否仍会对多态递归类型执行代码单态化,还是会退回到类型擦除或其他方法?


这个问题看起来非常类似于

为了回答这个问题,我将调整、纠正和详细说明那里给出的代码。

首先是一些定义:

abstract type BiTree{T} end

struct Branch{T} <: BiTree{T} 
    left::BiTree{T}
    right::BiTree{T}
end

struct Leaf{T} <: BiTree{T}
    value::T
end

Base.foldl(f, b::Branch) = f(foldl(f, b.left), foldl(f, b.right))
Base.foldl(f, l::Leaf) = f(l.value)


# fancy and concise constructor operations
(⊕)(l::Branch, r::Branch) = Branch(l, r) # just for illustration
(⊕)(l, r::Branch) = Branch(Leaf(l), r)
(⊕)(l::Branch, r) = Branch(l, Leaf(r))
(⊕)(l, r) = Branch(Leaf(l), Leaf(r))

这里我们有一个抽象类型和两个子类型,一种是树中内部节点的复合类型,另一种是叶子的子类型。我们还有两行递归操作来定义如何折叠或减少树中的值,以及一个简洁的树中缀构造函数。

如果我们定义my_tree然后用加法折叠它,我们得到这个:

julia> my_tree = ((((6 ⊕ 7) ⊕ (6 ⊕ 7)) ⊕ ((7 ⊕ 7) ⊕ (0 ⊕ 7))) ⊕ (((8 ⊕ 7) ⊕ (7 ⊕ 7)) ⊕ ((8 ⊕ 8) ⊕ (8 ⊕ 0)))) ⊕ ((((2 ⊕ 4) ⊕ 7) ⊕ (6 ⊕ (0 ⊕ 5))) ⊕ (((6 ⊕ 8) ⊕ (2 ⊕ 8)) ⊕ ((2 ⊕ 1) ⊕ (4 ⊕ 5))));

julia> typeof(my_tree)
Branch{Int64}

julia> foldl(+, my_tree)
160

请注意,类型my_tree完全暴露了它是一个带有某种子节点的内部节点,但我们无法真正看到它有多深。我们没有得到像这样的类型Branch{Branch{Leaf{Int32}, Branch{...。事实是Branch{Int64} is a BiTree{Int64}可见使用

julia> isa(my_tree, BiTree{Int64})
true

但仅从价值上看不出来my_tree单独的,并且深度在类型中不可见。

如果我们看看迄今为止作为我们工作的副作用生成的方法,我们会看到这一点

julia> using MethodAnalysis

julia> methodinstances(⊕)
4-element Vector{Core.MethodInstance}:
 MethodInstance for ⊕(::Branch{Int64}, ::Branch{Int64})
 MethodInstance for ⊕(::Int64, ::Branch{Int64})
 MethodInstance for ⊕(::Branch{Int64}, ::Int64)
 MethodInstance for ⊕(::Int64, ::Int64)

julia> methodinstances(foldl)
3-element Vector{Core.MethodInstance}:
 MethodInstance for foldl(::typeof(+), ::Branch{Int64})
 MethodInstance for foldl(::typeof(+), ::Leaf{Int64})
 MethodInstance for foldl(::typeof(+), ::BiTree{Int64})

无论我们尝试构建哪种 32 位整数树,这就是我们所需要的。无论我们尝试减少什么树+,这就是我们所需要的。

如果我们尝试使用不同的运算符进行折叠,我们可以获得更多方法

julia> foldl(max, my_tree)
8

julia> methodinstances(foldl)
6-element Vector{Core.MethodInstance}:
 MethodInstance for foldl(::typeof(+), ::Branch{Int64})
 MethodInstance for foldl(::typeof(max), ::Branch{Int64})
 MethodInstance for foldl(::typeof(+), ::Leaf{Int64})
 MethodInstance for foldl(::typeof(max), ::Leaf{Int64})
 MethodInstance for foldl(::typeof(+), ::BiTree{Int64})
 MethodInstance for foldl(::typeof(max), ::BiTree{Int64})

有趣的是,方法的数量增加了,但并没有爆炸。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Julia 是否对递归多态类型执行代码单态化? 的相关文章

  • 这个对自身单位的列表理解是如何工作的?

    在 haskell IRC 频道中有人问 是否有一种简洁的方法来定义一个列表 其中第 n 个条目是之前所有条目的平方和 我认为这听起来像一个有趣的谜题 递归定义无限列表是我真正需要练习的事情之一 所以我启动了 GHCi 并开始尝试递归定义
  • Clojure:只能从尾部位置重复

    我正在尝试递归地反转列表 但是我得到了Can only recur from tail position运行时 这到底意味着什么 如何改进我的代码才能使其正常工作 defn recursive reverse coll loop coll
  • 线程“main”中的异常 java.lang.StackOverflowError

    我有一段代码 但我无法弄清楚为什么它在线程 main java lang StackOverflowError 中给出异常 这是问题 Given a positive integer n prints out the sum of the
  • C# 中的递归自定义配置

    我正在尝试创建一个遵循以下递归结构的自定义配置部分
  • 调用基本方法而不是覆盖方法

    在 C 中 类A包含一个公共方法Foo 它进行一些处理并返回一个值 protected method Bar 也在课堂上A执行与以下相同的逻辑Foo 然后进行一些额外的处理 然后返回一个值 为了避免重复代码 Bar calls Foo 并使
  • 归并排序中的递归:两次递归调用

    private void mergesort int low int high line 1 if low lt high line 2 int middle low high 2 line 3 mergesort low middle l
  • 朱莉娅在矩阵中查找(行,列)而不是索引

    在 Julia 中 您可以通过以下方式找到矩阵中元素的坐标 julia gt find x gt x 2 1 2 3 2 3 4 1 0 2 3 element Array Int64 1 2 4 9 这些值是正确的 但我更希望得到 row
  • 来自 JSON 的 Angular 8 动态表单

    我正在尝试从 JSON 模式递归生成动态表单 但我正在努力解决找不到表单控件的问题 这是代码示例 我收到这个错误 错误错误 找不到名称为 createdAt 的控件 我尝试了不同的方法 但仍然存在问题 我知道我错过了一些东西 所以请帮忙 任
  • PHP递归遍历对象树[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 是否可以在运行时在 Julia 中创建类型?

    假设我想要一个以下形式的函数 abstract RecordType function CreateRecordType fields names Vector ASCIIString type name ASCIIString magic
  • 如何考虑子类型的多态性

    里氏替换原则指出 超类型的不变量必须保留在子类型中 我对这个原理和多态性的交叉特别感兴趣 事实上 特别是子类型多态性 参数多态性和 Haskell 类型类似乎就是这种情况 因此 我知道当函数的参数是逆变且返回类型是协变时 函数是子类型 我们
  • Julia Threads.@threads 比单线程性能慢

    我正在尝试求解一维热方程的数值 我正在使用有限差分 并且在 Julia 中使用 threads 指令时遇到一些问题 特别是下面有相同代码的两个版本 第一个是单线程 而另一个使用 threads 除了 thread指令之外 它们是相同的 fu
  • 递归树遍历 - 如何跟踪递归级别?

    我基本上试图从表示树结构的多维数组构建 html ul li 嵌套列表 下面的代码工作正常 但我想改进它 我需要一种方法来跟踪递归级别 以便我可以将不同的类应用于不同的级别 向生成的输出添加缩进等 function buildTree tr
  • duckmap 到底有什么作用?

    From 文档 https docs perl6 org routine duckmap duckmap将会应用 block每个元素上并返回一个新列表 其中包含块的已定义返回值 对于未定义的返回值 duckmap如果该元素实现了 将尝试下降
  • 如何在 Julia 中引用结构本身

    我有这个代码 struct MyStruct text String function MyStruct text String text text do other things end end 当我写这篇文章时 我意识到朱莉娅没有认识到
  • Fortran 递归分段错误

    我必须设计并实现一个 Fortran 例程来确定方格上簇的大小 并且递归地编写子例程似乎非常方便 然而 每当我的晶格大小超过某个值 大约 200 边 时 子例程就会始终出现段错误 这是我的集群检测例程 RECURSIVE SUBROUTIN
  • PHP - 递归搜索数组中的键和子键,成功时返回键['subkey]

    因此 我编写了一个函数 该函数可以在数组中深入搜索两个级别以查找键和子键对 基本上是在寻找key subkey 如果找到 则返回key subkey 我正在寻找一种以真正递归的方式执行此操作的方法 并根据需要进行尽可能多的深度搜索 直到到达
  • 如何从 Unix 命令行递归解压目录及其子目录中的档案?

    The unzip命令没有递归解压缩档案的选项 如果我有以下目录结构和档案 Mother Loving zip Scurvy Sea Dogs zip Scurvy Cures Limes zip 我想将所有档案解压缩到与每个档案同名的目录
  • 有没有相互递归的例子?

    是否有递归函数调用另一个函数 该函数也调用第一个函数 的示例 例子 function1 do something function2 do something function2 do something function1 do some
  • 如何使用二叉树中的递归来完成回溯

    我正在尝试插入一个二进制节点 我的代码很复杂 没有希望挽救它 所以我计划重写它 基本上我没有考虑回溯 也没有仔细考虑算法 我正在尝试使用顺序遍历插入二进制节点 但我不明白应该如何回溯 D B E A C F 我如何搜索根 D 的左子树 然后

随机推荐

  • 如何从 Z 缓冲区获取 Z 值

    我在 OpenGL 中绘图时遇到问题 我需要准确查看深度缓冲区中放置的值 谁能告诉我如何检索这些值 谢谢 克里斯 Use glReadPixels http www opengl org sdk docs man xhtml glReadP
  • C# 建立从笔记本电脑内部蓝牙 4.0 到蓝牙低功耗 (BLE) 外设的流

    我正在尝试编写一个连接到蓝牙低功耗设备 BLE 的程序 然后在更新时或在给定的时间间隔读取特征 我的外设是 Texas Instruments CC2540 BLE 设备 我的出发点是查看 TI 的示例程序 它有一个心率监视器 http p
  • 我可以在 El Capitan 上安装 Xcode 8.3

    我可以在不更新 Mac 操作系统的情况下安装 xcode 8 3 即 OS X El Capitan 版本 10 11 6 我在苹果网站上找不到任何参考资料 但是 这个link https stackoverflow com a 10335
  • 使用 PdfDocument 在 Android 中生成自定义尺寸的 PDF

    Pdf文档 https developer android com reference android graphics pdf PdfDocument是一个可以从 Android 视图生成 PDF 的类 您只需添加一个视图即可PdfDoc
  • 如何将复选框标记为已签入角度4

    我对 Angular 2 很陌生 我需要在单击按钮时标记复选框 我在循环中有一些复选框 例如 tr td td tr
  • 节点在异步函数完成之前退出

    我有一个返回承诺的函数 我试图在异步函数中等待它 问题是程序立即完成 而不是等待承诺 异步测试 js function doItSlow const deferred new Promise setTimeout gt console lo
  • 最好将项目添加到集合中,或将最终列表转换为集合?

    我有一些数据看起来像这样 ID1 ID2 ID3 ID1 ID4 ID5 ID3 ID5 ID7 ID6 其中每一行都是一个组 我的目标是为每个 ID 建立一个字典 然后是与其共享 gt 1 个组的一组其他 ID 例如 此数据将返回 ID1
  • 检测复制或相似的文本块

    我有很多关于 Markdown 格式编程的文本 有一个构建过程能够将这些文本转换为 Word HTML 并执行简单的验证规则 例如拼写检查或检查文档是否具有所需的标题结构 我想扩展该构建代码以检查所有文本中的复制粘贴或类似块 是否有任何现有
  • 字符编码问题

    我需要将其保存到数据库 mysql 中并将其显示出来 我的数据库是utf8 general ci 我 i visib i i 我 s i s xyg 我 ivi g i w d y d z 我 w ys z 我很忙 bu v ig y 我
  • Android Gradle DexException:多个 dex 文件定义 Lorg/hamcrest/Description

    com android dex DexException 多个 dex 文件定义 Lorg hamcrest Description 尝试通过以下方式进行调试构建 测试时发生安卓工作室 or via Gradle我的应用程序上的命令行 发布
  • HTML5 视频色差 Chrome 和 Internet Explorer

    我正在使用 HTML5 视频标签通过以下代码在我的网站上播放短视频
  • 找不到值类型为 Boolean 的属性“app:vm”的 GETTER

    我正在尝试在我的自定义控件中使用本机 2 路 Android 数据绑定 所以我在 xml 中有类似的东西
  • Chrome刷新右键重新加载选项不可用

    我正在尝试做一个hard reload and empty cache在 Chrome 中 因为之前加载的网站不断出现在localhost我正在使用的端口 问题是右键单击选项似乎已停止工作 即 当我右键单击刷新按钮时没有任何反应 只能单击左
  • 为什么模板可以直接使用$this关键字?

    我是 PHP 的新手 今天我在 Magento 中看到一些代码如下top phtml div class nav container ul li class home a href a li ul div
  • 如何使用 has_one 关联连接关联表

    在我的 Rails 应用程序中 我只要求用户在注册时输入电子邮件和姓名 然后让他们可以选择为其个人资料提供更完整的联系方式 因此 我有一个与 Contact rb 关联的 User rb 模型 即 User rb has one conta
  • 查找最大的空闲内存块

    当内存碎片化时 有时会出现内存不足的问题 是否有可能找到最大的空闲内存块 我使用 Delphi 2007 和 FastMM 在 Windows XP 上开发并在 Windows 2003 上运行应用程序 Regards EDIT 我可以添加
  • 用户表的不同名称字段?

    我有一个包含 2 个字段的表单 用户名密码 和一个包含这两个相同字段 用户名 密码 的 mysql 表 并且我的身份验证系统工作正常 但是 如果我的表字段具有不同的名称 我就无法使其工作 例如 我的用户 我的密码 如果你只是改变userna
  • 数字类型的类模板

    如何编写只接受数字类型的类模板 int double float等 作为模板 您可以使用std is arithmetic http en cppreference com w cpp types is arithmetic类型特征 如果您
  • 在 C# 中从 IronPython 调用时引用 Python“导入”程序集

    对于 IronPython 我完全是个菜鸟 我需要从 ASP NET 网站调用 py 脚本 并具有以下代码 var ipy IronPython Hosting Python CreateRuntime dynamic test ipy U
  • Julia 是否对递归多态类型执行代码单态化?

    我注意到 在执行代码单态化的语言 例如 C Rust 等 中实现多态递归类型即使不是不可能 也是非常困难的 这通常是因为编译器需要为该类型的每个可能的实例化生成代码 这通常会导致无限递归 支持此功能的语言通常使用类型擦除 编译器不会尝试实例