Motoko,⼀种直接在互联⽹上构建的编程语⾔
为了提供⽆缝的开发⼈员体验,我们希望创建⼀种称为Motoko的专⽤编程语⾔,该语⾔旨在直接⽀持Internet计算机的编程模型,从⽽使更有效地构建应⽤程序和利⽤某些更独特的功能变得更加容易。这个平台。
目前流行的编程语言在Dfinity,我们正在构建Internet计算机,这是⼀种去中⼼化的云计算平台,我们将其视为⽆缝的软件领域,开发⼈员可以在其中直接在Internet上部署应⽤程序和服务。为了实现这⼀愿景,我们决定将WebAssembly作为平台执⾏环境的通⽤语⾔,以便开发⼈员可以使⽤可编译为WebAssembly的任何语⾔对其进⾏编程。
为了提供⽆缝的开发⼈员体验,我们还觉得创建⼀种称为Motoko的专⽤编程语⾔⾮常重要,该语⾔旨在直接⽀持Internet Computer的编程模型,从⽽使更有效地构建应⽤程序和利⽤其中的某些功能变得更加容易。该平台的更多特殊功能。
我们很⾼兴与您分享⼀些使该项⽬如此特别的原因。
Web组装
⾸先,我们必须简短地谈论WebAssembly-⼜名Wasm(是的,正确拼写,没有⼤写字母)。您可能已经
知道,Wasm是⼀种新的低级代码格式,旨在可移植,安全和⾼效。它的最初⽤例是⽹络,但实际上名称⽤词不当:当我们在W3C⼯作组中设计Wasm时,我们谨慎地将其作为开放标准和通⽤平台来进⾏。也就是说,它不针对任何特定的编程语⾔,范例,计算环境或平台,并且我们确保它完全不与Web绑定。因此,Wasm在许多其他环境中被采⽤绝对不是偶然的,例如云计算,边缘计算,移动,嵌⼊式系统,物联⽹和区块链。
Wasm中涉及了许多设计考虑因素,其中⼀些显⽽易见,有些则相当微妙。这⾥太多了。关于Wasm的技术⽬标,设计选择,形式语义和实现技术的相当全⾯的讨论,可以在我们在ACM通讯中发表的科学⽂章中到(本⽂的旧版本和更多技术版本可在此处免费获得)。
与其他虚拟机相⽐,Wasm的主要区别在于,它并未针对任何特定的编程语⾔进⾏优化,⽽仅对底层硬件进⾏了抽象,其字节码直接对应于现代CPU的指令和内存模型。最重要的是,Wasm通过强⼤的模块化和严格的数学规范来⽀持沙箱操作,从⽽确保执⾏安全,没有不确定的⾏为,并且(⼏乎)完全具有确定性。此外,这些属性实际上具有机器验证的数学证明!
总⽽⾔之,这些属性旨在使Wasm在对便携性,安全性,通⽤性和性能有很⾼期望的⼴泛环境和⽤例(例如Dfinity的Internet计算机)中成为有吸引⼒的选择。
创建互联⽹计算机
互联⽹计算机是⼀个分散的云计算平台,将托管安全软件和新型的开放式互联⽹服务。它使⽤强⼤的加密共识协议在(可能不可信的)计算节点的对等⽹络上安全地复制计算,这些计算节点可能覆盖了许多虚拟⼦⽹(有时称为分⽚)。Wasm的优越属性使其成为表⽰在此平台上运⾏的程序的明显选择。我们还喜欢这样的想法,即不将开发⼈员限制为仅使⽤⼀种专⽤平台语⾔,⽽应将其潜在地向“所有⼈”开放。
⽆论如何,这就是理论。在实践中,将现有的编程语⾔移植到Wasm并不是⼀件容易的事。显然,它需要实现⼀个新的编译器后端。那很有趣,但是努⼒还不⽌于此:它还需要移植语⾔的运⾏时系统和库原语。还有⼀些功能,尤其是与更⾼级语⾔相关的功能,⽬前尚⽆法在Wasm中轻松实现,例如:线程,协程,异常和尾部调⽤。尽管提出了各种使Wasm具有各⾃功能的提议,但它们尚未最终确定标准化。
尽管已经有许多针对Wasm的实验语⾔实现,但⼤多数尚未准备就绪。其中包括低级系统语⾔,例如C / C ++和Rust。这些对于它们的⽤例⽆疑是很棒的,但是它们不是⽤于为Internet计算机开发⾼级应⽤程序的理想⼯具,在该⼯具中,与⼿动⼲预内存管理相⽐,可访问性,⽣产⼒和⾼保证往往更可取。
在某些平台(包括Internet计算机)上,运⾏Wasm需要克服其他障碍,并且它们必须与所提供的计算环境有关。例如,Dfinity的Internet 计算机与常规操作系统⼏乎没有相似之处:没有⽂件,I / O或其他
功能,这些功能通常在语⾔实现中被视为理所当然,并在运⾏时或库中⼤量使⽤。这意味着移植现有语⾔不仅仅是调整代码的问题:您可能需要到新的⽅法来替换缺少的平台功能的使⽤,删除它们或完全做出不同的设计选择。诸如WASI之类的努⼒试图在某种程度上解决这个问题,但仍处于起步阶段。
这些因素不可避免地使Dfinity的Internet计算机成为⼀种语⾔移植,即使采⽤已经存在通⽤Wasm端⼝的语⾔也是如此。
同时,⽤于Internet计算机的语⾔需要提供对平台主要概念的访问:具有异步消息传递功能的分布式编程模型,诸如循环(aka⽓体)之类的资源概念以及其他⼀些特质。当然,它们都可以作为库使⽤,但是⼀种本来包含适当结构的语⾔可以提供更加⽆缝的编程体验。
因此,如果我们⽆论如何都需要做⼀些⼯作才能起步,为什么不专⼼创建可以提供最佳⽤户体验并传达我们如何对Internet计算机编程的愿景的东西?
元⼦
因此,尽管存在创建另⼀种语⾔的所有风险,我们还是决定创建Motoko。我们想要⼀种安全,易于使⽤,⽆缝地展⽰平台概念的语⾔,以及对⼤多数程序员来说看起来⾜够友好和易于使⽤的语⾔。当前,
后⼀个⽬标⼏乎不可避免地使其牢固地位于语⾔的分号和⼤括号括号中。在这个营地中没有合适的语⾔。
但是Motoko相当传统的⽪肤只是表⾯的:它的内部是现代语⾔的内部。例如,每个构造都是⼀个表达式,它具有闭包,它具有变量类型和静态检查的模式匹配,它具有垃圾回收,当然,它具有实际上是健全的灵活类型系统,即,它确实保证了不存在某些错误,例如当机,未定义的⾏为,误解数据或仅丢失开关中的案例。没有孔!
同时,我们有意尝试不要幻想或重新发明轮⼦,⽽是建⽴在实践和理论上的丰富历史基础上,并承认在该领域数⼗年来的经验教训。除了集合了⼀系列易于理解的功能外,Motoko的设计还结合了许多⼩决定,以最⼩化安全⽅⾯的脚和错误,例如,默认情况下数字不会溢出,默认情况下本地变量是不可变的,默认情况下并发执⾏是原⼦的,默认情况下不会出现null,默认情况下字段是私有的,依此类推。哦,没有继承,只有⼦类型化。
实现Motoko的这些部分并将其编译为Wasm是常规的编译器技术。⽤OCaml编写的Motoko编译器使⽤类型化的中间表⽰形式,经过⼏次转换,然后吐出Wasm字节码。⽣成的Wasm模块包括⼀个⽤C和Rust编写的⼩型运⾏时系统,该系统主要使⽤Wasm内存作为堆来实现⼀个简单的垃圾收集器。这并不难,但是可以肯定的是这⾥有很⼤的改进潜⼒。
演员们
但是,Motoko的主要功能是在语法和类型系统上对actor的直接⽀持。演员模型是⼀个已有40多年历史的知名概念,但可悲的是,它⼏乎没有使其成为主流语⾔。演员就像⼀个对象(在Motoko中甚⾄看起来像⼀个对象),因为它封装了私有状态以及⼀组处理可以发送给它的消息的⽅法。但是所有消息发送都是异步的。因此,与OO中的常规⽅法不同,actor⽅法没有结果。⽽且,所有消息都是由参与者顺序接收的,也就是说,它具有隐式消息队列,并且即使同时发送消息,原⼦地执⾏的⽅法也是如此。
Actor是并发编程的绝佳模型,因为它们会⾃动防⽌竞争条件(由于原⼦性和封装状态)和死锁(因为执⾏不会阻塞),因此可以排除许多并发错误。所有这些都不需要程序员定义锁。参与者也是分布式编程的⼀个很好的模型,因为异步⾃然地处理了向潜在的远程接收者发送消息所涉及的延迟。最后,actor⾮常适合Dfinity的Internet计算机,在Internet计算机中,应⽤程序以所谓的容器的形式进⾏部署—本质上,以Wasm模块表⽰的参与者可以在⼦⽹之间进⾏通信。事实证明,Wasm的模块概念⾮常适合此操作,因为我们可以将模块导出直接解释为参与者⽅法。因此,Motoko演员会编译为Wasm模块,在该模块中,⽅法将导出为具有平台定义的特殊参数约定的Wasm函数。
简⽽⾔之,Motoko中的⼀个应⽤程序是⼀个参与者(或多个参与者),⽽参与者⼜是⼀个⼤型的异步
对象,被编译为⼀个Wasm模块。使⽤Wasm的内存概念,这样的参与者可以⽴即管理多达4 GiB的内部状态,尽管可以通过链接多个各⾃具有⾃⼰的内存的Wasm模块来进⼀步扩⼤内部状态。我们很想知道第⼀批⽤户将以多快的速度遇到此内存限制。
期货
为了使异步编程更⽅便并允许以顺序的“直接样式”表达,Motoko从编程语⾔研究的历史中⼜采⽤了40多年的想法,尽管幸运的是最近变得越来越流⾏:期货(也称为在某些社区中的承诺)。在Motoko中,它们以“异步值”的形式实现,即“ async ”类型的值,这些值由以“ async”关键字为前缀的表达式产⽣。特别地,函数主体可以是异步表达式,从⽽⾃然地替换了某些其他语⾔中存在的“异步函数”的更单⼀的概念。
这样,演员⽅法毕竟可以得到结果,只要结果是未来即可。可以等待期货来获得其价值,但只能在另⼀个异步表达式中进⾏,类似于其他现代语⾔所知的异步/等待单⼦。
Motoko编译器通过传统的CPS(连续传递样式)转换来实现此⽬的,将每个等待点转换为代表等待持续的单独的Wasm函数(加上⼀些关闭环境)。实际上,它是双管CPS,因为每条消息还可以具有带有相应故障继续的故障回复。按照惯例,⼀种具有异步结果的⽅法是⼀种发送带有结果值作为参数的回复消息的⽅法。该消息由创建的继续功能接收,然后可以继续执⾏已捕获的执⾏。等待回复不会阻
⽌演员-它可以在此期间⾃由接收其他消息。
坚持不懈
Motoko的另⼀个重要考虑因素是允许开发⼈员利⽤区块链技术,⽽不必学习全新的计算类型。因此,我们提取了您可能需要的当前区块链编程语⾔的所有特殊知识。例如,没有可观察到的块或块⾼度概念,没有⽤于更新区块链上状态的显式构造,也没有其他API将数据写⼊持久性存储,例如⽂件或数据库(尽管可以将其模拟为库) 。⽽是,Internet计算机实现正交持久性-另⼀个古⽼的想法是,程序具有“永远运⾏”的错觉,并且它的内存保持有效(⾄少直到明确将其删除)。在Motoko中,这意味着开发⼈员不必担⼼显式保存其数据,也不必担⼼⽂件或外部数据库的问题:程序变量中存储的任何值或数据结构在下⼀条消息到达时仍将存在,即使⼏个⽉后。
该平台负责在⽅法调⽤之间透明地保存和恢复容器的私有状态。由于Wasm模块的状态清楚地隔离在模块的内存,全局变量和表中,因此相对容易地将其改装到Wasm引擎上。在⼤多数情况下,使⽤操作系统公开的虚拟内存技术来观看Wasm内存就⾜够了。这样,平台便知道何时修改了此类内存中的页⾯,并且可以采取必要的措施来保留脏页,并为分布式共识协议哈希它们。
超越本⼦:接⼝定义
由于Internet计算机运⾏的是Wasm,因此Motoko只是创建应⽤程序的⼀种选择-故意这样做。我们期待提供其他语⾔选择。即使这样,由于每种语⾔将统⼀编译为以Wasm表⽰的容器,因此这些容器可以通过消息发送⾃由地相互通信,⽽不论其源语⾔是什么。
为了使此类互操作性得到良好定义,我们还引⼊了⼀种独⽴于Motoko的名为Candid的通⽤接⼝定义语⾔(IDL)。它描述了容器可以理解的消息集以及发送的数据类型。在Candid中,数据是由独⽴于Motoko类型系统或任何其他编程语⾔的规范数据类型(数字,⽂本,数组,记录,变体,函数,对其他容器的引⽤)组合⽽成的。
ew,还有另⼀种类型的系统吗?好吧,程序员可能会很⾼兴Motoko编译器可以⾃动使⽤和⽣成⽤于actor导出和导⼊的此类接⼝描述,并将它们映射到对应的Motoko类型。它还会⾃动⽣成正确的Wasm代码,以对每个消息的参数数据进⾏序列化和反序列化,从⽽透明地将Motoko的内部表⽰形式与Candid指定的⼆进制格式进⾏相互转换。
这样,Motoko程序可以以⼀种有类型的⽅式与外部容器进⾏通信,并像将其作为程序中的本地对象⼀样表⽰远程调⽤。不管远程容器是⽤Motoko还是⽤Rust编写的,这都是⽆关紧要的。罐的接⼝描述⾜以作为类型信息。除了简单的便利性之外,接⼝还提供了⼀种强⼤的模块化形式,可以在不访问其实现的情况下针对其他参与者/容器对程序进⾏类型检查。
结论
我们的⽬标是,互联⽹计算机将成为⼀个多语⾔平台,所有语⾔都具有同等的权利,可以跨容器边界⽆缝交互,⽽Motoko只是众多选择中的⼀种。这对于使Internet计算机平台成为开放平台⾮常重要。
迄今为⽌,Wasm已被证明是实现此⽬标的通⽤代码格式。我们特别受益于它的简单性,模块化以及安全和确定性的语义。但是,尽管具有这些不错的特性,但移植编译器和库,更不⽤说在不同Wasm⽣态系统之间进⾏应⽤程序移植,并不像⼈们希望的那样简单,因为它涉及的不仅仅是裸代码。但是Wasm仍然很年轻,预计会有⼀些障碍。
我们迫切期待的最⼤的Wasm功能是⼀流的引⽤类型和函数引⽤的出现。这将使系统API更加整洁,Wasm模块(以及Motoko程序)将通过该API与Internet Computer平台进⾏通信。有兴趣的程序员可以到更多的细节有关SDK的位置,并通过GitHub上有助于元⼦基础库在这⾥。
安德烈亚斯·罗斯伯格(Andreas Rossberg)是DFINITY的研究员兼⼯程师,他领导Motoko(DFINITY互联⽹计算机的新编程语⾔)的开发。在加⼊DFINITY之前,他是Google的⼯程师,负责在Chrome上运⾏的V8 JavaScript引擎,还曾在Max Planck软件系统研究所从事编程语⾔理论,设计和实现⽅⾯的学术研究。他是WebAssembly的共同设计师之⼀,并撰写了其规范。下⾯,他讨论了DFINITY在Internet计算机上使⽤WebAssembly的过程以及设计Motoko的经验。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。