21CTO导读:新推出的Mojo语言号称比 C 语言更快,还和 Python 语言一样简单,但运行速度却比后者快35000 倍,一起来看它的特性决定了哪些地方速度变快。
Mojo是一种新近发布的编程语言,专为人工智能开发者设计,它由 Swift 的创始人 Chris Lattner 创立的Modular公司出品。
Mojo与其它语言的速率比较。图源:Modular网站
如果你对 AI 充满热情,并且已经掌握了 Python,那么 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声明方法,所有字段都必须显式定义。
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
本文为 @ 万能的大雄 创作并授权 21CTO 发布,未经许可,请勿转载。
内容授权事宜请您联系 webmaster@21cto.com或关注 21CTO 公众号。
该文观点仅代表作者本人,21CTO 平台仅提供信息存储空间服务。