17611538698
webmaster@21cto.com

新 AI 语言Mojo 比 Python 强大的七个特性

编程语言 0 1611 2023-09-24 12:08:54

图片

21CTO导读:新推出的Mojo语言号称比 C 语言更快,还和 Python 语言一样简单,但运行速度却比后者快35000 倍,一起来看它的特性决定了哪些地方速度变快。

Mojo是一种新近发布的编程语言,专为人工智能开发者设计,它由 Swift 的创始人 Chris Lattner 创立的Modular公司出品。

图片

Mojo与其它语言的速率比较。图源:Modular网站

这个著名且哧人的 35000速率说法,来自 Mojo 与其它编程语言之间的基准比较,是在特定的 AWS 实例上使用,代码实现为 Mandelbrot 算法。

Mojo 定位是 Python 的超集,它将 Python 的可用性、简单性和多功能性与 C 语言的性能就这样难以置信地结合了起来。

图片

如果你对 AI 充满热情,并且已经掌握了 Python,那么 Mojo 绝对值得来试一试。

让我们一起深入探索这种令人兴奋的语言的七大功能。

Mojo 语言的特点


Mojo语言具备如下特点:

  • 渐进类型

使用强类型来提高性能并检测错误

  • 零成本抽象

通过将值分配到结构体来管理存储

  • 所有权+借用检查器

确保内存安全,避免并发死锁

  • 便携式参数算法

使用元编程来编写独立于硬件的算法并最大限度地减少重复

  • 语言集成并自动调整

自动优化目标硬件的参数值

  • 社区组织

Mojo 社区正在快速发展,每天都有很多成员加入。这种趋势短期内没有放缓的迹象

图片

Mojo 编辑器的屏幕截图。图片来源:编码之美。


我探索了Mojo 提供的这些很酷很新的功能,甚至运行了一些代码,接下来实践并查看该语言在升级Python的实际应用。

1.使用let和var来声明变量类型和常量


Mojo 引入了 let和var语句来让创建变量。如果我们愿意,可以为变量指定类似Int或string类型,就像在 TypeScript 中所做的一样,但不允许变量更改值。如下代码:

def  your_function ( a, b ):     let c = a     # 取消注释即可看到错误:     # c = b # 错误: c 变量是不可改变的    if c != b:         let d = b         print (d) 
your_function( 2 , 3 )


2. structs 用于更快的抽象


我们已经有 C++、Go 等语言的结构体版本。 Mojo 也有类似于 Python 类似的结构体,但它们也有些不同,因为Mojo 类是静态类型语言:你无法在运行时添加更多方法。这是取一个平衡,可能这样它不太灵活,但速度更快。

struct MyPair:     var first: Int     var secondary: Int     # 在这里使用 'fn' 而不是 'def' 声明
fn __init__(inout self, first: Int, secondary: Int): self.first = first self.second = secondary
fn __lt__(self, rhs : MyPair) -> Bool: return self.first < rhs.first or (self.first == rhs.first and self.second < rhs.second)

这是一种更严格的struct声明方法,所有字段都必须显式定义。

图片

Mojo 游乐场的屏幕截图。图片来源:编码之美


3.强类型检查


这种结构不仅为开发者提供了灵活性,还可以在 Mojo 中的编译时检查变量类型,就像 TypeScript 编译器现在所做的那样。


来看如下代码:

def pairTest  () -> Bool:     let p = MyPair( 1 , 2 ) # 取消注释即可查看错误:     # return p < 4 #给出编译时错误     return True


在这段代码中,4是一个Int型变量,p是MyPair函数的返回值,在其它编程语言有的是允许的,但在Mojo 中根本就不让你有这种比较。

4.方法重载


C++、Java、Swift等都有函数重载的概念,它是指有多个同名函数接受不同数据类型的参数。

来看这段代码:

struct Complex:     var re: F32     var im: F32 
fn __init__(inout self, x: F32): """从实数生成复数。""""""从实数生成复数。""" self.re = x self.im = 0.0 fn __init__(inout self, r: F32, i: F32): """从实数生成复数和虚部。""" self.re = r self.im = i

可以回想编程语言特性,像 JavaScript 和 Python 这样的弱类型语言是不能够进行函数重载的。

尽管在基于参数/类型的模块/文件函数和类方法中允许重载,但它不能仅仅基于返回类型就能工作,函数参数需要需要具有类型才可使用,否则重载不起作用,所发生的只是最近定义的函数覆盖所有先前定义的同名函数而已。

5. 与Python模块轻松集成


无缝与Python 集成,是 Mojo 语言迄今为止最大的卖点。


在 Mojo 中使用 Python 模块相当简单。作为超集,所需要做的就是用Python.import_module()中使用模块名称,就可以调用该方法。


在下面的例子中,我们导入了numpy库——这个大概是世界上最流行的 Python 库之一。代码来看如下:


