Julia 是怎么火起来的?( 四 )


以这种方式组织一本菜谱书将是解决表达式问题的烹饪版本的一种方法 , 这是一个比喻 , 在语言设计中 , 被称为“多分派”(multiple dispatch) , 简单地说 , 就是指根据应用它的所有成分或数据类型的类型自动选择一个方法 。
多分派是 Julia 解决表达式问题的方案 。 它也是语言的核心组织原则 , 因此 , 它既不是面向对象的 , 也不是函数式的 。 多分派比函数式或面向对象的解决方案更加强大、更加通用 。 多分派是一种秘诀 , 它使Julia变得更容易 , 并简化了大都数其他语言难以完成的任务:可以自由、直接地混合使用库并进行匹配 , 以及完成编写它们的人都无法想象的工作 。
例如:傅里叶光谱为了让这一点变得不那么抽象 , 我们可以来看一个例子 , 这个例子涉及到 Julia 事实上的标准绘图库 Plots.jl——绘图很容易:要制作正弦波的图形 , 一旦你将 x 定义为从 0 到 2π的点数组 , 那么只需键入plot(sin.(x))就可以得到如下图所示的图形:
Julia 是怎么火起来的?文章插图
Sin 后面的点使三角函数“广播”到 x 的每个元素 。
假设我正在创建用于傅里叶合成和分析的软件;例如 , 将声波分析作为谐波和 。 Julia 使你很容易创建自己的数据类型 , 而且关键的是 , 用户定义的类型不会减慢计算速度 。 我发明了一种叫做 Spect 的类型来包含波的谐波频谱 。 通常 , Plot 绘制数字数组的图形 , 如上例所示 。 但是 , 只需几行代码就可以告诉绘图包 , 我想通过查看由频谱中的谐波和构成的波的一个周期的图像来可视化我的 Spect 数据类型 。 如果我创建一个包含方波前十次谐波的特定 Spect 实例 , 并将其命名为 sqw , 那么我可以通过输入plot(sqw)来绘制这个图 。
Julia 是怎么火起来的?文章插图
其他类型的图形将自动工作 , 因此我可以输入scatter(sqw)来查看 。
Julia 是怎么火起来的?文章插图
一旦我有了光谱的数据类型 , 就可以编写函数对其进行操作 , 以各种方式转换光谱 。 我写了一个我称之为低通滤波器的东西 , 顾名思义 , 它能过滤掉超过指定值的谐波 。 为了过滤方波并将其绘制在一个步骤中 , 我可以说plot(lowpass(sqw, 3)) , 它将给我提供一个三次谐波滤除之后的方波图 。
Julia 是怎么火起来的?文章插图
我希望这个简短的可视化示例能够传达出自定义数据类型的一些强大功能 , 以及使用现有代码处理它们的能力 。 在这种情况下 , 绘图软件包并没有光谱的相关知识 , 但它却可以很容易地将其扩展为可视化 。
Chris Rackauckas 博士是麻省理工学院的应用数学家 , 也是许多广泛使用的 Julia 软件包的开发者 。 他给我描述了其他类似的例子 。 例如 , 有一个用于测量的 Julia 包 , 或其他带有不确定性的数字 。 然后是解决微分方程的软件包 。 你可以将它们组合起来以生成包括不确定性在内的解决方案 , 当你要求绘制方程式的图形时 , 你就会得到其解的图形 , 其中有显示不确定性的误差条状图 , 从而组成了三个库 , 这三个库并不是为了相互配合而编写的 。
Rackauckas 还有更多的例子:有一个叫做四元数的奇异数的 Julia 库 , 四元数有四个组成部分(就像我们熟悉的复数的更强版本) 。 你可以将这些数字与测量包结合使用微分方程求解器 , 当你绘制其解时 , 你会得到一个带有 4 条线的图 , 每条线都附有误差线 。
工具的重要性Julia 既不是第一个解决表达式问题的编程语言 , 甚至也不是第一个通过多分派解决这个问题的编程语言 。 Common Lisp 拥有这些特性都快40 年了 。 其他一些语言 , 如Perl的最新版本 , 也拥有这些特性 。 这些语言的用户都写过关于它是如何大大增加编写和扩展库的容易性 。 不同之处在于 Julia 是围绕多分派设计的 , 而在其他编程语言中 , 多分派是可选的 , 而且会带来性能损失 。 多分派设计的目的是使语言具有灵活性 , 并能够自然地表达数学思想;但即使是这样 , 它的设计者对于社区中产生的大量代码重用也感到吃惊 。
显然 , 对于我前文描述的那种流畅的可组合性 , 多分派或解决表达式问题的其他方式是必要的 , 但这还不够 。 Julia 在科学界得到了爆炸性的认可 , 因为它将这一特性和其他几个特性结合起来 , 对数学家来说非常有吸引力 。 它能够迅速地实现不费多少时间就能立即使用的代码 。 斯坦福大学的 Mykel Kochenderfer 教授使用 Julia 设计了一个国际标准的飞机防撞系统 , 他告诉我 , Julia“具有高级能力 , 可以由人类解释 , 但它的运行速度和我高度优化过的 C++ 代码一样快 。 ”(此外 , 尽管多分派设计和生成代码的速度通常作为语言的单独属性加以讨论 , 但一些速度实际上是 Julia 的函数分派策略的影响 。 )