1.1「Motoko——Basic concepts and terms && Mutable state」

1.【从声明到块表达式】

“声明列表(Declarations)”:

let x = 1;
let y = x + 1;
x * y + x

这三行语句是一个声明列表。

而一个声明列表自身不是一个表达式,所以我们不能用声明列表本身来作为声明另外一个值的初始化值。

“块表达式(Block expressions)”:

我们可以在声明列表的两端加上一对花括号来将其转换成块表达式。

如:

{let x = 1; let y = x + 1; x * y + x  //注意语法细节 最后一条语句不加分号
}

⚠️但块表达式只能用作控制流表达式的子式(like if, loop, case…)

在其他地方我们可以用 do{ … } 来代表块表达式,以此与object literals进行区分。

For example, do {} is the empty block of type (), while {} is an empty record of record type {}.

应用举例:

let z = do { let x = 1; let y = x + 1; x * y + x
};

2.【忽略声明列表中的非单位类型(non-unit-typed)表达式】

我们总是可以通过显式使用ignore忽略任何未使用的结果值来克服这种单元类型限制。例如:

let x = 1;
ignore(x + 42);
let y = x + 1;
ignore(y * 42);
x * y + x;

即:若有“返回值”但不使用,则必须加上ignore,否则编译器会报错。

3.【使用Motoko基础库(base library)】

To import from the base library, use the import keyword. Give a local module name to introduce, in this example D for “Debug”, and a URL where the import declaration may locate the imported module:

import D "mo:base/Debug";
D.print("hello world");

In this case, we import Motoko code (not some other module form) with the mo:prefix. We specify the base/ path, followed by the module’s file name Debug.mominus its extension.

Printing using Debug.print and debug_show:

Above, we print the text string using the function print in library Debug.mo:

print: Text -> ()

The function print accepts a text string (of type Text) as input, and produces the unit value (of unit type, or ()) as its output.

Because unit values carry no information, all values of type unit are identical, so the print function doesn’t actually produce an interesting result. Instead of a result, it has a side effect. The function print has the effect of emitting the text string in a human-readable form to the output terminal. Functions that have side effects, such as emitting output, or modifying state, are often called impure. Functions that just return values, without further side-effects, are called pure. We discuss the return value (the unit value) in detail below, and relate it to the void type for readers more familiar with that concept.

Finally, we can transform most Motoko values into human-readable text strings for debugging purposes, without having to write those transformations by hand.

The debug_show primitive permits converting a large class of values into values of type Text.

For instance, we can convert a triple (of type (Text, Nat, Text)) into debugging text without writing a custom conversion function ourselves:

import D "mo:base/Debug";
D.print(debug_show(("hello", 42, "world")))

Using these text transformations, we can print most Motoko data as we experiment with our programs.

4.【Accommodating incomplete code】

Sometimes, in the midst of writing a program, we want to run an incomplete version, or a version where one or more execution paths are either missing or simply invalid.

To accommodate these situations, we use the xxx, nyi and unreachable functions from the base Prelude library, explained below. Each wraps a general trap mechanism, explained further below.

Use short-term holes:

Short-term holes are never committed to a source repository, and only ever exist in a single development session, for a developer that is still writing the program.

Assuming that earlier, one has imported the prelude as follows:

import P "mo:base/Prelude";

The developer can fill any missing expression with the following one:

P.xxx()

The result will always type check at compile time, and will always trap at run time, if and when this expression ever executes.

Document longer-term holes:

By convention, longer-term holes can be considered “not yet implemented” (nyi) features, and marked as such with a similar function from the Prelude module:

P.nyi()

Document unreachable code paths:

In contrast to the situations above, sometimes code will never be filled, since it will never be evaluated, assuming the coherence of the internal logic of the programs’ invariants.

To document a code path as logically impossible, or unreachable, use the base library function unreachable:

P.unreachable()

As in the situations above, this function type-checks in all contexts, and when evaluated, traps in all contexts.

Execution traps stop the program:

Each form above is a simple wrapper around the always-fail use of the assert primitive:

assert false

Dynamically, we call this program-halting behavior a program(-generated) trap, and we say that the program traps when it executes this code. It will cease to progress further.

5.【不可变变量与变量的声明】

let text : Text = "abc";
let num : Nat = 30;
var pair : (Text, Nat) = (text, num);
var text2 : Text = text;

在上面这个声明列表中,let关键字用来声明一个在当前作用域中的immutable variables(不可变的变量);var关键字用来声明一个在当前作用域中的mutable variables(可变变量)。

6.【Annotation——声明类型】

在1.的声明列表中,在变量名后面加个冒号,后面跟一个变量类型关键字,作为一个annotation,用来解释说明(or限定)前面变量的类型。

例:

func( i : Nat ) : Nat

表示一个没有名字的(提供临时接口的)函数,其形参类行为Nat,返回值类型为Nat。

※一个名为 gen 的具有相同功能的函数还可以表示为:

gen : Nat -> Nat    //这就是函数gen的type

7.【可变变量的Assignment赋值语句 := 】

