Skip to main content

Motoko简介

Motoko是一种现代编程语言,你可以专门用于互联网计算机平台程序,也可以作为一种通用语言用于在其他平台上运行的语言。

易学性#

Motoko是一门现代语言,旨在让那些对现代面向对象或函数式编程习惯有一些基本熟悉的程序员,无论是JavaScript,还是其他现代编程语言,如Rust、Swift、TypeScript、C#或Java,都可以快速上手。

异步消息传递和类型声执行#

Motoko允许现代编程习惯,包括分布式应用的特殊编程抽象。每个应用程序由一个行为体(actors)组成,它与其他行为体(actors)的通信不使用共享状态,而是使用(异步的)消息传递。Motoko基于行为体的编程抽象允许人类可读的消息传递模式,并且它们强制要求每个网络交互遵守某些规则并避免某些常见错误。

具体来说,Motoko程序的类型是合理的,因为Motoko包括一个实用的、现代的类型系统,在执行前对每个程序进行检查。Motoko类型系统静态地检查每个Motoko程序在所有可能的输入上都能安全执行,没有内部类型错误。因此,在其他语言中常见的整类编程陷阱都被排除了,包括空指针错误、参数和结果类型的错误匹配以及其他许多错误。

为此,Motoko静态地编译成WebAssembly,这是一种可移植的二进制格式,对现代计算机硬件进行了简洁的抽象,因此允许它在互联网和互联网计算机协议上广泛移植。

每个微服务都是一个行为体(actor)#

Motoko为开发者提供了一个基于行为体(actor)的编程模型来表述服务器行为,包括互联网和互联网计算机协议上的微服务行为。

行为体类似于对象,但它的特殊之处在于它的孤立状态是远程存在的,而且它与程序罐的互动是异步的。

所有与行为体的通信以及行为体之间的通信都涉及到使用互联网计算机的信息传递协议在网络上异步传递信息。行为体的消息是按顺序处理的,所以状态的修改永远不会引起抢锁条件。

互联网计算机协议提供的底层计算平台确保每个基于消息的同步都会达到结束,但在这样做的时候,每个人也可能由于分布式系统中出现的问题而导致执行失败,包括超时等等。

异步 actors

像其他现代编程语言一样,Motoko允许组件间的异步通信使用符合人因工程学的语法。

在Motoko中,每个通信的组件都是一个行为体。

作为一个使用行为体(actors)的例子,也许我们自己就是一个行为体,请思考这三行代码:

let result1 = service1.computeAnswer(params);
let result2 = service2.computeAnswer(params);
finalStep(await result1, await result2)

我们可以用三个步骤来总结程序的执行:

该程序向两个不同的服务发出两个请求(第 1 行和第 2 行),每个服务在内部实现为一个参与者(对象)。

程序await在每个结果值上使用关键字等待每个结果准备就绪(第 3 行)。

程序通过调用finalStep函数在最后一步(第 3 行)中使用这两个结果。

一般来说,服务并发运行而不是相互等待,因为这样做可以减少整体延迟。但是,如果我们在没有特殊语言支持的情况下尝试以这种方式减少延迟,这种并发将很快牺牲清晰度和简单性。

即使在没有并发运行的情况下(例如,如果上面只有一个调用,而不是两个),出于同样的原因,编程抽象仍然允许清晰和简单。也就是说,它们向编译器发出信号,在何处转换程序,使程序员不必为了将程序的执行与底层系统的消息传递循环并发而扭曲程序的逻辑。

在这里,程序await在第 3 行中使用Motoko 提供的人类可读的语法以简单的方式表达这种并发行为。

在缺乏这些抽象的语言设置中,开发人员不仅会直接调用这两个函数,而且会采用非常先进的编程模式,可能会在系统提供的“事件处理程序”中注册开发人员提供的“回调函数”。每个回调将处理一个异步事件,该事件在答案准备好时出现。这种系统级编程功能强大,但很容易出错,因为它将高级数据流分解为通过共享状态进行通信的低级系统事件。有时这种风格是必要的,但在这里不是。

相反,我们的程序避开了这种更自然、更直接的编程风格,其中每个请求都类似于普通的函数调用。这种更简单、风格化的编程形式在表达与外部环境交互的实际系统方面变得越来越流行,就像今天的大多数现代软件一样。但是,它需要特殊的编译器和类型系统支持,我们将在下面详细讨论。

对异步行为的支持#

在异步计算环境中,一个程序和它的运行环境被允许执行内部的计算,这些计算是并发运行的。

具体来说,异步程序是指程序对其环境的请求不(一定)需要程序等待环境。同时,程序在等待的过程中被允许在这个环境中取得内部进展,也许是积极的。在上面的例子中,程序在等待第一个微服务的同时提出了第二个请求。

对称的是,环境对程序的请求并不(一定)要求环境在等待程序的回答时在其周围取得外部进展。

我们没有在上面展示这种 "通知 "模式的例子,因为它使用了回调(以及高阶函数和控制流),因此更加复杂。

语法形式 async 和 await#

为了满足清晰和简单的需要,Motoko采用了越来越常见的程序结构async和await,它们为程序员提供了一种结构化的语言来描述潜在的复杂的异步依赖图。

Async语法引入了futures。未来值(futures)代表一个 "promise"的结果,将在未来的某个时候异步交付(上面的第一个例子中没有显示)。当我们在行为体(Actors)和异步数据中介绍actor时,你会学到更多关于futures的知识。

在这里,我们只是使用调用service1.computeAnswer(params)service2.computeAnswer(params)所产生的。

语法await在一个future上进行同步,并有可能等待计算,直到future被其生产者完成。我们在上面的例子中展示了 await 形式的两种用法,即等待两个服务的返回结果。

当开发者使用这些关键字时,编译器会根据需要对程序进行转换,通常会对程序的控制流和数据流进行复杂的转换,而这些转换用手来完成是很乏味的。同时,Motoko的类型系统为这些结构强制执行某些正确的使用模式,包括在消费者和生产者之间流动的类型总是一致的,在服务之间发送的数据类型被允许在那里流动,并且不(例如)包含私有的可改变状态。

类型是静态的#

像其他现代编程语言一样,Motoko允许每个变量携带一个函数、对象或原始数据(例如,一个字符串、单词(word)或整数)的值。其他类型的值也存在,包括记录、图元和称为变体的 "标签数据"。

Motoko享有类型安全的正式属性,也被称为类型健全性。我们经常用这样的短语来概括这个想法。类型良好的Motoko程序不会出错,也就是说,它们不会通过将程序结构视为错误的类型而误用它们。

例如,Motoko程序中的每个变量都有一个相关的类型,在程序执行之前,这个类型是静态的。每个变量的使用都由编译器检查,以防止运行时的类型错误,包括空指针错误。

在这个意义上,Motoko类型在程序源代码中提供了一种可信的编译器验证的文件形式。

像往常一样,动态测试可以检查Motoko类型系统所不能及的属性。虽然是现代型语言,但Motoko类型系统并没有刻意的 "先进 "或奇特的新方式。相反,Motoko 的类型系统整合了当今现代但易于理解的实用类型系统的经验教训,为通用分布式编程提供了一种易于理解但数学上精确的语言。

科普小知识#

人因工程学