from PythonInterface import Python # 将此视为 Python 中的 `import numpy as np` let np = Python.import_module( "numpy" ) 
# 现在就像在 Python 中使用 numpy array = np.array([ 1 , 2 , 3 ]) print(array)


你可以对其它任何 Python 模块执行相同的操作。一些限制规则:


  • 必须导入整个模块才能访问各个成员。

  • 包括所有 Python 模块


然后,在 Mojo 中的运行速度将提高 35,000 倍。图片


6 fn.——定义函数的新方法


fn  是比 def 有更严格的定义规则。


def 灵活、可变、有 Python 式的友好;而fn是恒定的、稳定的并且丰富了 Python。它就像 JavaScript 的严格模式,但仅适用于def。


来看如下代码:


struct MyPair: 
fn __init__(inout self, first: Int, secondary: Int): self.first = first self.second = secondary

fn的定义规则总结如下:

  • 不可变参数:默认情况下,参数是不可变的——包括self。因此开发者是不能更改它们的。

  • 必需的参数类型:须为其参数指定类型。

  • 必需的变量声明:须在使用局部变量之前声明它们(使用let和var)

  • 显式异常声明:如果fn抛出异常,则必须显式指示何等错误。就像在 Java 中使用throws关键字所做的一样。


7. 可变和不可变函数参数


按值传递与按引用传递,相信你在C/C++等一样是强类型语言中遇到过这个概念。


Python 的def函数定义使用的是引用传递,就像JavaScript中一样;当然我们可以改变def作为参数传递的对象。但是,Mojodef使用的是值传递,因此,你得到的def是所传递对象的副本。你可以随心所欲地改变这个副本;更改不会影响主对象。


引用传递提高了内存效率,不必为函数创建对象的副本。


但新函数定义fn呢?它与 Python def一样,它默认使用引用传递,但一个关键的区别是这些引用是不可变的。我们可以在函数中读取原始对象,但不能改变它。


不可变的参数


borrowed 是 Mojo 中一个新鲜的、新的、冗余的关键字。


因为它的borrowed作用是使 Mojofn函数中的参数不可变——默认情况下它们是不可变的。当处理占用大量内存的对象时,或者我们不允许复制我们传递的对象时,这是非常有用的。


请看如下代码:

fn use_something_big(borrowed a: SomethingBig, b: SomethingBig):     """'a' 和 'b' 都是不可变的,因为 'borrowed' 是默认值。""""""'a' 和 'b' 都是不可变的,因为 '借用' 是默认值。"""     a.print_id() // 10     b.print_id() // 20
let a = SomethingBig( 10 ) let b = SomethingBig( 20 ) use_something_big(a, b)

SomethingBig我们不需要在函数中复制大对象fn,而是简单地将引用作为不可变参数传递。

可变参数


如果我们想要可变参数,可使用 newinout关键字:

struct Car:     var id_number: Int     var color: String 
fn __init__(inout self, id: Int):id : Int): self.id_number = id self.color = 'none'
# self 通过引用传递以进行如上所述的突变。 fn set_color(inout self, color: String): self.color = color
# 像 self 这样的参数默认作为借用传递。 fn print_id(self): # 与: fn print_id(borrowed self): print ( 'Id: {0}, color: {1}' )
car = Car( 11 ) car.set_color( 'red' ) # 没有错误

self在函数中是不可变的fn,所以我们需要inout修改color中的字段set_color。

要点总结如下:


  • Mojo:是一种新的人工智能编程语言,具有 C 的速度和 Python 的简单性。

  • let与var声明:Mojo 引入了let与var语句来创建可选类型变量。var变量是可变的,let变量则不是。

  • 结构:Mojo 具有静态结构,类似于 Python 类,但由于其不变性而速度更快。

  • 强类型检查:Mojo 支持编译时类型检查,类似于 TypeScript。

  • 方法重载:Mojo 允许函数重载,即具有相同名称的函数可以接受不同的数据类型。

  • Python 模块集成:Mojo 提供无缝的 Python 支持,运行 Python 模块的速度显着加快。

  • fn函数定义:Mojo 中的 fn 关键字是 Python 的更严格版本def,需要不可变参数和显式异常声明。

  • 可变和不可变参数:Mojo 引入了可变 ( inout) 和不可变 ( borrowed) 函数参数。


结语


当我们又见证 Mojo 这个新语言面世时,请思考这种新的以人工智能为中心的语言将如何彻底改变编程领域,这是件非常有趣有价值的事情。


利用 Python 提供的易用性来缩小性能差距,并引入强大的类型检查等强大功能,可能预示着人工智能开发的新时代。


让我们一起怀着好奇心和渴望来拥抱这一转变,充分发挥 Mojo 的潜力!


作者:场长

参考:

https://medium.com/ai-in-plain-english/mojo-python-upgrades-db4561232724

https://levelup.gitconnected.com/the-mojo-programming-language-2ae72af52265


评论