(代码上文语境略)
text2 := text2 # "xyz";
pair := (text2, pair.1);

易知,赋值语句写作 :=

/*In this example, we update text2 by appending string constant "xyz"to its suffix.*/

赋值操作 := 是常规的,适用于所有类型。

类比C/C++语言,Motoko也支持类似于+=、#=的特殊赋值语句。

赋值操作的完整列表列出了相应类型(数字类型(Nat类型)、布尔类型和文本类型)上的数字、逻辑和文本操作。

8.【常数组Immutable Arrays】

声明(例):

let a : [Nat] = [1, 2, 3] ;

元素为Nat类型 的常数组的数据类型为 [Nat]

The array a above holds three natural numbers, and has type [Nat]. In general, the type of an immutable array is [_], using square brackets around the type of the array’s elements, which must share a single common type, in this case Nat.

访问:

We can project from (read from) an array using the usual bracket syntax ([ and ]) around the index we want to access.

let x : Nat = a[2] + a[0] ;

Every array access in Motoko is safe. Accesses that are out of bounds will not access memory unsafely, but instead will cause the program to trap, as with an assertion failure.

9.【Array标准模版库(module)】

The Motoko standard library provides basic operations for immutable and mutable arrays. It can be imported as follows:

import Array "mo:base/Array";

实际导入了以下内容:

{append = func;chain = func;equal = func;filter = func;find = func;flatten = func;foldLeft = func;foldRight = func;freeze = func;init = func;keys = func;make = func;map = func;mapEntries = func;mapFilter = func;mapResult = func;tabulate = func;tabulateVar = func;thaw = func;vals = func
} :module {append : <A>([A], [A]) -> [A];chain : <A, B>([A], A -> [B]) -> [B];equal : <A>([A], [A], (A, A) -> Bool) -> Bool;filter : <A>([A], A -> Bool) -> [A];find : <A>([A], A -> Bool) -> ?A;flatten : <A>([[A]]) -> [A];foldLeft : <A, B>([A], B, (B, A) -> B) -> B;foldRight : <A, B>([A], B, (A, B) -> B) -> B;freeze : <A>([var A]) -> [A];init : <A>(Nat, A) -> [var A];keys : <A>([A]) -> Iter<Nat>;make : <A>(A) -> [A];map : <A, B>([A], A -> B) -> [B];mapEntries : <A, B>([A], (A, Nat) -> B) -> [B];mapFilter : <A, B>([A], A -> ?B) -> [B];mapResult : <A, R, E>([A], A -> Result<R, E>) -> Result<[R], E>;tabulate : <A>(Nat, Nat -> A) -> [A];tabulateVar : <A>(Nat, Nat -> A) -> [var A];thaw : <A>([A]) -> [var A];vals : <A>([A]) -> Iter<A>
}

In this section, we discuss some of the most frequently used array operations. For more information about using arrays, see the Array library descriptions.

10.【Allocate an immutable array with varying content】

In general, each new array allocated by a program will contain a varying number of varying elements. Without mutation, we need a way to specify this family of elements “all at once”, in the argument to allocation.

To accommodate this need, the Motoko language provides the higher-order array-allocation function Array.tabulate, which allocates a new array by consulting a user-provided “generation function” gen for each element.

func tabulate<T>(size : Nat, gen : Nat -> T) : [T]

Function gen specifies the array as a function value of arrow type Nat → T, where T is the final array element type.

The function gen actually functions as the array during its initialization: It receives the index of the array element, and it produces the element (of type T) that should reside at that index in the array. The allocated output array populates itself based on this specification.

For instance, we can first allocate array1 consisting of some initial constants, and then functionally-update some of the indices by “changing” them (in a pure, functional way), to produce array2, a second array that does not destroy the first.

let array1 : [Nat] = [1, 2, 3, 4, 6, 7, 8] ;
let array2 : [Nat] = Array.tabulate<Nat>(7, func(i:Nat) : Nat { if ( i == 2 or i == 5 ) { array1[i] * i }    // change 3rd and 6th entries else { array1[i] }    // no change to other entries
} ) ;

11.【可变数组Mutable Array】

元素为Nat类型的可变数组的数据类型为 [var Nat]

声明:

To indicate allocation of mutable arrays (in contrast to the forms above, for immutable ones), the mutable array syntax [var _] uses the var keyword, in both the expression and type forms:

let a : [var Nat] = [var 1, 2, 3] ;

As above, the array a above holds three natural numbers, but has type [var Nat].

12.【Allocate a mutable array with dynamic size】

To allocate mutable arrays of non-constant size, use the Array_init primitive, and supply an initial value:

func init<T>(size : Nat, x : T) : [var T]

For example:

var size : Nat = 42 ;
let x : [var Nat] = Array.init<Nat>(size, 3);

The variable size need not be constant here; the array will have size number of entries, each holding the initial value 3.

结果:

[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] : [var Nat]

Mutable updates:

可以用赋值语句,如

a[2] := 42;

对可变数组元素进行修改。

13.【Subtyping does not permit mutable to be used as immutable

