", line 5, in D
-.f(self) is already defined in C. To override f, it must be added `Override` decorator and its type must be `Self.() -> Nat` or the subtype of that
-.f(self)は既にCで定義されています。オーバーライドするためには`Override`デコレータを付与し、`Self.() -> Nat`型かそのサブタイプである必要があります。
+To override f, it must be added `Override` decorator and its type must be `Self.() -> Nat` or the subtype of that
+f(self) is already defined in C. To override f, it must be added `Override` decorator and its type must be `Self. To override, it must be given an `Override` decorator and its type must be `Self.() -> Nat` or the subtype of that.f(self).
```
-## 类型检查
-
-类型检查大体上只限于函数自变量的类型检查。在 Python 中,大部分的操作都是方法调用。调用时,如果对象所属的类中附有方法的话,就到此为止。
+## Type checking
+Type checking is generally all about checking the type of function arguments.
+In Python, most operations are method calls. If the class to which the object belongs does not have a method attached to it at the time of the call, that's it.
```python
def f(x):
@@ -81,7 +81,6 @@ f(c)
f(1) # TypeError
```
-
```erg
# f: |T, X <: {.m = Self.() -> T}| X -> T
f(x) = x.m()
diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md
index 319b137e..4d643c3b 100644
--- a/doc/zh_CN/syntax/00_basic.md
+++ b/doc/zh_CN/syntax/00_basic.md
@@ -1,21 +1,23 @@
-# 基本信息
+# Basics
-> :此文档尚未完成。未进行校样(文体、正确链接等)。此外,Erg 的语法在 0.* 版本之间可能会有颠覆性的改变,随之而来的文档更新可能跟不上。请事先谅解。
-> 此外,如果你发现本文档中的错误,请从或提出更正建议。
+> __Warning__: This document is incomplete. It has not been proofread (style, correct links, mistranslation, etc.). Also, Erg's syntax may be change destructively during version 0.*, and the documentation may not have been updated accordingly. Please be aware of this beforehand.
+> If you find any errors in this document, please report then to [here form](https://forms.gle/HtLYRfYzWCAaeTGb6) or [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new). We would appreciate your suggestions.
+>
+> [The Erg book original version (Japanese)](http://mtshiba.me/TheErgBook/)
-本文档介绍了 Erg 的基本语法。和位于不同的目录中。
+This document describes the basic syntax of Erg. The [Standard API](./API/index.md) and [internal documents for Erg contributors](./dev_guide/index.md) are located in another directory.
-## Hello, World!
-
-首先按照惯例举办 Hello World 活动吧。
+## Hello, World!
+First, let's do "Hello World".
```erg
print!("Hello, World!")
```
-跟 Python 和同系语言差不多。引人注目的是后面的,我会慢慢解释它的含义。此外,在 Erg 中,如果解释不准确,可以省略括号。与 Ruby 类似,它可以省略括号,但它不能具有多个解释,也不能在参数为 0 时省略,就像 Python 一样。
-
+This is almost identical to Python and other languages in the same family. The most striking feature is the `!`, the meaning of which will be explained later.
+In Erg, parentheses `()` can be omitted unless there is some confusion in interpretation.
+The omission of parentheses is similar to Ruby, but it is not possible to omit parentheses that can be interpreted in more than one way.
```erg
print! "Hello, World!" # OK
@@ -27,43 +29,71 @@ print! f x # OK, interpreted as `print!(f(x))`
print!(f(x, y)) # OK
print! f(x, y) # OK
print! f(x, g y) # OK
-print! f x, y # NG, can be taken to mean either `print!(f(x), y)` or `print!(f(x, y))`
+print! f x, y # NG, can be taken to mean either `print!(f(x), y)` or `print!(f(x, y))` print!
print!(f x, y) # NG, can be taken to mean either `print!(f(x), y)` or `print!(f(x, y))`
print! f(x, g y, z) # NG, can be taken to mean either `print!(x, g(y), z)` or `print!(x, g(y, z))`
```
-## 脚本
+## Scripts
-Erg 代码称为脚本。可以以文件格式(.er)保存和运行脚本。
+Erg code is called a script. Scripts can be saved and executed in file format (.er).
-## 注释
+## REPL/File Execution
-及更高版本将作为注释忽略。当你想要解释代码的意图,或者想要暂时禁用代码时,可以使用此选项。
+To start REPL, simply type:
+```sh
+> erg
+```
+
+`>` mark is a prompt, just type `erg`.
+Then the REPL should start.
+
+```sh
+> erg
+Starting the REPL server...
+Connecting to the REPL server...
+Erg interpreter 0.2.4 (tags/?:, 2022/08/17 0:55:12.95) on x86_64/windows
+>>>
+```
+
+Or you can compile from a file.
+
+```sh
+> 'print! "hello, world!"' >> hello.er
+
+> erg hello.er
+hello, world!
+```
+
+## Comments
+
+The code after `#` is ignored as a comment. Use this to explain the intent of the code or to temporarily disable the code.
```erg
-# コメント
-## `#`以降は改行されるまで無視されるので、`#`は何個あってもOK
+# Comment
+# `#` and after are ignored until a new line is inserted
#[
-複数行コメント
-対応する`]#`のところまでずっとコメントとして扱われます
+Multi-line comment
+Treated as a comment all the way up to the corresponding `]#`
]#
```
-## 表达式,分隔符
-
-脚本是一系列表达式(expression)。表达式是一个可以计算和评估的东西,在 Erg 中几乎所有的东西都是表达式。使用分隔符-换行符或分号-分隔每个表达式。Erg 脚本基本上是从左到右、从上到下进行评估的。
+## Expressions, separators
+A script is a series of expressions. An expression is something that can be calculated or evaluated, and in Erg almost everything is an expression.
+Each expression is separated by a separator - either a new line or a semicolon `;`-.
+Erg scripts are basically evaluated from left to right, top to bottom.
```erg
-n = 1 # 代入式
-f(1, 2) # 関数適用式
-1 + 1 # 演算子適用式
+n = 1 # assignment expression
+f(1, 2) # function-call expression
+1 + 1 # operator-call expression
f(1, 2); 1 + 1
```
-有一个称为即时块的功能,它使用块中最后计算的表达式作为变量的值,如下所示。这与无参数函数不同,它不使用。请注意,方块只在现场评估一次。
-
+As shown below, there is a syntax called instant block that takes the last expression evaluated in the block as the value of the variable.
+This differs from a function with no arguments, which does not add `()`. Note that instant blocks are evaluated only once on the fly.
```erg
i =
@@ -72,24 +102,22 @@ i =
assert i == 2
```
-这不能通过分号()来实现。
-
+This cannot be accomplished with a semicolon (`;`).
```erg
i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses
```
-## 缩进
-
-Erg 使用与 Python 相同的缩进来表示块。触发块开始的运算符(特殊格式)有五种:,,,和(其他运算符不是,但和也会生成缩进)。它们各自的含义将在后面介绍。
+## Indentation
+Erg, like Python, uses indentation to represent blocks. There are five operators (special forms) that trigger the start of a block: `=`, `->`, `=>`, `do`, and `do!` (In addition, `:` and `|`, although not operators, also produce indentation). The meanings of each are described later.
```erg
f x, y =
x + y
for! 0..9, i =>
- print! i
+ print!
for! 0..9, i =>
print! i; print! i
@@ -101,8 +129,7 @@ ans = match x:
_ -> "unknown"
```
-如果一行太长,可以使用在中间换行。
-
+If a line is too long, it can be broken using `\`.
```erg
# this does not means `x + y + z` but means `x; +y; +z`
diff --git a/doc/zh_CN/syntax/01_literal.md b/doc/zh_CN/syntax/01_literal.md
index 2e5bfc1f..f8336328 100644
--- a/doc/zh_CN/syntax/01_literal.md
+++ b/doc/zh_CN/syntax/01_literal.md
@@ -1,43 +1,40 @@
# Literal
-## 基本文字
-
-### 整数文字(Int Literal)
+## Basic Literals
+### Int Literal
```erg
0, -0, 1, -1, 2, -2, 3, -3, ...
```
-### 有理数文字(Ratio Literal)
-
+### Ratio Literal
```erg
0.00, -0.0, 0.1, 400.104, ...
```
-如果文字中的整数或小数部分为,则可以省略。
-
+If a `Ratio` literal has an integer or decimal part of `0`, you can omit the `0`.
```erg
assert 1.0 == 1.
assert 0.5 == .5
```
-> :这个名为的函数用于指示与相等。
-以下文档可能会使用来表示结果相等。
+> __Note__: This function `assert` was used to show that `1.0` and `1.` are equal.
+Subsequent documents may use `assert` to indicate that the results are equal.
-### 字符串文字(Str Literal)
-
-可以使用 Unicode 表示的任何字符串。与 Python 不同的是,不能进行标定。如果要在字符串中使用,请使用。
+### Str Literal
+Any Unicode-representable string can be used.
+Unlike Python, quotation marks cannot be enclosed in `'`. If you want to use `"` in a string, use `\"`.
```erg
"", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "السَّلَامُ عَلَيْكُمْ", ...
```
-使用将表达式填充到字符串中。这称为字符串插值。如果要输出和本身,请输入和。
-
+`{}` allows you to embed expressions in strings. This is called string interpolation.
+If you want to output `{`, `}` itself, use `\{`, `\}`.
```erg
assert "1 + 1 is 2" == "{1} + {1} is {1+1}"
@@ -45,84 +42,74 @@ s = "1+1"
assert "\{1+1}\" == "\{{s}\}"
```
-### 指数文字(Exponential Literal)
-
-这是在学术计算中经常使用的指数表示法的文字。它将成为类型为的实例。用于表示非常大/非常小的数字。与 Python 相同。
+### Exponential Literal
+This is a literal representing exponential notation often used in academic calculations. It is an instance of type ``Ratio``.
+The notation is the same as in Python.
```erg
1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ...
```
-
```erg
assert 1e-10 == 0.0000000001
```
-## 文字的组合(复合文字)
+## Compound Literals
-在文档中,这些文字都有单独的说明,有关详细信息,请参阅。
-
-### 数组文字(./10_array.md)
+Each of these literals has its own documentation describing them separately, so please refer to that documentation for details.
+### [Array Literal](./10_array.md)
```erg
[], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ...
```
-### 字典文字(./11_dict.md)
-
+### [Dict Literal](./11_dict.md)
```erg
{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
```
-### 元组文字(./12_tuple.md)
-
+### [Tuple Literal](./12_tuple.md)
```erg
(), (1, 2, 3), (1, "hello", True), ...
```
-### 记录文字(./13_record.md)
-
+### [Record Literal](./13_record.md)
```erg
{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
```
-### 集文字(./14_set.md)
-
+### [Set Literal](./14_set.md)
```erg
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ...
```
-与文字不同,删除重复元素。
-
+As a difference from `Array` literals, duplicate elements are removed in `Set`.
```erg
assert {1, 2, 1} == {1, 2}
```
-### 看起来像文字但不像文字的东西
-
-## 真伪对象(Boolean Object)
+### What looks like a literal but isn't
+## Boolean Object
```erg
True, False
```
-### None 对象
-
+### None Object
```erg
None
```
-## 范围对象(Range Object)
-
+## Range Object
```erg
assert 0..5 == {1, 2, 3, 4, 5}
@@ -131,29 +118,26 @@ assert 0..<10 notin 10
assert 0..9 == 0..<10
```
-## 浮点对象(Float Object)
-
+## Float Object
```erg
assert 0.0f64 == 0
assert 0.0f32 == 0.0f64
```
-对象乘以,即的单位对象。
-
-## 复杂对象(Complex Object)
+Float objects are constructed by multiplying a `Ratio` object by `f64`, which is a `Float 64` unit object.
+## Complex Object
```erg
1+2im, 0.4-1.2im, 0im, im
```
-对象仅通过与的运算组合来表示,是一个虚单位对象。
+A `Complex` object is simply an arithmetic combination of an imaginary unit object, `im`.
## *-less multiplication
-Erg 可以省略表示乘法的,除非解释正确。但是,运算符的连接强度设置为大于。
-
+In Erg, you can omit the `*` to indicate multiplication as long as there is no confusion in interpretation. However, the combined strength of the operators is set stronger than `*`.
```erg
# same as `assert (1*m) / (1*s) == 1*(m/s)`
diff --git a/doc/zh_CN/syntax/02_name.md b/doc/zh_CN/syntax/02_name.md
index 8bc44707..8b87e4a2 100644
--- a/doc/zh_CN/syntax/02_name.md
+++ b/doc/zh_CN/syntax/02_name.md
@@ -1,56 +1,55 @@
-# 变量
+# Variable
-变量是代数的一种。Erg 中的代数-有时也称为变量(如果正确)-是指命名对象并使其可从代码中的其他位置使用的功能。
-
-变量定义如下。部分称为变量名(或标识符),称为赋值运算符,部分称为赋值。
+Variables are a type of algebra; algebra in Erg - sometimes simply referred to as variable if there is no confusion - refers to the feature to name objects and make them referable from elsewhere in the code.
+A variable is defined as follows.
+The `n` part is called the variable name (or identifier), `=` is the assignment operator, and the `1` part is the assigned value.
```erg
n = 1
```
-以这种方式定义的随后可用作表示整数对象的变量。此系统称为赋值(或绑定)。我们刚才提到了是一个对象。我们将在后面讨论对象是什么,但我们现在应该将其赋值到赋值运算符(例如)的右侧。
-
-如果要指定变量的类型。类型是指对象所属的集合,这也将在后面介绍。指定为自然数()。
+The `n` defined in this way can thereafter be used as a variable to denote the integer object `1`. This system is called assignment (or binding).
+We have just said that `1` is an object. We will discuss what an object is later, but for now we will assume that it is something that can be assigned to, i.e., on the right side of the assignment operator (`=`, etc.).
+If you want to specify the "type" of a variable, do the following. The type is roughly the set to which an object belongs, as will be explained later.
+Here we specify that `n` is a natural number (`Nat`) type.
```erg
n: Nat = 1
```
-请注意,与其他语言不同,多重赋值是不可能的。
-
+Note that, unlike other languages, multiple assignments are not allowed.
```erg
# NG
-l1 = l2 = [1, 2, 3] # SyntaxError: 多重代入はできません
+l1 = l2 = [1, 2, 3] # SyntaxError: multiple assignment not allowed
# OK
l1 = [1, 2, 3]
l2 = l1.clone()
```
-也不能对变量进行重新赋值。可以使用的功能,即保持可变状态的功能将在后面讨论。
-
+It is also not possible to reassign to a variable. The syntax that can be used instead, to hold mutable states, are described later.
```erg
i = 1
i = i + 1 # AssignError: cannot assign twice
```
-你可以在内部范围内定义具有相同名称的变量,但它们只是放在上面,而不是破坏性地重写值。如果返回到外部范围,则值也将返回。请注意,这与 Python“语句”的作用域不同。这类功能通常称为阴影。但是,与其他语言的阴影不同,你不能在同一范围内进行阴影。
-
+You can define a variable with the same name in the inner scope, but you are only covering it over, not destructively rewriting its value. If you go back to the outer scope, the value will return as well.
+Note that this is a different behavior than the Python "statement" scope.
+This kind of functionality is generally referred to as shadowing. However, unlike shadowing in other languages, you cannot shadow in the same scope.
```erg
x = 0
# x = 1 # AssignError: cannot assign twice
if x.is_zero(), do:
- x = 1 # 外側のxとは同名の別物
+ x = 1 # different from outer x with same name
assert x == 1
assert x == 0
```
-以下乍一看似乎可行,但还是不行。这不是技术限制,而是设计判断。
-
+The following may seem possible at first glance, but it is still not possible. This is a design decision, not a technical constraint.
```erg
x = 0
@@ -60,10 +59,10 @@ if x.is_zero(), do:
assert x == 0
```
-## 常数
-
-常数也是代数的一种。如果标识符以大写字母开头,则将其视为常量。它被称为常量,因为它一旦定义就不会改变。部分称为常量名称(或标识符)。其他与变量相同。
+## Constants
+Constants are also a type of algebra. If you start an identifier with a capital letter, it is treated as a constant. They are called constants because once defined, they do not change.
+The `N` part is called the constant name (or identifier). Otherwise, it is the same as a variable.
```erg
N = 0
@@ -72,10 +71,11 @@ if True, do:
pass()
```
-常量在定义的范围之后变得不变。我也不能阴影。由于该性质,常量可用于模式匹配。后面我们会讨论模式匹配。
+Constants are immutable beyond the defined scope. They cannot be shadowed. Because of this property, constants can be used in pattern matching. Pattern matching is explained later.
-你可能希望将常量用于不变的值,如数学常量或有关外部资源的信息。除之外的对象通常是全部大写字母(所有字符都是大写的样式)。
+For example, constants are used for mathematical constants, information about external resources, and other immutable values.
+It is common practice to use all-caps (style in which all letters are capitalized) for identifiers of objects other than [types](./type/01_type_system.md).
```erg
PI = 3.141592653589793
@@ -83,7 +83,6 @@ URL = "https://example.com"
CHOICES = ["a", "b", "c"]
```
-
```erg
PI = 3.141592653589793
match! x:
@@ -91,20 +90,19 @@ match! x:
other => print! "other"
```
-当为时,上面的代码输出。如果将更改为其他数字,则输出。
-
-有些常量是不能赋值的。可变对象等等。可变对象是可以更改其内容的对象,如下所述。这是因为常量只能由常量表达式赋值。我们还将在后面讨论常数表达式。
+The above code prints `π` when `x` is `3.141592653589793`. If `x` is changed to any other number, it prints `other`.
+Some objects cannot be bound as constants. Mutable objects, for example. Mutable objects are objects whose states can be changed, as described in detail later.
+This is because of the rule that only constant expressions can be assigned to constants. Constant expressions are also discussed later.
```erg
X = 1 # OK
X = !1 # TypeError: cannot define Int! object as a constant
```
-## 删除代数
-
-可以使用函数删除代数。所有依赖于代数(直接引用代数的值)的其他代数都将被删除。
+## Delete an Variable
+You can delete an variable by using the `Del` function. All other variables that depend on the variable (that is, that refer directly to the value of the variable) are also removed.
```erg
x = 1
@@ -119,27 +117,24 @@ Del y, Z
f(2) # NameError: f is not defined (deleted in line 6)
```
-但是,只能删除模块中定义的代数。不能删除内置常量,如。
-
+Note that `Del` can only delete variables defined in the user-defined module. Built-in constants such as `True` cannot be deleted.
```erg
Del True # TypeError: cannot delete built-in constants
Del print! # TypeError: cannot delete built-in variables
```
-## Appendix:赋值等价性
-
-注意,当时,不一定是。例如有。这是由 IEEE 754 规定的正式浮点数的规格。
+## Appendix: Assignment and Equivalence
+Note that `x == a` is not necessarily true when `x = a`. An example is `Float.NaN`. This is the formal specification of floating-point numbers as defined by IEEE 754.
```erg
x = Float.NaN
-assert x != Float.NaN
-assert x != x
+assert x ! = NaN
+assert x ! = x
```
-其他,也存在原本就没有定义等值关系的对象。
-
+There are other objects for which no equivalence relation is defined in the first place.
```erg
f = x -> x**2 + 2x + 1
@@ -151,8 +146,8 @@ D = Class {i: Int}
C == D # TypeError: cannot compare class objects
```
-严格地说,并不是将右边值直接代入左边的识别符。函数对象和类对象的情况下,对对象进行赋予变量名的信息等的“修饰”。但是结构型的情况不受此限制。
-
+Strictly speaking, `=` does not assign the right-hand side value directly to the left-hand side identifier.
+In the case of function and class objects, "modification" such as giving variable name information to the object is performed. However, this is not the case for structural types.
```erg
f x = x
diff --git a/doc/zh_CN/syntax/03_declaration.md b/doc/zh_CN/syntax/03_declaration.md
index 2cdffa57..b609984e 100644
--- a/doc/zh_CN/syntax/03_declaration.md
+++ b/doc/zh_CN/syntax/03_declaration.md
@@ -1,11 +1,12 @@
-# 声明
-
-声明是指定要使用的变量类型的语法。可以在代码中的任何地方声明,但不能只声明变量。必须始终初始化。赋值后声明可以检查类型是否与赋值对象匹配。
+# Declaration
+Declaration is the syntax for specifying the type of variable to be used.
+Declarations can be made anywhere in the code, but declarations alone do not refer to the variables. They must be initialized.
+After the assignment, the declaration can be checked to ensure that the type is compatible with the object to which it is assigned.
```erg
i: Int
-# i: Int = 2可以与赋值同时声明
+# Can be declared at the same time as the assignment, like i: Int = 2
i = 2
i: Num
i: Nat
@@ -13,26 +14,24 @@ i: -2..2
i: {2}
```
-赋值后声明类似于类型检查,但在编译时进行检查。运行时使用进行类型检查可以用“可能是 XX”进行检查,但编译时使用进行类型检查是严格的。如果没有确定是“某某型”,就无法通过检查,就会出现错误。
-
+Declaration after assignment is similar to type checking by `assert`, but has the feature that it is checked at compile time.
+Type checking by `assert` at runtime can be checked for "may be type Foo", but type checking by `:` at compile time is strict: if the type is not determined to be "type Foo", it will not pass the check and an error will occur.
```erg
-i = (-1..10).sample!()
-assert i in Nat # 这可能会通过
-i: Int # 这通过了
-i: Nat # 这不起作用(因为 -1 不是 Nat 的元素)
+i = (-1..10).sample!
+assert i in Nat # this may pass
+i: Int # this will pass
+i: Nat # this will not pass (-1 is not an element of Nat)
```
-可以通过两种方式声明函数。
-
+Functions can be declared in 2 different ways.
```erg
f: (x: Int, y: Int) -> Int
f: (Int, Int) -> Int
```
-如果显式声明参数名称,则在定义时如果名称不同,将导致类型错误。如果你想给出参数名称的任意性,可以使用第二种方法声明它。在这种情况下,类型检查只显示方法名称及其类型。
-
+If you declare the argument names explicitly, a type error will result if the names are different at definition time. If you want to give the argument names arbitrary names, you can declare them in the second way. In that case, only the method name and its type will be seen by type checking.
```erg
T = Trait {
diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md
index a500538c..be531d30 100644
--- a/doc/zh_CN/syntax/04_function.md
+++ b/doc/zh_CN/syntax/04_function.md
@@ -1,7 +1,6 @@
-# 函数
-
-函数是一个块,它接受参数并对其进行处理,然后将其作为返回值返回。定义如下。
+# Function
+A function is a block that takes an "argument", processes it, and returns it as a "return value". It is defined as follows.
```erg
add x, y = x + y
@@ -9,8 +8,10 @@ add x, y = x + y
add(x, y) = x + y
```
-在定义函数时指定的参数通常称为伪参数(parameter)。相反,函数调用过程中传递的参数称为实际参数(argument)。是接受和作为假参数,然后返回的函数。你可以按如下方式调用(应用)定义的函数。
-
+The names specified after a function name are called parameters.
+In contrast, the objects passed to a function are called arguments.
+The function `add` is a function that takes `x` and `y` as parameters and returns the sum of them, `x + y`.
+The defined function can be called (applied/invoked) as follows.
```erg
add 1, 2
@@ -18,30 +19,26 @@ add 1, 2
add(1, 2)
```
-## 冒号样式
-
-函数的调用方式如下:,但如果实际参数太多,一行太长,则可以使用(冒号)来应用。
+## Colon application style
+Functions are invoked like `f x, y, ...`, but if there are too many arguments for a single line, they can be applied using `:` (colon).
```erg
f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4
```
-
```erg
f some_long_name_variable_1 + some_long_name_variable_2:
some_long_name_variable_3 * some_long_name_variable_4
```
-
```erg
f:
some_long_name_variable_1 + some_long_name_variable_2
some_long_name_variable_3 * some_long_name_variable_4
```
-上面三个代码都是同一个意思。此样式在使用函数时也很有用。
-
+All three codes above mean the same thing. This style is also useful when using `if` functions, for example.
```erg
result = if Bool.sample!():
@@ -53,26 +50,24 @@ result = if Bool.sample!():
0
```
-在之后,不能写注释以外的代码,必须换行。
+After `:`, no code other than comments may be written, and must always be on a new line.
-## 关键字参数(Keyword Arguments)
-
-如果定义了具有大量参数的函数,则可能会导致传递参数的顺序错误。在这种情况下,使用关键字参数进行调用是安全的。
+## Keyword Arguments
+If a function is defined with a large number of parameters, there is a danger of passing the arguments in the wrong order.
+In such cases, it is safe to call the function using keyword arguments.
```erg
f x, y, z, w, v, u: Int = ...
```
-上面定义的函数有很多参数,并且排列很难懂。我们不应该做这样的函数,但在使用别人写的代码时可能会碰到这样的代码。因此,我们使用关键字参数。关键字参数的名称优先于顺序,因此即使顺序不正确,也会将值从名称传递到正确的参数。
-
+The functions defined above have many arguments and are arranged in a confusing order. You should not create such a function, but you may encounter such code when using code written by others. Therefore, we use keyword arguments. If you use keyword arguments, the values are passed from the name to the correct argument, even if they are in the wrong order.
```erg
f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3
```
-请注意,如果在关键字参数和之后立即换行,将被视为冒号应用样式。
-
+Note that keyword arguments and a new line immediately after the `:` are considered a colon-call style.
```erg
# means `f(x: y)`
@@ -83,12 +78,11 @@ f x:
y
```
-## 默认参数(Default parameters)
+## Default parameters
-如果一个参数在大多数情况下是固定的,并且你想要省略它,则可以使用默认参数。
-
-缺省参数由(or-assign operator)指定。如果未指定,则将赋给。
+Default parameters are used when some parameters are mostly fixed and you want to be able to omit them.
+Default parameters are specified by `:=`(walrus operator). If `base` is not specified, assign `math.E` to `base`.
```erg
math_log x: Ratio, base := math.E = ...
@@ -97,52 +91,46 @@ assert math_log(100, 10) == 2
assert math_log(100) == math_log(100, math.E)
```
-请注意,不指定参数和赋值是有区别的。
-
+Note that there is a distinction between specifying no argument and assigning `None`.
```erg
-p! x := 0 = print! x
+p! x := 0 = print!
p!(2) # 2
p!() # 0
p!(None) # None
```
-也可以与类型和模式一起使用。
-
+Can also be used with type specification and patterns.
```erg
math_log x, base: Ratio := math.E = ...
f [x, y] := [1, 2] = ...
```
-但是,在缺省参数中,不能调用以下过程或赋值可变对象。
-
+However, within the default arguments, it is not possible to call the procedures (described later) or assign mutable objects.
```erg
f x := p! 1 = ... # NG
```
-此外,不能将刚定义的参数用作传递给缺省参数的值。
-
+Also, the argument just defined cannot be used as the value passed to the default argument.
```erg
f x := 1, y := x = ... # NG
```
-## 可变长度参数
-
-函数将参数作为日志输出,可以接收任意数量的参数。
+## Variable-length arguments
+The `log` function, which outputs a log (record) of its arguments, can take any number of arguments.
```erg
log "Hello", "World", "!" # Hello World !
```
-如果要定义这样的函数,请将作为参数。这样,参数就可以作为可变长度数组接收。
-
+To define such a function, add `...` to a parameter. This way, the function receives arguments as a variable-length array.
```erg
-f x: ...Int =
+f ...x =
for x, i ->
log i
@@ -150,8 +138,7 @@ f x: ...Int =
f 1, 2, 3, 4, 5
```
-## 多模式函数定义
-
+## Function definition with multiple patterns
```erg
fib n: Nat =
@@ -161,8 +148,7 @@ fib n: Nat =
n -> fib(n - 1) + fib(n - 2)
```
-如果函数的定义正下方出现,如上面所示,则可以重写如下所示。
-
+Functions like the one above, where `match` appears directly under the definition, can be rewritten as follows.
```erg
fib 0 = 0
@@ -170,20 +156,18 @@ fib 1 = 1
fib(n: Nat): Nat = fib(n - 1) + fib(n - 2)
```
-请注意,多模式函数定义不是所谓的过载(多重定义)。一个函数始终只有一个类型。在上面的示例中,必须与和具有相同的类型。此外,与相同,模式匹配从上到下依次进行。
-
-如果存在不同类的混合实例,则必须在最后一个定义中指明函数参数类型为 Or。
+Note that a function definition with multiple patterns is not so-called overloading (multiple definition); a function has only a single definition. In the example above, `n` must be of the same type as `0` or `1`. Also, as with `match`, pattern matching is done from top to bottom.
+If instances of different classes are mixed, the last definition must specify that the function argument is of type `Or`.
```erg
f "aa" = ...
f 1 = ...
-# `f x = ...` is invalid
+# `f x = ... ` is invalid
f x: Int or Str = ...
```
-它还必须具有包容性,如。
-
+Also, like `match`, it must also be exhaustive.
```erg
fib 0 = 0
@@ -191,8 +175,7 @@ fib 1 = 1
# PatternError: pattern of fib's parameter is not exhaustive
```
-但是,即使在上述情况下,也可以使用下面的显式指定类型来获得全面性。
-
+However, it can be made exhaustive by explicitly specifying the type using the [refinement type](./type/12_refinement.md) described later.
```erg
fib: 0..1 -> 0..1
@@ -201,12 +184,12 @@ fib 1 = 1
# OK
```
-## 递归函数
+## Recursive functions
-递归函数是定义中包含自身的函数。
-
-作为一个简单的例子,我们尝试定义函数来计算阶乘。阶乘是“乘以所有小于或等于的正数”的计算。5 的阶乘为。
+A recursive function is a function that includes itself in its definition.
+As a simple example, let us define a function `factorial` that performs a factorial calculation. Factorial is a computation that "multiplies all positive numbers less than or equal to".
+The factorial of 5 is `5*4*3*2*1 == 120`.
```erg
factorial 0 = 1
@@ -214,10 +197,13 @@ factorial 1 = 1
factorial(n: Nat): Nat = n * factorial(n - 1)
```
-首先从阶乘定义开始,0 和 1 的阶乘都是 1. 按顺序计算,2 的阶乘为,3 的阶乘为,4 的阶乘为。如果你仔细观察这里,你会发现一个数字 n 的阶乘是它前面的数字 n-1 的阶乘乘以 n。如果你将其放入代码中,则会得到。是递归函数,因为的定义包含它自己。
-
-注意,如果未指定类型,则会这样推断。
+First, from the definition of factorial, the factorial of 0 and 1 are both 1.
+In turn, the factorial of 2 is `2*1 == 2`, the factorial of 3 is `3*2*1 == 6`, and the factorial of 4 is `4*3*2*1 == 24`.
+If we look closely, we can see that the factorial of a number n is the factorial of the preceding number n-1 multiplied by n.
+Putting this into code, we get `n * factorial(n - 1)`.
+Since the definition of `factorial` contains itself, `factorial` is a recursive function.
+As a reminder, if you do not add a type specification, it is inferred like this.
```erg
factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int
@@ -226,19 +212,20 @@ factorial 1 = 1
factorial n = n * factorial(n - 1)
```
-但是,即使可以推理,也应该明确指定递归函数的类型。在上面的示例中,像这样的代码是有效的,
-
+However, even if you can reason about it, you should explicitly specify the type of the recursive function. In the example above, a code like ``factorial(-1)`` would work, but
```erg
factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ...
```
-,此计算不会停止。如果不仔细定义值的范围,递归函数可能会陷入无限循环。类型还有助于防止接受不想要的值。
+and this computation does not stop. Recursive functions must carefully define the range of values or you may end up in an infinite loop.
+So the type specification also helps to avoid accepting unexpected values.
-## 编译时函数
-
-如果函数名以大写字母开头,则该函数为编译时函数。所有用户定义的编译时函数的参数都必须是常量,并且必须显式。编译函数能做的事情是有限的。在编译时函数中只能使用常量表达式,即某些运算符(四则运算,比较运算,类型构建运算等)和编译时函数。赋值的参数也必须是常量表达式。相反,计算可以在编译时进行。
+## Compile-time functions
+A function name begins with an uppercase letter to indicate a compile-time function. User-defined compile-time functions must have all arguments as constants and must specify their types.
+Compile-time functions are limited in what they can do. Only constant expressions can be used in compile-time functions, i.e., only some operators (such as quadrature, comparison, and type construction operations) and compile-time functions. Arguments to be passed must also be constant expressions.
+In return, the advantage is that the computation can be done at compile time.
```erg
Add(X, Y: Nat): Nat = X + Y
@@ -252,18 +239,16 @@ math = import "math"
Sin X = math.sin X # ConstantError: this function is not computable at compile time
```
-编译时函数通常用于多相类型定义等。
-
+Compile-time functions are also used in polymorphic type definitions.
```erg
Option T: Type = T or NoneType
Option: Type -> Type
```
-## Appendix:比较函数
-
-Erg 没有为函数定义。那是因为函数的结构等价性判定算法一般不存在。
+## Appendix: Function Comparison
+Erg does not define `==` for functions. This is because there is no structural equivalence algorithm for functions in general.
```erg
f = x: Int -> (x + 1)**2
@@ -272,18 +257,17 @@ g = x: Int -> x**2 + 2x + 1
assert f == g # TypeError: cannot compare functions
```
-和总是返回相同的结果,但这是非常困难的。我们得把代数学灌输给编译器。因此,Erg 放弃了整个函数比较,也会导致编译错误。这是与 Python 不同的规格,需要注意。
-
+Although `f` and `g` always return the same result, it is extremely difficult to make that determination. We have to teach algebra to the compiler.
+So Erg gives up on function comparisons entirely, and `(x -> x) == (x -> x)` also results in a compile error. This is a different specification from Python and should be noted.
```python
# Python, weird example
f = lambda x: x
assert f == f
-assert (lambda x: x) != (lambda x: x)
+assert (lambda x: x) ! = (lambda x: x)
```
-## Appendix2:完成()
-
+## Appendix2: ()-completion
```erg
f x: Object = ...
@@ -299,7 +283,7 @@ f(a, b) # TypeError: f() takes 1 positional argument but 2 were given
f((a, b)) # OK
```
-函数类型实际上是的语法糖。
+The function type `T -> U` is actually the syntax sugar of `(T,) -> U`.
Previous | Next
diff --git a/doc/zh_CN/syntax/05_builtin_funcs.md b/doc/zh_CN/syntax/05_builtin_funcs.md
index a843467c..f0b3075a 100644
--- a/doc/zh_CN/syntax/05_builtin_funcs.md
+++ b/doc/zh_CN/syntax/05_builtin_funcs.md
@@ -1,9 +1,8 @@
-# 内置函数
+# Built-in functions
## if
-是一个函数,它可以根据条件改变操作。
-
+`if` is a function that changes processing depending on a condition.
```erg
result: Option Int = if! Bool.sample!(), do:
@@ -12,8 +11,8 @@ result: Option Int = if! Bool.sample!(), do:
print! result # None (or 1)
```
-随机返回集合的值。如果返回值为 true,则执行。还可以指定当条件为假时如何处理。第二个 do 块称为 else 块。
-
+`.sample!()` returns a random set of values. If the return value is true, `print! "True"` is executed.
+You can also specify what to do if the condition is false; the second do block is called the else block.
```erg
result: Nat = if Bool.sample!():
@@ -26,8 +25,7 @@ result: Nat = if Bool.sample!():
print! result # 1 (or 0)
```
-如果只执行一行操作,则可以省略缩进。
-
+If the process is a single line, you can omit indentation.
```erg
result = if Bool.sample!():
@@ -37,8 +35,7 @@ result = if Bool.sample!():
## for
-你可以使用来编写重复的操作。
-
+You can use `for` to write a repeating process.
```erg
match_s(ss: Iterator(Str), pat: Pattern): Option Str =
diff --git a/doc/zh_CN/syntax/06_operator.md b/doc/zh_CN/syntax/06_operator.md
index 20b655e6..abe81367 100644
--- a/doc/zh_CN/syntax/06_operator.md
+++ b/doc/zh_CN/syntax/06_operator.md
@@ -1,13 +1,13 @@
-# 运算符
+# operator
-运算符(操作符)是表示运算的符号。运算符(操作数)位于运算符的右侧(左),在 Erg 中它只是一个对象。
+Operators are symbols that represent operations. Operands are things to the (left) right of an operator.
-运算符是一种函数,因此它本身也可以绑定到一级对象中的变量。绑定必须用包围。对于(和),必须指定(二元运算)/(一元运算)以实现唯一化,因为同时存在一元运算符和二元运算符。
+Operators are a kind of function, and thus are themselves first-class objects that can be bound to variables. When binding, it is necessary to enclose it with ``.
+For `+` (and `-`), there are both unary and binary operators, so `_+_`(binary operation)/`+_`(unary operation ) must be specified.
-
-```erg
+``` erg
add = `+` # SyntaxError: specify `_+_` or `+_`
-add = `_+_`
+add=`_+_`
assert f(1, 2) == 3
assert f("a", "b") == "ab"
@@ -15,10 +15,9 @@ g = `*` # OK, this is binary only
assert g(1, 2) == 2
```
-但是,请注意,某些称为特殊格式的运算符不能被绑定。
+Some fundamental operators, called special forms, cannot be bound.
-
-```erg
+``` erg
def = `=` # SyntaxError: cannot bind `=` operator, this is a special form
# NG: def x, 1
function = `->` # SyntaxError: cannot bind `->` operator, this is a special form
diff --git a/doc/zh_CN/syntax/07_side_effect.md b/doc/zh_CN/syntax/07_side_effect.md
index 85944adf..342cae82 100644
--- a/doc/zh_CN/syntax/07_side_effect.md
+++ b/doc/zh_CN/syntax/07_side_effect.md
@@ -1,36 +1,34 @@
-# 副作用和过程
-
-到目前为止,我一直没有解释中的含义,现在我终于明白了它的含义。这个!直截了当地表示此对象是具有“副作用”的“过程”。过程对函数产生了一种称为“副作用”的效果。
+# Side effects and procedures
+We have been neglecting to explain the meaning of the `!`, but now its meaning will finally be revealed. This `!` indicates that this object is a "procedure" with a "side-effect". A procedure is a function with a side-effect.
```erg
f x = print! x # EffectError: functions cannot be assigned objects with side effects
# hint: change the name to 'f!'
```
-上面的代码是编译错误。因为你在函数中使用过程。在这种情况下,必须将其定义为过程。
-
+The above code will result in a compile error. This is because you are using a procedure in a function. In such a case, you must define it as a procedure.
```erg
p! x = print! x
```
-,,...是代表过程的典型变量名称。以这种方式定义的过程也不能在函数中使用,因此副作用是完全隔离的。
+`p!`, `q!`, ... are typical variable names for procedures.
+Procedures defined in this way also cannot be used within a function, so side-effects are completely isolated.
-## 方法
-
-每个函数和过程都有一个方法。函数方法仅保留的不变引用,过程方法保留的可变引用。是一个特殊参数,在方法上下文中是指调用的对象本身。引用的不能指定给任何其他变量。
+## Methods
+Functions and procedures each can be methods. Functional methods can only take immutable references to `self`, while procedural methods can take mutable references to `self`.
+The `self` is a special parameter, which in the context of a method refers to the calling object itself. The reference `self` cannot be assigned to any other variable.
```erg
-C.
+C!.
method ref self =
x = self # OwnershipError: cannot move out 'self'
x
```
-该方法还可以剥夺的所有权。该方法的定义不包括或。
-
+Procedural methods can also take [ownership](./18_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition.
```erg
n = 1
@@ -38,39 +36,39 @@ s = n.into(Str) # '1'
n # ValueError: n was moved by .into (line 2)
```
-始终只能有一个过程方法具有可变引用。此外,当可变参照被取走时,将无法从原始对象获取参照。从这个意义上说,会对产生副作用。
-
-但是,请注意,可以从可变参照生成(不变/可变)参照。这允许你在过程方法中递归或。
+Only one procedural methods can have a mutable reference at any given time. In addition, while a mutable reference is taken, no more mutable reference can be taken from the original object. In this sense, `ref!` causes a side-effect on `self`.
+Note, however, that it is possible to create (immutable/mutable) references from mutable references. This allows recursion and `print!` of `self` in procedural methods.
```erg
T -> T # OK (move)
-T -> Ref T # OK
+T -> Ref T # OK (move)
T => Ref! T # OK (only once)
Ref T -> T # NG
Ref T -> Ref T # OK
-Ref T => Ref! T # NG
-Ref! T -> T # NG
-Ref! T -> Ref T # OK
-Ref! T => Ref! T # OK
+Ref T => Ref!
+T -> Ref T # NG
+T -> Ref T # OK
+T => Ref!
```
-## Appendix:严格定义副作用
+## Appendix: Strict definition of side-effects
-代码有没有副作用的规则并不是马上就能理解的。在理解之前,建议先将其定义为函数,然后在出现错误时将其定义为过程。但是,对于那些想要掌握语言严格规范的人来说,下面我们会更详细地介绍副作用。
+The rules for whether a code has a side-effect or not are not immediately understandable.
+Until you can understand them, we recommend that you leave it to the compiler to define them as functions for the time being, and if an error occurs, add `!` to treat them as procedures.
+However, for those who want to understand the exact specifications of the language, the following is a more detailed explanation of side-effects.
-首先,请注意,返回值的等价性与 Erg 中的副作用无关。对于任何,都有一个过程(例如,总是返回),也有一个函数是。
-
-前一个示例是,后一个示例是以下函数。
+First, it must be stated that the equivalence of return values is irrelevant with respect to side effects in Erg.
+There are procedures that for any given `x` will result in `p!(x) == p!(x)` (e.g. always return `None`), and there are functions that will result in `f(x) ! = f(x)`.
+An example of the former is `print!`, and an example of the latter is the following function.
```erg
nan _ = Float.NaN
-assert nan(1) != nan(1)
+assert nan(1) ! = nan(1)
```
-也有一些对象无法进行等价判定,例如类或函数。
-
+There are also objects, such as classes, for which equivalence determination itself is not possible.
```erg
T = Structural {i = Int}
@@ -82,14 +80,13 @@ D = Class {i = Int}
assert C == D # TypeError: cannot compare classes
```
-回到正题上来。“副作用”在 Erg 中的确切定义是,
+Back to the point: the precise definition of "side-effect" in Erg is
-* 访问外部可变信息
+* Accessing mutable external information.
-中选择所需的墙类型。外部通常是指外部范围。“外部”不包括 Erg 无法接触的计算机资源或运行前/运行后信息。“访问”不仅包括写入,还包括读取。
-
-以过程为例。看似没有重写任何变量。但是,如果这是一个函数,那么外部变量可以用这样的代码重写。
+"External" generally refers to the outer scope; computer resources that Erg cannot touch and pre-/post-execution information are not included in "external". "Access" includes reading as well as writing.
+As an example, consider the `print!` procedure. At first glance, `print!` does not seem to rewrite any variables. But if it were a function, it could rewrite outer variables, for example, with code like this:
```erg
camera = import "some_camera_module"
@@ -97,17 +94,18 @@ ocr = import "some_ocr_module"
n = 0
_ =
- f x = print x # 仮にprintを関数として使えたとします
+ f x = print x # Suppose we could use print as a function
f(3.141592)
-cam = camera.new() # カメラはPCのディスプレイを向いています
+cam = camera.new() # camera faces PC display
image = cam.shot!()
n = ocr.read_num(image) # n = 3.141592
```
-模块是为相机产品提供 API 的外部库,是 OCR(光学字符识别)的库。直接副作用是由引起的,但显然,这些信息是从泄露的。因此,在性质上不能是函数。
-
-然而,当你在函数中临时检查值时,你可能不希望将附加到相关函数中。在这种情况下,可以使用函数。在执行整个代码后显示值。这不会传播副作用。
+Think of the `camera` module as an external library providing an API for a certain camera product, and `ocr` as a library for OCR (optical character recognition).
+The direct side-effect is caused by `cam.shot!()`, but obviously that information is leaked from `f`. Therefore, `print!` cannot be a function by nature.
+Nevertheless, there may be cases where you want to temporarily check a value in a function and do not want to add `!` in the related function just for that purpose. In such cases, the `log` function can be used.
+`log` prints the value after the entire code has been executed. In this way, side-effects are not propagated.
```erg
log "this will be printed after execution"
@@ -116,7 +114,7 @@ print! "this will be printed immediately"
# this will be printed after execution
```
-换句话说,如果程序没有反馈,即任何外部对象都不能使用该信息,则信息的“泄露”本身可能是允许的。不被“传播”就行了。
+If there is no feedback to the program, or in other words, if no external object can use the internal information, then the "leakage" of the information may be allowed. It is only necessary that the information not be "propagated".
Previous | Next
diff --git a/doc/zh_CN/syntax/08_procedure.md b/doc/zh_CN/syntax/08_procedure.md
index 28a74bcd..44363e46 100644
--- a/doc/zh_CN/syntax/08_procedure.md
+++ b/doc/zh_CN/syntax/08_procedure.md
@@ -1,7 +1,7 @@
-# 过程
-
-处理可变对象时需要过程,但如果变量对象是参数,则不一定是过程。
+# Procedures
+Procedures are necessary when dealing with mutable objects, but having a mutable object as an argument does not necessarily make it a procedure.
+Here is a function takes a mutable object (not procedure).
```erg
peek_str s: Str! = log s
diff --git a/doc/zh_CN/syntax/09_builtin_procs.md b/doc/zh_CN/syntax/09_builtin_procs.md
index 6b731630..5a78d28e 100644
--- a/doc/zh_CN/syntax/09_builtin_procs.md
+++ b/doc/zh_CN/syntax/09_builtin_procs.md
@@ -1,9 +1,10 @@
-# 内置过程
+# Built-in procedure
## id!
-返回对象的唯一标识号。在纯 Erg 语义中,结构相同的对象之间没有差异,但实际上,对象在内存中的位置是不同的。返回表示此位置的数字。
-
+Returns the unique identification number of the object.
+Although in pure Erg semantics no difference can be found between objects with the same structure, in practice objects have different locations in memory.
+`id!` returns a number representing this position.
```erg
```
diff --git a/doc/zh_CN/syntax/10_array.md b/doc/zh_CN/syntax/10_array.md
index 067f9564..a3c8c20c 100644
--- a/doc/zh_CN/syntax/10_array.md
+++ b/doc/zh_CN/syntax/10_array.md
@@ -1,12 +1,12 @@
-# 排列
-
-数组是最基本的。集合是可以在内部包含多个对象的对象。
+# Array
+Arrays are the most basic __collection (aggregate)__.
+A collection is an object that can hold multiple objects inside it.
```erg
a = [1, 2, 3]
-a: [Int; 3] # 型指定: セミコロンの後の数字は要素数
-# 要素数がわからない場合は省略可能
+a: [Int; 3] # Type specification: number after semicolon is the number of elements
+# Can be omitted if the number of elements is not known
a: [Int]
mut_a = [!1, !2, !3]
@@ -14,41 +14,37 @@ mut_a[0].inc!()
assert mut_a == [2, 2, 3]
```
-通常,数组不能包含不同类型的对象。
+As a rule, arrays cannot contain objects of different types.
-
-```erg
+```erg.
[1, "a"] # TypeError: 1st element is Int, but 2nd element is Str
```
-但是,这种显式类型可以避免限制。
-
+However, you can bypass the restriction by explicitly specifying the type like this.
```erg
-[1, "a"]: [Int or Str]
+[1, "a"]: [Int or Str].
```
-## 切片
-
-数组还可以同时检索多个值。我们管这个叫切片。
+## Slice
+An array can also have multiple values taken out at once. This is called slicing.
```erg
l = [1, 2, 3, 4]
-# Pythonのl[1:3]に相当
-assert l[1..<3] == [2, 3]
+# Same as l[1:3] in Python
+assert l[1.. <3] == [2, 3]
assert l[1..2] == [2, 3]
-# l[1]と同じ
+# Same as l[1]
assert l[1..1] == [2]
-# Pythonのl[::2]に相当
+# Same as l[::2] in Python
assert l[..].step(2) == [2, 4]
```
-切片获得的对象是数组的(不可变)引用。
-
+The object obtained by slicing is an (immutable) copy to an array.
```erg
-print! Typeof l[1..2] # Ref [Int; 4]
+print! Typeof l[1..2] # [Int; 4]
```
diff --git a/doc/zh_CN/syntax/11_tuple.md b/doc/zh_CN/syntax/11_tuple.md
index ec52e918..75a942c3 100644
--- a/doc/zh_CN/syntax/11_tuple.md
+++ b/doc/zh_CN/syntax/11_tuple.md
@@ -1,7 +1,7 @@
-# 元
-
-元组类似于数组,但可以包含不同类型的对象。这样的收藏称为非等质收藏。与此相对,等质集合包括数组和集合。
+# Tuple
+Tuples are similar to arrays, but can hold objects of different types.
+Such a collection is called an unequal collection. In contrast, homogeneous collections include arrays, sets, etc.
```erg
t = (1, True, "a")
@@ -9,8 +9,8 @@ t = (1, True, "a")
assert(i == 1 and b == True and s == "a")
```
-元组可以以的形式检索第 n 个元素。请注意,与 Python 不同,它不是。这是因为元组元素的访问更接近于属性,而不是方法(数组中的是方法)(编译时检查元素是否存在,类型可以根据 n 而变化)。
-
+The tuple `t` can retrieve the nth element in the form `t.n`; note that unlike Python, it is not `t[n]`.
+This is because accessing tuple elements is more like an attribute (the existence of the element is checked at compile time, and the type can change depending on `n`) than a method (an array's `[]` is a method).
```erg
assert t.0 == 1
@@ -18,97 +18,89 @@ assert t.1 == True
assert t.2 == "a"
```
-不嵌套时,括号是可选的。
-
+Parentheses `()` are optional when not nested.
```erg
t = 1, True, "a"
i, b, s = t
```
-元组可以包含不同类型的对象,但不能包含数组之类的小版本。
-
+Tuples can hold objects of different types, so they cannot be iterated like arrays.
```erg
t: ({1}, {2}, {3}) = (1, 2, 3)
(1, 2, 3).iter().map(x -> x + 1) # TypeError: type ({1}, {2}, {3}) has no method `.iter()`
-# すべて同じ型の場合配列と同じように`(T; n)`で表せるが、これでもイテレーションは出来ない
+# If all types are the same, they can be represented by `(T; n)` like arrays, but this still does not allow iteration
t: (Int; 3) = (1, 2, 3)
assert (Int; 3) == (Int, Int, Int)
```
-但是,非等质集合(如元组)可以通过上传、Intersection 等转换为等质集合(如数组)。这叫做等质化。
-
+However, nonhomogeneous collections (such as tuples) can be converted to homogeneous collections (such as arrays) by upcasting, intersecting, and so on.
+This is called equalization.
```erg
-(Int, Bool, Str) can be [T; 3] | T :> Int, T :> Bool, T :> Str
+(Int, Bool, Str) can be [T; 3] where T :> Int, T :> Bool, T :> Str
```
-
```erg
t: (Int, Bool, Str) = (1, True, "a") # non-homogenous
a: [Int or Bool or Str; 3] = [1, True, "a"] # homogenous
_a: [Show; 3] = [1, True, "a"] # homogenous
_a.iter().map(x -> log x) # OK
-t.try_into([Show; 3])?.iter().map(x -> log x) # OK
+t.try_into([Show; 3])? .iter().map(x -> log x) # OK
```
-## 单位
-
-具有 0 个元素的元组称为单元。单位是一个值,但也指其类型本身。
+## Unit
+A tuple with zero elements is called a __unit__. A unit is a value, but also refers to its own type.
```erg
unit = ()
(): ()
```
-单元是所有元素 0 元组的超类。
-
+Unit is a superclass of all element 0 tuples.
```erg
() > (Int; 0)
() > (Str; 0)
```
-此对象的用途包括参数、没有返回值的过程等。Erg 子例程必须具有参数和返回值。但是,在某些情况下,例如在过程中,可能会产生副作用,但没有有意义的参数返回值。在这种情况下,单位作为“没有意义的,形式上的值”来使用。
-
+The use of this object is for procedures with no arguments and no return value, etc. Erg subroutines must have arguments and a return value. However, in some cases, such as a procedure, there may be no meaningful arguments or return value, only side effects. In such cases, we use units as "meaningless, formal values.
```erg
-# ↓ 実はこの括弧はユニット
-p!() =
- # `print!`は意味のある値を返さない
+# ↓ Actually, this parenthesis is a unit
+p!() =.
+ # `print!` does not return a meaningful value
print! "Hello, world!"
p!: () => ()
```
-但是,Python 在这种情况下更倾向于使用而不是单位。在 Erg 中,如果一开始就确定不返回有意义的值(如过程),则返回;如果操作失败,可能一无所获(如元素检索),则返回。
+However, Python tends to use `None` instead of units in such cases.
+In Erg, you should use `()` when you are sure from the beginning that the operation will not return a meaningful value, such as in a procedure, and return `None` when there is a possibility that the operation will fail and you will get nothing, such as when retrieving an element.
-## 参数和元组
-
-实际上,Erg 的所有对象都是一个参数,一个返回值。具有 N 个参数的子程序仅接受“一个具有 N 个元素的元组”作为参数。
+## Arguments and Tuple
+Actually, all of Erg's `Callable` objects are one argument and one return value; a subroutine that takes N arguments was just receiving "one tuple with N elements" as an argument.
```erg
-# f x = ...は暗黙にf(x) = ...とみなされる
+# f x = ... is implicitly assumed to be f(x) = ... is considered to be
f x = x
assert f(1) == 1
f(1, 2, 3) # ArgumentError: f takes 1 positional argument but 3 were given
-# 可変個の引数を受け取る
-g x: Int, ...y: Int = y
+# ArgumentError: f takes 1 positional argument but 3 were given
+g x: Int, . . y: Int = y
assert (2, 3) == g 1, 2, 3
```
-这将解释函数的类型。
-
+This also explains the function type.
```erg
assert f in T: {(T,) -> T | T}
-assert g in {(Int, ...(Int; N)) -> (Int; N) | N: Nat}
+assert g in {(Int, ... (Int; N)) -> (Int; N) | N: Nat}
```
-准确地说,函数的输入不是元组,而是具有默认属性的命名元组。这是一个特殊的元组,只能作为函数的参数使用,可以像记录一样命名并具有缺省值。
-
+To be precise, the function's input is not a tuple but a "Named tuple with default attributes". This is a special tuple that can only be used in function arguments, can be named like a record, and can have a default value.
```erg
f(x: Int, y=0) = x + y
diff --git a/doc/zh_CN/syntax/12_dict.md b/doc/zh_CN/syntax/12_dict.md
index 04d4d305..2bbfbfd0 100644
--- a/doc/zh_CN/syntax/12_dict.md
+++ b/doc/zh_CN/syntax/12_dict.md
@@ -1,40 +1,37 @@
# Dict
-Dict 是一个包含键值对的集合。
-
+Dict is a collection of key/value pairs.
```erg
ids = {"Alice": 145, "Bob": 214, "Charlie": 301}
assert ids["Alice"] == 145
```
-如果密钥为 Hash,则该密钥可以不是字符串。
-
+The key does not have to be a string if it is a `Hash` object.
```erg
-# rangeオブジェクトをキーにするのは非推奨(スライスと混同される)
+# deprecated to use a range object as a key (confused with slice)
r = {1..3: "1~3", 4..6: "4~6", 7..9: "7~9"}
assert r[1..3] == "1~3"
l = {[]: "empty", [1]: "1"}
assert l[[]] == "empty"
```
-顺序对迪奇并不重要。也不能有重复的元素。在这一点上,Dict 与相似。Dict 也可以说是一个有价值的 Set。
-
+Order does not matter for Dict. It also cannot have duplicate elements. In this respect, Dict is similar to Set.
+You could say that a Dict is a Set with values.
```erg
{"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214}
```
-从 Dict 文字生成 Dict 时,将检查是否存在重复的键。如果存在重复项,则会导致编译错误。
-
+When generating a dict from a dict literal, it is checked for duplicate keys.
+Any duplicates will result in a compile error.
```erg
{"Alice": 145, "Alice": 1} # KeyError: Duplicate key "Alice"
```
-使用生成空 Dict。请注意,表示空数组。
-
+Empty Dict is created with `{:}`. Note that `{}` denotes an empty set.
```erg
mut_dict = !{:}
@@ -45,25 +42,24 @@ assert mut_dict["Alice"] == 145
## Heterogeneous Dict
-键值的类型可以不是单一的,这样的字典称为。
-
+There need not be a single key/value type. Such a dictionary is called a __heterogenous dict_.
```erg
-d: {Str: Int, Int: Str} = {”a”: 1, 1: “a”}
-assert d[”a”] == 1
-assert d[1] == “a”
+d: {Str: Int, Int: Str} = {"a": 1, 1: "a"}
+assert d["a"] == 1
+assert d[1] == "a"
```
-但是,不能将相同类型的值应用于不同类型的键,也不能将不同类型的值应用于不同类型的键。在这些情况下,请改用 Or 类型(Union)。
-
+However, it is not possible to assign values of the same type to keys of different types, or values of different types to keys of the same type.
+In such cases, use the type Or instead.
```erg
-invalid1 = {1: “a”, “a”: “b”}
-invalid2 = {1: “a”, 2: 2}
+invalid1 = {1: "a", "a": "b"}
+invalid2 = {1: "a", 2: 2}
-# Ergの型推論はOr型を推論しないので、型指定が必要
-valid1: {Int or Str: Str} = {1: “a”, “a”: “b”}
-valid2: {Int: Int or Str} = {1: “a”, 2: 2}
+# Erg type inference does not infer Or type, so type specification is required
+valid1: {Int or Str: Str} = {1: "a", "a": "b"}
+valid2: {Int: Int or Str} = {1: "a", 2: 2}
```
diff --git a/doc/zh_CN/syntax/13_record.md b/doc/zh_CN/syntax/13_record.md
index fbbebec9..8fb4c524 100644
--- a/doc/zh_CN/syntax/13_record.md
+++ b/doc/zh_CN/syntax/13_record.md
@@ -1,7 +1,7 @@
-# 记录
-
-记录是一个集合,它具有通过键访问的 Dict 和在编译时检查访问的元组的性质。如果你使用过 JavaScript,请将其视为对象文字符号(更高级)。
+# Record
+A record is a collection that combines the properties of a Dict accessed by key and a tuple whose access is inspected at compile time.
+If you know JavaScript, think of it as a (more enhanced) kind of object literal notation.
```erg
john = {.name = "John"; .age = 21}
@@ -12,33 +12,34 @@ assert john in {.name = Str; .age = Nat}
john["name"] # Error: john is not subscribable
```
-和部分称为属性,和部分称为属性值。
-
-它与 JavaScript 对象文字的区别在于不能以字符串形式访问。也就是说,属性不仅仅是字符串。这可能是因为它在编译时决定对值的访问,也可能是因为字典和记录是不同的。也就是说,是 Dict,是记录。那么,词典和记录该如何区分使用呢?通常建议使用记录。记录具有以下优点:编译时检查元素是否存在,并且可以指定。可见性规范相当于 public/private 规范,例如在 Java 语言中。有关详细信息,请参见。
+The `.name` and `.age` parts are called attributes, and the `"John"` and `21` parts are called attribute values.
+The difference from JavaScript object literals is that they are not accessible as strings. That is, attributes are not just strings.
+This is because access to the value is determined at compile-time, and because dictionaries and records are different things. In other words, `{"name": "John"}` is a Dict and `{name = "John"}` is a record.
+So how should we use dictionaries and records?
+In general, we recommend using records. Records have the advantages of being checked at compile-time for the existence of elements and of being able to specify __visibility_.
+Specifying visibility is equivalent to specifying public/private in Java and other languages. For details, see [visibility](./15_visibility.md) for details.
```erg
a = {x = 1; .y = x + 1}
a.x # AttributeError: x is private
-# Hint: declare as `.x`
+# Hint: declare as `.x`.
assert a.y == 2
```
-对于熟悉 JavaScript 的人来说,上面的例子可能很奇怪,但如果简单地声明,则外部无法访问,如果加上,则可以通过访问。
-
-还可以显式指定属性的类型。
+The above example may seem strange to someone familiar with JavaScript, but simply declaring `x` makes it inaccessible from the outside. `. `. `.
+You can also explicitly specify the type of an attribute.
```erg
anonymous = {
- .name: Option! Str = !None
+ .name: Option! Str = !
.age = 20
}
anonymous.name.set! "John"
```
-记录也可以有方法。
-
+A record can also have the method.
```erg
o = {
@@ -51,28 +52,27 @@ o.inc!()
assert o.i == 1
```
-关于记录有一个值得注意的语法。当记录的所有属性值都是类(结构类型不允许)时,记录本身将其属性视为请求属性。这种类型称为记录类型。有关详细信息,请参阅记录部分。
-
+There is a notable syntax with respect to records. When all the attribute values of a record are classes (not structural types), the record itself behaves as a type with its own attributes as required attributes.
+Such a type is called a record type. See the section [Record] for more details.
```erg
-# レコード
+# record
john = {.name = "John"}
-# レコード型
+# record type
john: {.name = Str}
Named = {.name = Str}
john: Named
greet! n: Named =
print! "Hello, I am {n.name}"
-greet! john # "Hello, I am John"
+john # "Hello, I am John" print!
-print! Named.name # Str
+Named.name # Str
```
-## 分解记录
-
-可以按如下方式分解记录。
+## Deconstructing a record
+Records can be deconstructed as follows.
```erg
record = {x = 1; y = 2}
@@ -88,8 +88,8 @@ match point:
{x = x; y = y; z = z} -> "({x}, {y}, {z})"
```
-此外,如果记录具有与属性同名的变量,则可以将或省略为,将或省略为。但是,如果只有一个属性,则必须使用将其与集合区分开来。
-
+`x = ...` can also be abbreviated to `x` when there is a variable with the same name as the attribute, for example, `x = x` or `x = .x` to `x`, and `.x = .x` or `.x = x` to `.x`.
+However, when there is only one attribute, it must be followed by `;` to distinguish it from a set.
```erg
x = 1
@@ -106,8 +106,7 @@ tuple = {x}
assert tuple.1 == 1
```
-此语法可用于分解记录并将其赋给变量。
-
+This syntax can be used to deconstructed a record and assign it to a variable.
```erg
# same as `{x = x; y = y} = xy`
@@ -120,10 +119,9 @@ assert a == 1
assert b == 2
```
-## 空记录
-
-空记录由表示。与 Unit 一样,空记录也是其类本身。
+## Empty Record
+An empty record is represented by `{=}`. An empty record is also its own class, like Unit.
```erg
empty_record = {=}
@@ -134,23 +132,26 @@ empty_record: Structural {=}
{x = 3; y = 5}: Structural {=}
```
-空记录不同于空 Dict或空集。尤其要注意它与的含义正好相反(在 Python 中,是一个空字典,而在 Erg 中,它是)。作为枚举类型,是空类型,不包含任何元素。类型是对其进行的类化。相反,记录类中的没有请求实例属性,因此所有对象都是它的元素。是此别名。(修补程序)具有非常基本的提供方法,如。
-
+An empty record is different from an empty Dict `{:}` or empty set `{}`. In particular, note that it is the opposite of `{}` in meaning (in Python, `{}` is an empty dictionary, while in Erg it is `!{:}` in Erg).
+As an enumerated type, `{}` is an empty type that contains nothing in its elements. The `Never` type is a classification of this type.
+Conversely, the record class `{=}` has no required instance attribute, so all objects are elements of it. An `Object` is an alias of this.
+An `Object` (a patch of `Object`) is an element of `. __sizeof__` and other very basic provided methods.
```erg
AnyPatch = Patch Structural {=}
- .__sizeof__ self = ...
+ . __sizeof__ self = ...
.clone self = ...
...
Never = Class {}
```
-请注意,没有其他类型和类在结构上与,类型等效,如果用户定义类型时在右边指定,,则会出错。这可以防止将转换为的错误。此外,如果定义组合结果为的类型(例如),则会发出警告,将其简单地定义为。
+Note that no other type or class can be structurally equivalent to the `{}`, `Never` type, and it is an error if the user defines a type with `{}`, `Class {}` on the right side.
+This means that, for example, `1..10 or -10. -1`, but `1..10 and -10... -1`. `-1` when it should be `1..10 or -10...-1`, for example.
+Also, if you define a type (such as `Int and Str`) that results in a composition `Object`, you will be warned to simply set it to `Object`.
-## 即时块
-
-Erg 还有一个语法叫即时块,它只是返回最后评估的值。不能保留属性。
+## Instant Block
+Erg has another syntax, instant block, which simply returns the last value evaluated. Attributes cannot be retained.
```erg
x =
@@ -163,10 +164,10 @@ y =
.x = 1 # SyntaxError: cannot define an attribute in an entity block
```
-## 数据类
-
-如果尝试单独实现方法,则必须直接在实例中定义原始记录(由记录文本生成的记录)。这效率很低,而且随着属性数量的增加,错误显示等很难看到,也很难使用。
+## Data Class
+A bare record (a record generated by a record literal) must be defined directly in the instance if you try to implement a method on its own.
+This is inefficient, and as the number of attributes increases, error messages and the like become difficult to see and use.
```erg
john = {
@@ -176,11 +177,11 @@ john = {
.inc_age! ref! self = self::age.update! x -> x + 1
}
john + 1
-# TypeError: + is not implemented for {name = Str; age = Int; .greet! = Ref(Self).() => None; inc_age! = Ref!(Self).() => None}, Int
+# TypeError: + is not implemented for {name = Str; age = Int; .greet! = Ref(Self). () => None; inc_age! = Ref! () => None}, Int
```
-因此,在这种情况下,我们将继承记录类。此类类称为数据类。我们将在部分详细讨论这一点。
-
+So, in such a case, you can inherit a record class. Such a class is called a data class.
+This is described in [class](./type/04_class.md).
```erg
Person = Inherit {name = Str; age = Nat}
@@ -194,5 +195,5 @@ john + 1
```
- Previous | Next
+ Previous | Next
diff --git a/doc/zh_CN/syntax/14_set.md b/doc/zh_CN/syntax/14_set.md
index 648b9d0a..324b4969 100644
--- a/doc/zh_CN/syntax/14_set.md
+++ b/doc/zh_CN/syntax/14_set.md
@@ -1,18 +1,16 @@
-# 集
+# Set
-集代表一个集合,在数据结构上是重复的、没有顺序的数组。
+A set represents a collection, which is structurally a duplicate, unordered array.
-
-```erg
+``` erg
assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3}
-assert {1, 2} == {1, 1, 2} # 重複は自動で削除される
+assert {1, 2} == {1, 1, 2} # duplicates are automatically removed
assert {1, 2} == {2, 1}
```
-集合可以进行集合运算。
+Sets can perform set operations.
-
-```erg
+``` erg
assert 1 in {1, 2, 3}
assert not 1 in {}
assert {1} or {2} == {1, 2}
@@ -20,31 +18,29 @@ assert {1, 2} and {2, 3} == {2}
assert {1, 2} not {2} == {1}
```
-布景是一个等质的收藏。要使不同类中的对象共存,必须使它们相等。
+A set is a homogeneous collection. In order for objects of different classes to coexist, they must be homogenized.
-
-```erg
+``` erg
s: {Int or Str} = {"a", 1, "b", -1}
```
-## 设置为类型
+## Sets as types
-套也可以当作一种类型。这些类型称为。
+Sets can also be treated as types. Such types are called __Enum types__.
-
-```erg
+``` erg
i: {1, 2, 3} = 1
assert i in {1, 2, 3}
```
-集的元素将变为类型元素。需要注意的是,布景本身是不一样的。
+Elements of the set are directly elements of the type.
+Note that the sets themselves are different.
-
-```erg
+``` erg
mut_set = {1, 2, 3}.into {Int; !3}
mut_set.insert!(4)
```
Previous | Next
-
+