不能在期望使用 [Nat] 常数组的地方使用 [var Nat] 可变数组。

PS:Motoko forbids uses of mutable arrays across asynchronous communication, where mutable state is never shared.

1.1「Motoko——Basic concepts and terms Mutable state」相关推荐

  1. Cluster analysis :Basic Concepts and Algorithms -- Part 5 Cluster Evalation

    系列文章 Cluster analysis :Basic Concepts and Algorithms – Part 1 Overview Cluster analysis :Basic Conce ...

  2. Cluster analysis :Basic Concepts and Algorithms -- Part 3 Hierarchical Clustering

    系列文章目录 Cluster analysis :Basic Concepts and Algorithms – Part 1 Overview Cluster analysis :Basic Con ...

  3. 未来:spring响应式编程 Hands-On Reactive Programming in Spring 5(二)------Basic Concepts

    看完这篇文章你会有很大收获! 好学近乎知,力行近乎仁,知耻而后勇. The previous chapter explained why it is important to build reacti ...

  4. 1.3「Motoko——Actors and async data」

    1.3「Motoko--Actors and async data」 2021.5.3 Motoko笔记 Internet Computer的编程模型由内存隔离容器组成,这些容器通过二进制数据编码的异 ...

  5. 如何利用 C# 爬取「当当 - 计算机与互联网图书销量榜」!

    前段时间我们介绍了如何利用 C# 语言来爬取"京东 - 计算机与互联网图书销量榜" 网页的方法,通过该方法,我们能够获得"京东"的图书销售排行榜数据. 可是,读 ...

  6. 如何利用 C# 爬取「猫眼电影:热映口碑榜」及对应影片信息!

    我们生活在一个快节奏的时代里,每天除了辛苦的提升自己,为生活打拼之外,偶尔的放松去看场电影也是必要的.可是能够抽出的时间有限,选择看哪部电影就是一个挠头的问题了. 幸好,有类似猫眼电影.豆瓣电影.淘票 ...

  7. 「绩效领导力:聚焦战略目标有效落地」沙龙圆满落幕

    "6月17日下午,由互次方科技和菜根发展联合主办的「绩效领导力:聚焦战略目标有效落地」沙龙活动在中国(杭州)人工智能小镇举行." 2021年,疫情余波未平,对各行各业都造成了一定冲 ...

  8. 阿里云 OAM 入选「2020中国技术力量年度榜单」,定义云原生应用交付标准

    2020 年 11 月 19 日,备受关注的「2020 中国技术力量年度榜单」评选结果终于揭晓.在该榜单设立的「年度开源新锐项目」.「开源杰出贡献人物」.「云原生行业落地典范」三大分项中,阿里云云原生 ...

  9. 「AI在左,营销在右」互动营销创意破圈,这事儿不难

    写在篇首 营销创意是个「体力活」,考验的是N次改稿中依然振作起来的体力和毅力:从业10年的资深广告人在面对Z世代的脑洞需求时,只能说:套路无效:创意方案从PlanA-PlanZ可以绕字母表一个循环但可 ...

最新文章

  1. R语言ggplot2可视化图中添加希腊字母实战
  2. 将一个PPT文档按页分割成多个PPT文档的代码
  3. LoadRunner 测试Tuxedo的问题
  4. \\ n和\\ r之间的区别?
  5. css sprite技巧详解
  6. 【数据竞赛】组合特征的构建技巧,如何快速构建百大组合特征池
  7. 《移动应用开发》作业——HTML、CSS
  8. AWS共享资源的警告
  9. tcpreplay工具安装使用
  10. php 白名单,php实现ip白名单黑名单功能
  11. WampServer服务器离线问题的解决方法
  12. call mysql_connect_Call to undefined function mysql_connect()
  13. Kaggle/Titanic python分析和建模
  14. 程序员之道——编程也是一门艺术
  15. FileZilla Server 设置
  16. (8)USB协议 —— 高速模式握手过程
  17. wamp 升php7,wamp升级php7
  18. 洛谷 P4234 LCT + 排序 + 枚举
  19. 混合高斯背景建模原理
  20. 用AI 来一键体验“返老还童”的快乐!马化腾、李彦宏、杨幂都能还原的那种 |儿童节福利...

热门文章

  1. 超越过去三年冠军,AAMAS2019 桥牌游戏论文揭秘
  2. 本周AI热点回顾:何恺明RegNet超越EfficientNet、数学难题“abc猜想”封印终被开启、微软麻将 AI 论文发布
  3. c语言写一个测试缘分的程序,【心理测试】测你的缘分能求来吗
  4. 奖客富翁系统代码C语言,木马代码-c语言木马代码,最简单的,我保证不做违法的 – 手机爱问...
  5. 电磁场与电磁波(4)——导体、电介质、高斯定理
  6. PHP中RabbitMQ之amqp扩展实现(四)
  7. Uber实时大数据系统架构分析-Kafka-Samza-Siddhi
  8. BIOS知识枝桠 -- PCIE
  9. 链接生成-链接生成器-免费批量在线链接生成器
  10. 分析快、易操作的数据分析工具推荐