"
-````console
+```console
>>> dis.dis("[1,2,3].map(lambda x: x+1)")
1 0 LOAD_CONST 0 (1)
2 LOAD_CONST 1 (2)
@@ -47,33 +47,30 @@ Currently (Python 3.9), CPython MAKE_FUNCTION every time a lambda function is ca
14 MAKE_FUNCTION 0
16 CALL_FUNCTION 1
18 RETURN_VALUE
-````
+```
## STORE_FAST(namei)
-```python
fastlocals[namei] = stack.pop()
-```
-
-Probably corresponds to STORE_NAME at the top level.
-This is supposed to store an unreferenced (or single) variable.
-Is it for optimization that the global space has its own instruction?
+Possibly corresponds to STORE_NAME at top level
+The unreferenced (or single) variable is assumed to be stored by this
+Is it for optimization that the global space has its own instructions?
## LOAD_FAST(namei)
stack.push(fastlocals[namei])
-fastlocals is varnames?
+fastlocals are varnames?
## LOAD_CLOSURE(namei)
```python
cell = freevars[namei]
-stack.push(cell)
+stack. push(cell)
```
-After that BUILD_TUPLE is called.
-It is only called in a closure, and cellvars is supposed to store references in the closure.
-Unlike LOAD_DEREF, the entire cell (container with references) is pushed onto the stack
+Then BUILD_TUPLE is called
+It is only called inside the closure, and cellvars are supposed to store references inside the closure.
+Unlike LOAD_DEREF, each cell (container filled with references) is pushed to the stack
## STORE_DEREF(namei)
@@ -82,8 +79,8 @@ cell = freevars[namei]
cell.set(stack.pop())
```
-Variables without references in the inner scope are STORE_FAST, but referenced variables are STORE_DEREF.
-In Python, the reference count is increased or decreased within this instruction
+Variables without references in inner scopes are STORE_FAST, but referenced variables are STORE_DEREF
+In Python, the reference count is incremented and decremented within this instruction
## LOAD_DEREF(namei)
@@ -92,26 +89,26 @@ cell = freevars[namei]
stack.push(cell.get())
```
-## Name List
+## name list
### varnames
-List of names of internal variables of the function corresponding to `fast_locals`.
-Even if there is a variable with the same name in names, it is not basically the same (it is newly created, and the outside variable cannot be accessed from its scope).
-In other words, variables defined in scope without external references go into varnames
+Name list of function internal variables corresponding to fast_locals
+Even if there are variables with the same name in names, they are basically not the same (newly created and outside variables cannot be accessed from that scope)
+i.e. variables without external references defined in scope go into varnames
### names
-Corresponding to `globals`.
-A list of names of external constants (reference only) used in a scope (even ordinary variables at the top level go into names).
-In other words, constants defined outside the scope go into names
+Compatible with globals
+Name list of external constants (only referenced) used within the scope (at the top level, even ordinary variables are included in names)
+i.e. constants defined outside the scope go into names
-## free variable
+## free variables
-Corresponds to `freevars`.
-Variables captured by closure. It behaves static within the same function instance.
+Compatible with freevars
+Variables captured by the closure. It behaves statically within the same function instance.
## cell variables
-Corresponds to `cellvars`.
-Variables captured by an inner closure function within a function. A copy is made, so the original variable remains intact.
+Corresponds to cellvars
+Variables captured within a function to an inner closure function. Since a copy is made, the original variable remains as it is.
\ No newline at end of file
diff --git a/doc/EN/python/class_system.md b/doc/EN/python/class_system.md
index 89b6d2e9..fa6c7f10 100644
--- a/doc/EN/python/class_system.md
+++ b/doc/EN/python/class_system.md
@@ -51,7 +51,7 @@ TypeError: can only concatenate str (not "int") to str
Erg statically checks for consistency with the parent class.
The `Override` decorator must be given when overriding, and the type of the overriding function must be a subtype of the type of the function being overridden.
-```erg
+```python
>>> C = Class()
... .f self = 1
... .g self = self.f() + 1
@@ -81,7 +81,7 @@ f(c)
f(1) # TypeError
```
-```erg
+```python
# f: |T, X <: {.m = Self.() -> T}| X -> T
f(x) = x.m()
diff --git a/doc/EN/syntax/00_basic.md b/doc/EN/syntax/00_basic.md
index 4d643c3b..09b98fb7 100644
--- a/doc/EN/syntax/00_basic.md
+++ b/doc/EN/syntax/00_basic.md
@@ -2,8 +2,6 @@
> __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/)
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.
@@ -11,7 +9,7 @@ This document describes the basic syntax of Erg. The [Standard API](./API/index.
First, let's do "Hello World".
-```erg
+```python
print!("Hello, World!")
```
@@ -19,7 +17,7 @@ This is almost identical to Python and other languages in the same family. The m
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
+```python
print! "Hello, World!" # OK
print! "Hello,", "World!" # OK
print!() # OK
@@ -70,7 +68,7 @@ hello, world!
The code after `#` is ignored as a comment. Use this to explain the intent of the code or to temporarily disable the code.
-```erg
+```python
# Comment
# `#` and after are ignored until a new line is inserted
#[
@@ -85,7 +83,7 @@ A script is a series of expressions. An expression is something that can be calc
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
+```python
n = 1 # assignment expression
f(1, 2) # function-call expression
1 + 1 # operator-call expression
@@ -95,7 +93,7 @@ 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
+```python
i =
x = 1
x + 1
@@ -104,7 +102,7 @@ assert i == 2
This cannot be accomplished with a semicolon (`;`).
-```erg
+```python
i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses
```
@@ -112,7 +110,7 @@ i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses
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
+```python
f x, y =
x + y
@@ -131,7 +129,7 @@ ans = match x:
If a line is too long, it can be broken using `\`.
-```erg
+```python
# this does not means `x + y + z` but means `x; +y; +z`
x
+ y
diff --git a/doc/EN/syntax/01_literal.md b/doc/EN/syntax/01_literal.md
index f8336328..3411024d 100644
--- a/doc/EN/syntax/01_literal.md
+++ b/doc/EN/syntax/01_literal.md
@@ -4,19 +4,19 @@
### Int Literal
-```erg
+```python
0, -0, 1, -1, 2, -2, 3, -3, ...
```
### Ratio Literal
-```erg
+```python
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
+```python
assert 1.0 == 1.
assert 0.5 == .5
```
@@ -29,14 +29,14 @@ Subsequent documents may use `assert` to indicate that the results are equal.
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
+```python
"", "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
+```python
assert "1 + 1 is 2" == "{1} + {1} is {1+1}"
s = "1+1"
assert "\{1+1}\" == "\{{s}\}"
@@ -47,11 +47,11 @@ assert "\{1+1}\" == "\{{s}\}"
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
+```python
1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ...
```
-```erg
+```python
assert 1e-10 == 0.0000000001
```
@@ -61,37 +61,37 @@ Each of these literals has its own documentation describing them separately, so
### [Array Literal](./10_array.md)
-```erg
+```python
[], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ...
```
### [Dict Literal](./11_dict.md)
-```erg
+```python
{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
```
### [Tuple Literal](./12_tuple.md)
-```erg
+```python
(), (1, 2, 3), (1, "hello", True), ...
```
### [Record Literal](./13_record.md)
-```erg
+```python
{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
```
### [Set Literal](./14_set.md)
-```erg
+```python
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ...
```
As a difference from `Array` literals, duplicate elements are removed in `Set`.
-```erg
+```python
assert {1, 2, 1} == {1, 2}
```
@@ -99,19 +99,19 @@ assert {1, 2, 1} == {1, 2}
## Boolean Object
-```erg
+```python
True, False
```
### None Object
-```erg
+```python
None
```
## Range Object
-```erg
+```python
assert 0..5 == {1, 2, 3, 4, 5}
assert 0..10 in 5
assert 0..<10 notin 10
@@ -120,7 +120,7 @@ assert 0..9 == 0..<10
## Float Object
-```erg
+```python
assert 0.0f64 == 0
assert 0.0f32 == 0.0f64
```
@@ -129,7 +129,7 @@ Float objects are constructed by multiplying a `Ratio` object by `f64`, which is
## Complex Object
-```erg
+```python
1+2im, 0.4-1.2im, 0im, im
```
@@ -139,7 +139,7 @@ A `Complex` object is simply an arithmetic combination of an imaginary unit obje
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
+```python
# same as `assert (1*m) / (1*s) == 1*(m/s)`
assert 1m / 1s == 1 (m/s)
```
diff --git a/doc/EN/syntax/02_name.md b/doc/EN/syntax/02_name.md
index 8b87e4a2..63138c32 100644
--- a/doc/EN/syntax/02_name.md
+++ b/doc/EN/syntax/02_name.md
@@ -5,7 +5,7 @@ Variables are a type of algebra; algebra in Erg - sometimes simply referred to a
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
+```python
n = 1
```
@@ -15,13 +15,13 @@ We have just said that `1` is an object. We will discuss what an object is later
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
+```python
n: Nat = 1
```
Note that, unlike other languages, multiple assignments are not allowed.
-```erg
+```python
# NG
l1 = l2 = [1, 2, 3] # SyntaxError: multiple assignment not allowed
# OK
@@ -31,7 +31,7 @@ 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
+```python
i = 1
i = i + 1 # AssignError: cannot assign twice
```
@@ -40,7 +40,7 @@ You can define a variable with the same name in the inner scope, but you are onl
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
+```python
x = 0
# x = 1 # AssignError: cannot assign twice
if x.is_zero(), do:
@@ -51,7 +51,7 @@ 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
+```python
x = 0
if x.is_zero(), do:
x = x + 1 # NameError: cannot define variables refer to variables with the same name
@@ -64,7 +64,7 @@ assert x == 0
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
+```python
N = 0
if True, do:
N = 1 # AssignError: constants cannot be shadowed
@@ -77,13 +77,13 @@ For example, constants are used for mathematical constants, information about ex
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
+```python
PI = 3.141592653589793
URL = "https://example.com"
CHOICES = ["a", "b", "c"]
```
-```erg
+```python
PI = 3.141592653589793
match! x:
PI => print! "π"
@@ -95,7 +95,7 @@ The above code prints `π` when `x` is `3.141592653589793`. If `x` is changed to
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
+```python
X = 1 # OK
X = !1 # TypeError: cannot define Int! object as a constant
```
@@ -104,7 +104,7 @@ X = !1 # TypeError: cannot define Int! object as a constant
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
+```python
x = 1
y = 2
Z = 3
@@ -119,7 +119,7 @@ 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
+```python
Del True # TypeError: cannot delete built-in constants
Del print! # TypeError: cannot delete built-in variables
```
@@ -128,7 +128,7 @@ Del print! # TypeError: cannot delete built-in variables
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
+```python
x = Float.NaN
assert x ! = NaN
assert x ! = x
@@ -136,7 +136,7 @@ assert x ! = x
There are other objects for which no equivalence relation is defined in the first place.
-```erg
+```python
f = x -> x**2 + 2x + 1
g = x -> (x + 1)**2
f == g # TypeError: cannot compare function objects
@@ -149,7 +149,7 @@ 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
+```python
f x = x
print! f #
g x = x + 1
diff --git a/doc/EN/syntax/03_declaration.md b/doc/EN/syntax/03_declaration.md
index b609984e..1548c120 100644
--- a/doc/EN/syntax/03_declaration.md
+++ b/doc/EN/syntax/03_declaration.md
@@ -4,7 +4,7 @@ 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
+```python
i: Int
# Can be declared at the same time as the assignment, like i: Int = 2
i = 2
@@ -17,7 +17,7 @@ i: {2}
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
+```python
i = (-1..10).sample!
assert i in Nat # this may pass
i: Int # this will pass
@@ -26,14 +26,14 @@ i: Nat # this will not pass (-1 is not an element of Nat)
Functions can be declared in 2 different ways.
-```erg
+```python
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
+```python
T = Trait {
.f = (x: Int, y: Int): Int
}
diff --git a/doc/EN/syntax/04_function.md b/doc/EN/syntax/04_function.md
index be531d30..8e93f12b 100644
--- a/doc/EN/syntax/04_function.md
+++ b/doc/EN/syntax/04_function.md
@@ -2,7 +2,7 @@
A function is a block that takes an "argument", processes it, and returns it as a "return value". It is defined as follows.
-```erg
+```python
add x, y = x + y
# or
add(x, y) = x + y
@@ -13,7 +13,7 @@ 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
+```python
add 1, 2
# or
add(1, 2)
@@ -23,16 +23,16 @@ add(1, 2)
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
+```python
f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4
```
-```erg
+```python
f some_long_name_variable_1 + some_long_name_variable_2:
some_long_name_variable_3 * some_long_name_variable_4
```
-```erg
+```python
f:
some_long_name_variable_1 + some_long_name_variable_2
some_long_name_variable_3 * some_long_name_variable_4
@@ -40,7 +40,7 @@ f:
All three codes above mean the same thing. This style is also useful when using `if` functions, for example.
-```erg
+```python
result = if Bool.sample!():
do:
log "True was chosen"
@@ -57,19 +57,19 @@ After `:`, no code other than comments may be written, and must always be on a n
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
+```python
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
+```python
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
+```python
# means `f(x: y)`
f x: y
@@ -84,7 +84,7 @@ Default parameters are used when some parameters are mostly fixed and you want t
Default parameters are specified by `:=`(walrus operator). If `base` is not specified, assign `math.E` to `base`.
-```erg
+```python
math_log x: Ratio, base := math.E = ...
assert math_log(100, 10) == 2
@@ -93,7 +93,7 @@ assert math_log(100) == math_log(100, math.E)
Note that there is a distinction between specifying no argument and assigning `None`.
-```erg
+```python
p! x := 0 = print!
p!(2) # 2
p!() # 0
@@ -102,20 +102,20 @@ p!(None) # None
Can also be used with type specification and patterns.
-```erg
+```python
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
+```python
f x := p! 1 = ... # NG
```
Also, the argument just defined cannot be used as the value passed to the default argument.
-```erg
+```python
f x := 1, y := x = ... # NG
```
@@ -123,13 +123,13 @@ f x := 1, y := x = ... # NG
The `log` function, which outputs a log (record) of its arguments, can take any number of arguments.
-```erg
+```python
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
+```python
f ...x =
for x, i ->
log i
@@ -140,7 +140,7 @@ f 1, 2, 3, 4, 5
## Function definition with multiple patterns
-```erg
+```python
fib n: Nat =
match n:
0 -> 0
@@ -150,7 +150,7 @@ fib n: Nat =
Functions like the one above, where `match` appears directly under the definition, can be rewritten as follows.
-```erg
+```python
fib 0 = 0
fib 1 = 1
fib(n: Nat): Nat = fib(n - 1) + fib(n - 2)
@@ -160,7 +160,7 @@ Note that a function definition with multiple patterns is not so-called overload
If instances of different classes are mixed, the last definition must specify that the function argument is of type `Or`.
-```erg
+```python
f "aa" = ...
f 1 = ...
# `f x = ... ` is invalid
@@ -169,7 +169,7 @@ f x: Int or Str = ...
Also, like `match`, it must also be exhaustive.
-```erg
+```python
fib 0 = 0
fib 1 = 1
# PatternError: pattern of fib's parameter is not exhaustive
@@ -177,7 +177,7 @@ fib 1 = 1
However, it can be made exhaustive by explicitly specifying the type using the [refinement type](./type/12_refinement.md) described later.
-```erg
+```python
fib: 0..1 -> 0..1
fib 0 = 0
fib 1 = 1
@@ -191,7 +191,7 @@ 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
+```python
factorial 0 = 1
factorial 1 = 1
factorial(n: Nat): Nat = n * factorial(n - 1)
@@ -205,7 +205,7 @@ Since the definition of `factorial` contains itself, `factorial` is a recursive
As a reminder, if you do not add a type specification, it is inferred like this.
-```erg
+```python
factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int
factorial 0 = 1
factorial 1 = 1
@@ -214,7 +214,7 @@ 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
+```python
factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ...
```
@@ -227,7 +227,7 @@ A function name begins with an uppercase letter to indicate a compile-time funct
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
+```python
Add(X, Y: Nat): Nat = X + Y
assert Add(1, 2) == 3
@@ -241,7 +241,7 @@ Sin X = math.sin X # ConstantError: this function is not computable at compile t
Compile-time functions are also used in polymorphic type definitions.
-```erg
+```python
Option T: Type = T or NoneType
Option: Type -> Type
```
@@ -250,7 +250,7 @@ Option: Type -> Type
Erg does not define `==` for functions. This is because there is no structural equivalence algorithm for functions in general.
-```erg
+```python
f = x: Int -> (x + 1)**2
g = x: Int -> x**2 + 2x + 1
@@ -269,7 +269,7 @@ assert (lambda x: x) ! = (lambda x: x)
## Appendix2: ()-completion
-```erg
+```python
f x: Object = ...
# will be completed to
f(x: Object) = ...
diff --git a/doc/EN/syntax/05_builtin_funcs.md b/doc/EN/syntax/05_builtin_funcs.md
index f0b3075a..12aa1eeb 100644
--- a/doc/EN/syntax/05_builtin_funcs.md
+++ b/doc/EN/syntax/05_builtin_funcs.md
@@ -4,7 +4,7 @@
`if` is a function that changes processing depending on a condition.
-```erg
+```python
result: Option Int = if! Bool.sample!(), do:
log "True was chosen"
1
@@ -14,7 +14,7 @@ print! result # None (or 1)
`.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
+```python
result: Nat = if Bool.sample!():
do:
log "True was chosen"
@@ -27,7 +27,7 @@ print! result # 1 (or 0)
If the process is a single line, you can omit indentation.
-```erg
+```python
result = if Bool.sample!():
do 1
do 0
@@ -37,7 +37,7 @@ result = if Bool.sample!():
You can use `for` to write a repeating process.
-```erg
+```python
match_s(ss: Iterator(Str), pat: Pattern): Option Str =
for ss, s ->
if pat.match(s).is_some():
diff --git a/doc/EN/syntax/06_operator.md b/doc/EN/syntax/06_operator.md
index abe81367..087f6862 100644
--- a/doc/EN/syntax/06_operator.md
+++ b/doc/EN/syntax/06_operator.md
@@ -5,7 +5,7 @@ Operators are symbols that represent operations. Operands are things to the (lef
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
+```python
add = `+` # SyntaxError: specify `_+_` or `+_`
add=`_+_`
assert f(1, 2) == 3
@@ -17,7 +17,7 @@ assert g(1, 2) == 2
Some fundamental operators, called special forms, cannot be bound.
-``` erg
+```python
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/EN/syntax/07_side_effect.md b/doc/EN/syntax/07_side_effect.md
index 342cae82..1037bb36 100644
--- a/doc/EN/syntax/07_side_effect.md
+++ b/doc/EN/syntax/07_side_effect.md
@@ -2,14 +2,14 @@
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
+```python
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
+```python
p! x = print! x
```
@@ -21,7 +21,7 @@ Procedures defined in this way also cannot be used within a function, so side-ef
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
+```python
C!.
method ref self =
x = self # OwnershipError: cannot move out 'self'
@@ -30,7 +30,7 @@ C!.
Procedural methods can also take [ownership](./18_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition.
-```erg
+```python
n = 1
s = n.into(Str) # '1'
n # ValueError: n was moved by .into (line 2)
@@ -40,7 +40,7 @@ Only one procedural methods can have a mutable reference at any given time. In a
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
+```python
T -> T # OK (move)
T -> Ref T # OK (move)
T => Ref! T # OK (only once)
@@ -63,14 +63,14 @@ There are procedures that for any given `x` will result in `p!(x) == p!(x)` (e.g
An example of the former is `print!`, and an example of the latter is the following function.
-```erg
+```python
nan _ = Float.NaN
assert nan(1) ! = nan(1)
```
There are also objects, such as classes, for which equivalence determination itself is not possible.
-```erg
+```python
T = Structural {i = Int}
U = Structural {i = Int}
assert T == U
@@ -88,7 +88,7 @@ Back to the point: the precise definition of "side-effect" in Erg is
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
+```python
camera = import "some_camera_module"
ocr = import "some_ocr_module"
@@ -107,7 +107,7 @@ The direct side-effect is caused by `cam.shot!()`, but obviously that informatio
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
+```python
log "this will be printed after execution"
print! "this will be printed immediately"
# this will be printed immediately
diff --git a/doc/EN/syntax/08_procedure.md b/doc/EN/syntax/08_procedure.md
index 44363e46..a46e863a 100644
--- a/doc/EN/syntax/08_procedure.md
+++ b/doc/EN/syntax/08_procedure.md
@@ -3,7 +3,7 @@
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
+```python
peek_str s: Str! = log s
```
diff --git a/doc/EN/syntax/09_builtin_procs.md b/doc/EN/syntax/09_builtin_procs.md
index 5a78d28e..eff9af73 100644
--- a/doc/EN/syntax/09_builtin_procs.md
+++ b/doc/EN/syntax/09_builtin_procs.md
@@ -6,7 +6,7 @@ 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
+```python
```
diff --git a/doc/EN/syntax/10_array.md b/doc/EN/syntax/10_array.md
index a3c8c20c..fd42f8a3 100644
--- a/doc/EN/syntax/10_array.md
+++ b/doc/EN/syntax/10_array.md
@@ -3,7 +3,7 @@
Arrays are the most basic __collection (aggregate)__.
A collection is an object that can hold multiple objects inside it.
-```erg
+```python
a = [1, 2, 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
@@ -16,13 +16,13 @@ assert mut_a == [2, 2, 3]
As a rule, arrays cannot contain objects of different types.
-```erg.
+```python.
[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
+```python
[1, "a"]: [Int or Str].
```
@@ -30,7 +30,7 @@ However, you can bypass the restriction by explicitly specifying the type like t
An array can also have multiple values taken out at once. This is called slicing.
-```erg
+```python
l = [1, 2, 3, 4]
# Same as l[1:3] in Python
assert l[1.. <3] == [2, 3]
@@ -43,7 +43,7 @@ assert l[..].step(2) == [2, 4]
The object obtained by slicing is an (immutable) copy to an array.
-```erg
+```python
print! Typeof l[1..2] # [Int; 4]
```
diff --git a/doc/EN/syntax/11_tuple.md b/doc/EN/syntax/11_tuple.md
index 75a942c3..403833b5 100644
--- a/doc/EN/syntax/11_tuple.md
+++ b/doc/EN/syntax/11_tuple.md
@@ -3,7 +3,7 @@
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
+```python
t = (1, True, "a")
(i, b, s) = t
assert(i == 1 and b == True and s == "a")
@@ -12,7 +12,7 @@ assert(i == 1 and b == True and s == "a")
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
+```python
assert t.0 == 1
assert t.1 == True
assert t.2 == "a"
@@ -20,14 +20,14 @@ assert t.2 == "a"
Parentheses `()` are optional when not nested.
-```erg
+```python
t = 1, True, "a"
i, b, s = t
```
Tuples can hold objects of different types, so they cannot be iterated like arrays.
-```erg
+```python
t: ({1}, {2}, {3}) = (1, 2, 3)
(1, 2, 3).iter().map(x -> x + 1) # TypeError: type ({1}, {2}, {3}) has no method `.iter()`
# If all types are the same, they can be represented by `(T; n)` like arrays, but this still does not allow iteration
@@ -38,11 +38,11 @@ assert (Int; 3) == (Int, Int, Int)
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
+```python
(Int, Bool, Str) can be [T; 3] where T :> Int, T :> Bool, T :> Str
```
-```erg
+```python
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
@@ -54,21 +54,21 @@ t.try_into([Show; 3])? .iter().map(x -> log x) # OK
A tuple with zero elements is called a __unit__. A unit is a value, but also refers to its own type.
-```erg
+```python
unit = ()
(): ()
```
Unit is a superclass of all element 0 tuples.
-```erg
+```python
() > (Int; 0)
() > (Str; 0)
```
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
+```python
# ↓ Actually, this parenthesis is a unit
p!() =.
# `print!` does not return a meaningful value
@@ -83,7 +83,7 @@ In Erg, you should use `()` when you are sure from the beginning that the operat
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
+```python
# f x = ... is implicitly assumed to be f(x) = ... is considered to be
f x = x
assert f(1) == 1
@@ -95,14 +95,14 @@ assert (2, 3) == g 1, 2, 3
This also explains the function type.
-```erg
+```python
assert f in T: {(T,) -> T | T}
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
+```python
f(x: Int, y=0) = x + y
f: (Int, y=Int) -> Int
diff --git a/doc/EN/syntax/12_dict.md b/doc/EN/syntax/12_dict.md
index 2bbfbfd0..3c03c35f 100644
--- a/doc/EN/syntax/12_dict.md
+++ b/doc/EN/syntax/12_dict.md
@@ -2,14 +2,14 @@
Dict is a collection of key/value pairs.
-```erg
+```python
ids = {"Alice": 145, "Bob": 214, "Charlie": 301}
assert ids["Alice"] == 145
```
The key does not have to be a string if it is a `Hash` object.
-```erg
+```python
# 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"
@@ -20,20 +20,20 @@ assert l[[]] == "empty"
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
+```python
{"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214}
```
When generating a dict from a dict literal, it is checked for duplicate keys.
Any duplicates will result in a compile error.
-```erg
+```python
{"Alice": 145, "Alice": 1} # KeyError: Duplicate key "Alice"
```
Empty Dict is created with `{:}`. Note that `{}` denotes an empty set.
-```erg
+```python
mut_dict = !{:}
mut_dict.insert! "Alice", 145
mut_dict.insert! "Bob", 214
@@ -44,7 +44,7 @@ assert mut_dict["Alice"] == 145
There need not be a single key/value type. Such a dictionary is called a __heterogenous dict_.
-```erg
+```python
d: {Str: Int, Int: Str} = {"a": 1, 1: "a"}
assert d["a"] == 1
assert d[1] == "a"
@@ -53,7 +53,7 @@ assert d[1] == "a"
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
+```python
invalid1 = {1: "a", "a": "b"}
invalid2 = {1: "a", 2: 2}
diff --git a/doc/EN/syntax/13_record.md b/doc/EN/syntax/13_record.md
index 8fb4c524..c7f8694e 100644
--- a/doc/EN/syntax/13_record.md
+++ b/doc/EN/syntax/13_record.md
@@ -3,7 +3,7 @@
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
+```python
john = {.name = "John"; .age = 21}
assert john.name == "John"
@@ -20,7 +20,7 @@ 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
+```python
a = {x = 1; .y = x + 1}
a.x # AttributeError: x is private
# Hint: declare as `.x`.
@@ -31,7 +31,7 @@ The above example may seem strange to someone familiar with JavaScript, but simp
You can also explicitly specify the type of an attribute.
-```erg
+```python
anonymous = {
.name: Option! Str = !
.age = 20
@@ -41,7 +41,7 @@ anonymous.name.set! "John"
A record can also have the method.
-```erg
+```python
o = {
.i = !0
.inc! ref! self = self.i.inc!()
@@ -55,7 +55,7 @@ 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
+```python
# record
john = {.name = "John"}
# record type
@@ -74,7 +74,7 @@ Named.name # Str
Records can be deconstructed as follows.
-```erg
+```python
record = {x = 1; y = 2}
{x = a; y = b} = record
assert a == 1
@@ -91,7 +91,7 @@ match point:
`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
+```python
x = 1
y = 2
xy = {x; y}
@@ -108,7 +108,7 @@ assert tuple.1 == 1
This syntax can be used to deconstructed a record and assign it to a variable.
-```erg
+```python
# same as `{x = x; y = y} = xy`
{x; y} = xy
assert x == 1
@@ -123,7 +123,7 @@ assert b == 2
An empty record is represented by `{=}`. An empty record is also its own class, like Unit.
-```erg
+```python
empty_record = {=}
empty_record: {=}
# Object: Type = {=}
@@ -137,7 +137,7 @@ As an enumerated type, `{}` is an empty type that contains nothing in its elemen
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
+```python
AnyPatch = Patch Structural {=}
. __sizeof__ self = ...
.clone self = ...
@@ -153,7 +153,7 @@ Also, if you define a type (such as `Int and Str`) that results in a composition
Erg has another syntax, instant block, which simply returns the last value evaluated. Attributes cannot be retained.
-```erg
+```python
x =
x = 1
y = x + 1
@@ -169,7 +169,7 @@ y =
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
+```python
john = {
name = "John Smith"
age = !20
@@ -183,7 +183,7 @@ john + 1
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
+```python
Person = Inherit {name = Str; age = Nat}
Person.
greet! ref self = print! "Hello, my name is {self::name} and I am {self::age} years old."
diff --git a/doc/EN/syntax/14_set.md b/doc/EN/syntax/14_set.md
index b1757c12..3bace4d6 100644
--- a/doc/EN/syntax/14_set.md
+++ b/doc/EN/syntax/14_set.md
@@ -1,16 +1,16 @@
# Set
-A set is an unordered array with no duplicates.
+A set represents a collection, which is structurally a duplicate, unordered array.
-```erg
+```python
assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3}
assert {1, 2} == {1, 1, 2} # duplicates are automatically removed
assert {1, 2} == {2, 1}
```
-Sets can perform mathematical set operations.
+Sets can perform set operations.
-```erg
+```python
assert 1 in {1, 2, 3}
assert not 1 in {}
assert {1} or {2} == {1, 2}
@@ -18,30 +18,29 @@ assert {1, 2} and {2, 3} == {2}
assert {1, 2} not {2} == {1}
```
-A set is a homogenous collection. Objects of different classes must be made equal in order to coexist.
+A set is a homogeneous collection. In order for objects of different classes to coexist, they must be homogenized.
-```erg
-s1 = {"a", 1, "b", -1} # TypeError
-s2: {Int or Str} = {"a", 1, "b", -1}
+```python
+s: {Int or Str} = {"a", 1, "b", -1}
```
-## Set as Type
+## Sets as types
-Sets can also be treated as types. Such a type is called an __Enum type_.
+Sets can also be treated as types. Such types are called __Enum types__.
-```erg
+```python
i: {1, 2, 3} = 1
assert i in {1, 2, 3}
```
-The elements of the set are directly the elements of the type.
-Note that the set itself is different.
+Elements of the set are directly elements of the type.
+Note that the sets themselves are different.
-```erg
+```python
mut_set = {1, 2, 3}.into {Int; !3}
mut_set.insert!(4)
```
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/15_type.md b/doc/EN/syntax/15_type.md
index 97b8bad7..8430dc74 100644
--- a/doc/EN/syntax/15_type.md
+++ b/doc/EN/syntax/15_type.md
@@ -4,4 +4,4 @@ Types are a very important feature in Erg, so we have a [dedicated section](./ty
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/16_iterator.md b/doc/EN/syntax/16_iterator.md
index 302d197b..d53deb4c 100644
--- a/doc/EN/syntax/16_iterator.md
+++ b/doc/EN/syntax/16_iterator.md
@@ -2,7 +2,7 @@
An iterator is an object used to retrieve elements of a container.
-```erg
+```python
for! 0..9, i =>
print! i
```
@@ -12,7 +12,7 @@ Each number (=Int object) is assigned to `i` and the following operation (=`prin
Now let's look at the type signature of the `for!` procedure.
-```erg
+```python
for!: |T: Type, I <: Iterable T| (I, T => None) => None
```
@@ -20,7 +20,7 @@ The first argument seems to accept an object of type `Iterable`.
`Iterable` is a type with `.Iterator` attribute, `.iter` method in the request method.
-```erg
+```python
Iterable T = Trait {
.Iterator = {Iterator}
.iter = Self(T). () -> Self.Iterator T
@@ -29,7 +29,7 @@ Iterable T = Trait {
The type `{Iterator}` of the `.Iterator` attribute is so-called set-kind (kind is described [here](./type/advanced/kind.md)).
-```erg
+```python
assert [1, 2, 3] in Iterable(Int)
assert 1..3 in Iterable(Int)
assert [1, 2, 3].Iterator == ArrayIterator
diff --git a/doc/EN/syntax/17_mutability.md b/doc/EN/syntax/17_mutability.md
index e88b87b1..47484bfa 100644
--- a/doc/EN/syntax/17_mutability.md
+++ b/doc/EN/syntax/17_mutability.md
@@ -3,7 +3,7 @@
As we have already seen, all Erg variables are immutable. However, Erg objects have the concept of mutability.
Take the following code as an example.
-```erg
+```python
a = [1, 2, 3]
a = a + [4, 5, 6]
print! a # [1, 2, 3, 4, 5, 6]
@@ -13,7 +13,7 @@ The above code cannot actually be executed by Erg. This is because it is not rea
This code can be executed.
-```erg
+```python
b = ![1, 2, 3]
b.concat! [4, 5, 6]
print! b # [1, 2, 3, 4, 5, 6]
@@ -22,7 +22,7 @@ print! b # [1, 2, 3, 4, 5, 6]
The final result of `a, b` looks the same, but their meanings are very different.
Although `a` is a variable that represents an array of `Nat`, the objects pointed to in the first and second lines are different. The name `a` is the same, but the contents are different.
-```erg
+```python
a = [1, 2, 3]
print! id! a # 0x000002A798DFE940
_a = a + [4, 5, 6]
@@ -33,14 +33,14 @@ The `id!` procedure returns the address in memory where the object resides.
`b` is a `Nat` "dynamic" array. The content of the object changes, but the variables point to the same thing.
-```erg
+```python
b = ![1, 2, 3]
print! id! b # 0x000002A798DFE220
b.concat! [4, 5, 6]
print! id! b # 0x000002A798DFE220
```
-```erg
+```python
i = !0
if! True. do!
do! i.inc!() # or i.add!(1)
@@ -51,7 +51,7 @@ print! i # 1
`!` is a special operator called the __mutation operator__. It makes immutable objects mutable.
The behavior of objects marked with `!` can be customized.
-```erg
+```python
Point = Class {.x = Int; .y = Int}
# In this case .x is made mutable and .y remains immutable
@@ -69,7 +69,7 @@ print! p.x # 1
Unlike variables, constants point to the same thing in all scopes.
Constants are declared with the `=` operator.
-```erg
+```python
PI = 3.141592653589
match! x:
PI => print! "this is pi"
diff --git a/doc/EN/syntax/18_ownership.md b/doc/EN/syntax/18_ownership.md
index 26b463a0..6c724767 100644
--- a/doc/EN/syntax/18_ownership.md
+++ b/doc/EN/syntax/18_ownership.md
@@ -1,110 +1,110 @@
-# Ownership System
+# Ownership system
-Since Erg is a language that uses Python as its host language, its method of memory management is dependent on the Python implementation.
-Semantically, however, Erg's memory management is different from that of Python. The most noticeable differences appear in the ownership system and the prohibition of circular references.
+Since Erg is a language that uses Python as the host language, the method of memory management depends on the Python implementation.
+But semantically Erg's memory management is different from Python's. A notable difference is in the ownership system and the prohibition of circular references.
## Ownership
-Erg has an ownership system influenced by Rust.
-While Rust's ownership system is generally considered arcane, Erg's has been simplified to make it intuitive.
-In Erg, ownership is attached to __mutable objects__, which cannot be referenced after you lose ownership.
+Erg has an ownership system inspired by Rust.
+Rust's ownership system is generally considered esoteric, but Erg's is simplified to be intuitive.
+In Erg, __mutable objects__ are owned and cannot be referenced after ownership is lost.
-```erg
-v = [1, 2, 3].into [Int; !3].
+```python
+v = [1, 2, 3].into [Int; !3]
-push!vec, x =
+push! vec, x =
vec.push!(x)
- vec.
+ vec
-# ownership of v's contents ([1, 2, 3]) is transferred to w
+# The contents of v ([1, 2, 3]) are owned by w
w = push! v, 4
print! v # error: v was moved
-print! w # [1, 2, 3, 4]
+print!w # [1, 2, 3, 4]
```
-Ownership transfers occur when an object is passed to a subroutine, for example.
-If you wish to retain ownership of the object after passing it to a subroutine, you must do cloning, freezing, or borrowing.
-However, as described below, borrowing can only be used in limited situations.
+Ownership transfer occurs, for example, when an object is passed to a subroutine.
+If you want to still have ownership after giving it away, you'll need to clone, freeze, or borrow.
+However, as will be explained later, there are limited situations in which it can be borrowed.
-## Cloning
+## replication
-Duplicate an object and transfer ownership of it. This is done by applying the `.clone` method to the real argument.
-The cloned object will be exactly the same as the original object, but independent of each other and unaffected by changes.
+Duplicate an object and transfer its ownership. It does this by applying the `.clone` method to the actual arguments.
+The duplicated object is exactly the same as the original, but independent of each other and unaffected by changes.
-Cloning is equivalent to deep copying in Python, and is generally more computationally and memory expensive than freezing and borrowing, since it re-creates the same object in its entirety.
-Subroutines that require object duplication are called "argument-consuming" subroutines.
+Duplication is equivalent to Python's deep copy, and since it recreates the same object entirely, the computation and memory costs are generally higher than freezing and borrowing.
+A subroutine that needs to duplicate an object is said to be an "argument consuming" subroutine.
-```erg
-capitalize s: Str!
- s.capitalize!()
+```python
+capitalize s: Str!=
+ s. capitalize!()
s
-s1 = !" hello"
+s1 = !"hello"
s2 = capitalize s1.clone()
-log s2, s1 # !" HELLO hello"
+log s2, s1 # !"HELLO hello"
```
-## Freezing
+## freeze
-Taking advantage of the fact that immutable objects can be referenced from multiple places, a variable object is converted to an immutable object.
-This is called freezing. Freezing is used to create iterators from mutable arrays.
-Since iterators cannot be created directly from mutable arrays, they are converted to immutable arrays.
-If you do not want to destroy the array, use the [`.freeze_map` method](./type/mut.md), etc.
+We take advantage of the fact that immutable objects can be referenced from multiple places and convert mutable objects to immutable objects.
+This is called freezing. Freezing is used, for example, when creating an iterator from a mutable array.
+Since you can't create an iterator directly from a mutable array, convert it to an immutable array.
+If you don't want to destroy the array, use the [`.freeze_map` method](./type/mut.md).
-```erg
-# Calculate the sum of the values produced by the iterator
+```python
+# Compute the sum of the values produced by the iterator
sum|T <: Add + HasUnit| i: Iterator T = ...
-x = [1, 2, 3].into [Int; !3].
+x = [1, 2, 3].into [Int; !3]
x.push!(4)
-i = x.iter() # TypeError: [Int; !4] has no method `iter`.
+i = x.iter() # TypeError: [Int; !4] has no method `iter`
y = x.freeze()
i = y.iter()
assert sum(i) == 10
-y # y is still touched after this.
+y # y can still be touched
```
-## Borrowing
+## borrow
-Borrowing is less expensive than cloning or freezing.
-Borrowing can be done in simple cases such as the following.
+Borrowing is cheaper than duplicating or freezing.
+Borrowing can be done in the following simple cases:
-```erg
+```python
peek_str ref(s: Str!) =
log s
-s = !" hello"
+s = !"hello"
peek_str s
```
-The borrowed value is called a __reference__ to the original object.
-You can "subloan" a reference to another subroutine, but you can't consume it because you are only borrowing it.
+A borrowed value is called a __reference__ to the original object.
+You can "sublease" the reference to another subroutine, but you cannot consume it because you are only borrowing it.
-```erg
-steal_str ref(s: Str!) =.
- # The log function only borrows arguments, so it can subloan
+```python
+steal_str ref(s: Str!) =
+ # Since the log function only borrows the arguments, it can be sub-leased
log s
- # Discard function consumes arguments, so it is an error
+ # error because the discard function consumes arguments
discard s # OwnershipError: cannot consume a borrowed value
# hint: use `clone` method
```
-```erg
+```python
steal_str ref(s: Str!) =
- # this is also no good (= consumes the right side)
+ # This is no good either (= consumes the right side)
x = s # OwnershipError: cannot consume a borrowed value
x
```
-Erg references are more restrictive than Rust. Although references are first-class objects in the language, they cannot be created explicitly and can only be specified as a way of passing real arguments by `ref`/`ref!`.
-This means that it is not possible to pack references into arrays or create classes with references as attributes.
+Erg's references are more restrictive than Rust's. References are first-class objects in the language, but cannot be created explicitly, they can only be specified as argument passing via `ref`/`ref!`.
+This means that you cannot stuff references into arrays or create classes with references as attributes.
-However, such restrictions are common in languages without references, so they are not that inconvenient.
+However, such restrictions are a natural specification in languages without references in the first place, and they are not so inconvenient.
-## Circular references
+## circular references
-Erg is designed to prevent unintentional memory leaks, and the memory checker will generate an error when it detects a circular reference. In most cases, this error can be resolved with a weak reference `Weak`. However, this does not allow the creation of objects with circular structures such as cyclic graphs, so we plan to implement an API that can create circular references as an unsafe operation.
+Erg is designed to prevent unintentional memory leaks, and will issue an error if the memory checker detects a circular reference. In most cases, this error can be resolved with a weak reference `Weak`. However, since it is not possible to generate objects with circular structures such as cyclic graphs, we plan to implement an API that can generate circular references as unsafe operations.
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/19_visibility.md b/doc/EN/syntax/19_visibility.md
index 4c1fef53..170616f8 100644
--- a/doc/EN/syntax/19_visibility.md
+++ b/doc/EN/syntax/19_visibility.md
@@ -1,56 +1,56 @@
# Visibility
Erg variables have the concept of __visibility__.
-All variables we have seen so far are called __private variables__. These are variables that are invisible to the outside world.
-For example, a private variable defined in the `foo` module cannot be referenced from another module.
+All the variables we've seen so far are called __private variables__. This is an externally invisible variable.
+For example, a private variable defined in the `foo` module cannot be referenced by another module.
-```erg
+```python
# foo.er
x = "this is an invisible variable"
```
-```erg
-# bar.er
+```python
+#bar.er
foo = import "foo"
foo.x # AttributeError: Module 'foo' has no attribute 'x' ('x' is private)
```
-In contrast, there is also a __public variable__, which can be referenced externally.
+On the other hand, there are also __public variables__, which can be referenced from the outside.
Public variables are defined with `.`.
-```erg
+```python
# foo.er
.x = "this is a visible variable"
```
-```erg
-# bar.er
+```python
+#bar.er
foo = import "foo"
assert foo.x == "this is a visible variable"
```
-Private variables do not need to be marked with anything, but can be marked with `::` or `self::` (or `Self::` for types, etc.) to make them explicitly private. A module can also be `module::`.
+You don't need to add anything to private variables, but you can also add `::` or `self::` (`Self::` for types etc.) to indicate that they are private. increase. It can also be `module::` if it is a module.
-```erg
+```python
::x = "this is an invisible variable"
assert ::x == x
-assert self::x == ::x
+assert self ::x == ::x
assert module::x == ::x
```
-In the context of mere sequential execution, private variables are almost synonymous with local variables. They can be referenced from inner scope.
+In the context of purely sequential execution, private variables are almost synonymous with local variables. It can be referenced from the inner scope.
-```erg
+```python
::x = "this is a private variable"
y =
x + 1 # exactly module::x
```
-The `::` allows you to distinguish between variables with the same name in a scope.
-Specify the scope of the variable you want to reference on the left. For the top level, specify `module`.
-If not specified, the innermost variable is referenced as in the normal case.
+By using `::`, you can distinguish variables with the same name within the scope.
+Specify the scope of the variable you want to refer to on the left. Specify `module` for the top level.
+If not specified, the innermost variable is referenced as usual.
-```erg
+```python
::x = 0
assert x == 0
y =
@@ -64,38 +64,38 @@ y =
assert module::x == 0
```
-In the scope of an anonymous subroutine, `self` specifies its own scope.
+In the anonymous subroutine scope, `self` specifies its own scope.
-```erg
+```python
x = 0
f = x ->
log module::x, self::x
-f 1 # 0 1
+f1# 0 1
```
`::` is also responsible for accessing private instance attributes.
-```erg
+```python
x = 0
C = Class {x = Int}
C.
- # Top-level x is referenced (warns to make it module::x)
+ # Top-level x is referenced (warning to use module::x)
f1 self = x
- # x of instance attribute is referenced
+ # instance attribute x is referenced
f2 self = self::x
```
## Visibility in external modules
-A class defined in one module can actually define methods from an external module as well.
+A class defined in one module can actually define methods from an external module.
-```erg
-## foo.er
+```python
+# foo.er
.Foo = Class()
```
-```erg
-# bar.er
+```python
+#bar.er
{Foo; ...} = import "foo"
Foo::
@@ -109,45 +109,45 @@ Foo.
foo::private() # AttributeError
```
-However, both of those methods can only be used within that module.
-Externally defined private methods can be referenced by methods of the `Foo` class only within the defining module.
-Public methods are exposed outside the class, but not to outside the module.
+However, both of those methods are only available within that module.
+Private methods defined externally are visible to methods of the `Foo` class only within the defining module.
+Public methods are exposed outside the class, but not outside the module.
-```erg
-# baz.er.
+```python
+# baz.er
{Foo; ...} = import "foo"
foo = Foo.new()
foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defined in module 'bar')
```
-Also, you cannot define a method on the type you are re-exporting.
-This is to avoid confusion when a method is found or not found depending on the module from which it is imported.
+Also, methods cannot be defined in the type to be re-exported.
+This is to avoid confusion about methods being found or not found depending on the module they are imported from.
-```erg
-# bar.er
+```python
+#bar.er
{.Foo; ...} = import "foo"
.Foo::
private self = pass # Error
-.Foo.
- Foo:: public self = self::private() # Error
+Foo.
+ public self = self::private() # Error
```
If you want to do something like this, define a [patch](./type/07_patch.md).
-```erg
-# bar.er.
+```python
+#bar.er
{Foo; ...} = import "foo"
FooImpl = Patch Foo
-FooImpl::
+FooImpl :=:
private self = pass
-FooImpl.
+Foo Impl.
public self = self::private()
```
-```erg
+```python
# baz.er
{Foo; ...} = import "foo"
{FooImpl; ...} = import "bar"
@@ -156,22 +156,22 @@ foo = Foo.new()
foo.public()
```
-## Restricted Public Variables
+## restricted public variables
Variable visibility is not limited to complete public/private.
You can also publish with restrictions.
-``` erg
+```python
# foo.er
.record = {
- .a = {
- .(.record)x = 0
- .(module)y = 0
- .z = 0
- }
- _ = .a.x # OK
- _ = .a.y # OK
- _ = .a.z # OK
+ .a = {
+ .(.record)x = 0
+ .(module)y = 0
+ .z = 0
+ }
+ _ = .a.x # OK
+ _ = .a.y # OK
+ _ = .a.z # OK
}
_ = .record.a.x # VisibilityError
@@ -179,7 +179,7 @@ _ = .record.a.y # OK
_ = .record.a.z # OK
```
-``` erg
+```python
foo = import "foo"
_ = foo.record.a.x # VisibilityError
_ = foo.record.a.y # VisibilityError
@@ -187,5 +187,5 @@ _ = foo.record.a.z # OK
```
- Previous | Next
-
+ Previous | Next
+
\ No newline at end of file
diff --git a/doc/EN/syntax/20_naming_rule.md b/doc/EN/syntax/20_naming_rule.md
index f729d83e..bba494fb 100644
--- a/doc/EN/syntax/20_naming_rule.md
+++ b/doc/EN/syntax/20_naming_rule.md
@@ -1,38 +1,38 @@
-# Naming Conventions
+# Naming convention
-If a variable is to be used as a constant expression, it must begin with a capital letter. The second and succeeding letters may be in lowercase.
+If you want to use a variable as a constant expression, make sure it starts with a capital letter. Two or more letters may be lowercase.
-```erg
+```python
i: Option Type = Int
match i:
t: Type -> log "type"
None -> log "None"
```
-Objects with side-effects must end with `!` must end with `!`. They are procedures, procedural methods, and mutable types.
-However, the `Proc` type itself is not a mutable type.
+Objects with side effects always end with `!`. Procedures and procedural methods, and mutable types.
+However, the `Proc` type itself is not mutable.
-```erg
+```python
# Callable == Func or Proc
c: Callable = print!
match c:
- p! -> log "proc" # can omit `: Proc` since it is self-explanatory
+ p! -> log "proc" # `: Proc` can be omitted since it is self-explanatory
f -> log "func"
```
-If you want to expose the attribute to the outside world, define it with `.`. `.` attribute is not prefixed, the attribute is not public. To avoid confusion, they cannot coexist in the same scope.
+If you want to expose an attribute to the outside world, define it with `.` at the beginning. If you don't put `.` at the beginning, it will be private. To avoid confusion, they cannot coexist within the same scope.
-```erg
+```python
o = {x = 1; .x = 2} # SyntaxError: private and public variables with the same name cannot coexist
```
## Literal Identifiers
-The above rule can be avoided by enclosing the string in single quotes (''). That is, a procedural object can also be assigned without `!`. In this case, however, even if the value is a constant expression, it is not considered a constant.
-Such a string identifier enclosed in single quotes is called a literal identifier.
-This is used when calling the API (FFI) of other languages such as Python.
+The above rule can be circumvented by enclosing the string in single quotes (''). That is, procedural objects can also be assigned without `!`. However, in this case, even if the value is a constant expression, it is not considered a constant.
+A character string enclosed in single quotes like this is called a literal identifier.
+This is used when calling APIs (FFI) of other languages such as Python.
-```erg
+```python
bar! = pyimport("foo").'bar'
```
@@ -40,11 +40,11 @@ Identifiers that are also valid in Erg do not need to be enclosed in ''.
Furthermore, literal identifiers can contain both symbols and spaces, so strings that cannot normally be used as identifiers can be used as identifiers.
-```erg
+```python
'∂/∂t' y
'test 1: pass x to y'()
```
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/21_lambda.md b/doc/EN/syntax/21_lambda.md
index 67167106..9a534f48 100644
--- a/doc/EN/syntax/21_lambda.md
+++ b/doc/EN/syntax/21_lambda.md
@@ -1,94 +1,95 @@
-# Anonymous Function
+# anonymous function
-An anonymous function is a syntax for creating function objects on the fly without naming them.
+Anonymous functions are a syntax for creating function objects on the fly without naming them.
-```erg
-# `->` is the anonymous function operator
+```python
+# `->` is an anonymous function operator
# same as `f x, y = x + y`
f = (x, y) -> x + y
# same as `g(x, y: Int): Int = x + y`
g = (x, y: Int): Int -> x + y
```
-You can omit `()` if there is only one argument.
+You can omit the `()` if there is only one argument.
-```erg
-assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4].
-assert ((i, j) -> [i, j])(1, 2) == [1, 2].
+```python
+assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4]
+assert ((i, j) -> [i, j])(1, 2) == [1, 2]
```
-In the case below `0..9, (i -> ...)`, not `(0..9, i) -> ...`.
-`->` takes only one argument on the left side. Multiple arguments are taken as a single tuple.
+In the case below it is `0..9, (i -> ...)` and not `(0..9, i) -> ...`.
+`->` takes only one argument on the left side. Multiple arguments are received as a single tuple.
-```erg
+```python
for 0..9, i: Int ->
...
```
-For anonymous functions, there is a difference in syntactic interpretation due to whitespace.
+In anonymous functions, there is a difference in parsing due to whitespace.
-```erg
-# In this case, it is interpreted as ``T(() -> Int)``.
-i: T () -> Int
-# In this case, it is interpreted as (U()) -> Int
+```python
+# In this case, interpreted as `T(() -> Int)`
+i: T() -> Int
+# in this case it is interpreted as (U()) -> Int
k: U() -> Int
```
-Anonymous functions can be used without arguments. `=>` is an anonymous procedure operator.
+Anonymous functions can be used without arguments.
-```erg
-p!= () => print!"`p!` was called"
-# `() ->`, `() =>` have the sugar-coated constructs `do`, `do!`.
+```python
+# `=>` is an anonymous procedure operator
+p! = () => print! "`p!` was called"
+# `() ->`, `() =>` have syntax sugar `do`, `do!`
# p! = do! print! "`p!` was called"
p!() # `p!` was called
```
-Argumentless functions can be used for lazy initialization.
+No-argument functions can be used for lazy initialization.
-```erg
+```python
time = import "time"
date = import "datetime"
now = if! True:
- do!
- time.sleep!
+ do!:
+ time. sleep! 1000
date.now!()
do date.new("1970", "1", "1", "00", "00")
```
-Typing and pattern matching can also be done. For this reason, the ``match`` function is realized almost entirely by the power of anonymous functions.
-The anonymous functions given as arguments to the ``match`` function are tried in order from the top. So, it is necessary to describe special cases at the top and more general cases as you go down. If you get the order wrong (as far as possible), the compiler will issue a Warning.
+You can also type and pattern match. Because of this, the `match` function is mostly implemented with the power of anonymous functions.
+Anonymous functions given as arguments to the `match` function are tried in order from the top. So, you should describe the special cases at the top and the more general cases at the bottom. If you get the order wrong, the compiler will issue a warning (if possible).
-```erg
-n = (Complex or Ratio or Int).sample!
-i = match n:
+```python
+n = (Complex or Ratio or Int).sample!()
+i = matchn:
PI -> PI # if equal to constant PI
- (i: 1..10) -> i # if 1~10 Int
- (i: Int) -> i # for Int
- (c: Complex) -> c.real() # case of Complex, Int < Complex, but can fall back
- _ -> panic "cannot convert to Int" # none of the above; match must cover all patterns
+ For (i: 1..10) -> i # Int from 1 to 10
+ (i: Int) -> i # Int
+ (c: Complex) -> c.real() # For Complex. Int < Complex, but can fallback
+ _ -> panic "cannot convert to Int" # If none of the above apply. match must cover all patterns
```
-Error handling can also be done using `?` or `match`.
+Error handling is also generally done using `?` or `match`.
-```erg
+```python
res: ParseResult Int
-match res:
+matchres:
i: Int -> i
err: Error -> panic err.msg
res2: Result Int, Error
match res2:
- ok: Not Error -> log Typeof ok
+ ok: Not Error -> log Type of ok
err: Error -> panic err.msg
```
-## Anonymous Polymorphic Function
+## Anonymous polycorrelation coefficient
-```erg
+```python
# same as id|T| x: T = x
id = |T| x: T -> x
```
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/22_subroutine.md b/doc/EN/syntax/22_subroutine.md
index 0128c059..c5f70cff 100644
--- a/doc/EN/syntax/22_subroutine.md
+++ b/doc/EN/syntax/22_subroutine.md
@@ -2,14 +2,14 @@
## Func
-```erg
+```python
some_func(x: T, y: U) -> V
some_func: (T, U) -> V
```
## Proc
-```erg
+```python
some_proc!(x: T, y: U) => V
some_proc!: (T, U) => V
```
@@ -18,7 +18,7 @@ some_proc!: (T, U) => V
The method type cannot be specified externally with ``Self``.
-```erg
+```python
.some_method(self, x: T, y: U) => ()
# Self.(T, U) => () takes ownership of self
.some_method: Ref(Self). (T, U) => ()
@@ -28,7 +28,7 @@ The method type cannot be specified externally with ``Self``.
In the following, assume that the type `T!` takes the type argument `N: Nat`. To specify it externally, use a type variable.
-```erg
+```python
T!: Nat -> Type
# ~> indicates the state of the type argument before and after application (in this case, self must be a variable reference)
T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => ()
@@ -39,7 +39,7 @@ For methods that do not have `ref!`, i.e., are deprived of ownership after appli
If ownership is taken, it is as follows.
-```erg
+```python
# If you don't use N, you can omit it with _.
# .some_method!: |N, X: Nat| T!(N).({X}) => T!(N+X)
.some_method!|N, X: Nat|(self(N), X: Nat) => T!(N+X)
@@ -51,7 +51,7 @@ It can be defined as a normal function by enclosing it with ``.
Neuter alphabetic operators such as `and` and `or` can be defined as neuter operators by enclosing them with ``.
-```erg
+```python
and(x, y, z) = x and y and z
`_+_`(x: Foo, y: Foo) = x.a + y.a
`-_`(x: Foo) = Foo.new(-x.a)
diff --git a/doc/EN/syntax/23_closure.md b/doc/EN/syntax/23_closure.md
index 3d5040d9..06128bf3 100644
--- a/doc/EN/syntax/23_closure.md
+++ b/doc/EN/syntax/23_closure.md
@@ -1,32 +1,32 @@
# Closure
-Erg subroutines have a "closure" feature that captures external variables.
+Erg subroutines have a feature called a "closure" that captures external variables.
-```erg
+```python
outer = 1
f x = outer + x
assert f(1) == 2
```
-Like immutable objects, mutable objects can also be captured.
+As with immutable objects, mutable objects can also be captured.
-```erg
+```python
sum = !0
for! 1..10, i =>
- sum.add!
+ sum.add!i
assert sum == 45
-p! x =
- sum.add!
+p!x=
+ sum.add!x
p!(1)
assert sum == 46
```
Note, however, that functions cannot capture mutable objects.
-If mutable objects could be referenced in a function, the following code could be written.
+If a mutable object can be referenced in a function, you can write code like the following.
-```erg
-# !!! This code is actually an error !!!
+```python
+# !!! This code actually gives an error !!!
i = !0
f x = i + x
assert f 1 == 1
@@ -34,31 +34,31 @@ i.add! 1
assert f 1 == 2
```
-The function should return the same value for the same argument, but that assumption has been violated.
-Note that ``i`` is evaluated for the first time at call time.
+The function should return the same value for the same arguments, but the assumption is broken.
+Note that `i` is evaluated only at call time.
-If you want the contents of a mutable object at the time of the function definition, `.clone` it.
+Call `.clone` if you want the contents of the mutable object at the time the function was defined.
-```erg
+```python
i = !0
immut_i = i.clone().freeze()
-f x = immut_i + x
+fx = immut_i + x
assert f 1 == 1
i.add! 1
assert f 1 == 1
```
-## Avoiding Mutable States, Functional Programming
+## avoid mutable state, functional programming
-```erg
-## Erg
+```python
+# Erg
sum = !0
for! 1..10, i =>
- sum.add!
+ sum.add!i
assert sum == 45
```
-The equivalent program above can be written in Python as follows.
+The equivalent program above can be written in Python as follows:
```python
# Python
@@ -68,29 +68,29 @@ for i in range(1, 10):
assert sum == 45
```
-However, Erg recommends a simpler way of writing.
-Instead of using subroutines and mutable objects to carry around state, the style is to localize the state using functions. This is called functional programming.
+However, Erg recommends a simpler notation.
+Instead of carrying around state using subroutines and mutable objects, use a style of localizing state using functions. This is called functional programming.
-```erg
+```python
# Functional style
sum = (1..10).sum()
assert sum == 45
```
-The above code produces exactly the same result as the previous one, but it can be seen that this one is much simpler.
+The code above gives exactly the same result as before, but you can see that this one is much simpler.
-The `fold` function can be used to perform a variety of operations other than summing.
+The `fold` function can be used to do more than sum.
`fold` is an iterator method that executes the argument `f` for each iteration.
-The initial value of the counter to accumulate the results is specified by `init` and accumulated in `acc`.
+The initial value of the counter that accumulates results is specified in `init` and accumulated in `acc`.
-```erg
+```python
# start with 0, result will
sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i)
assert sum == 45
```
-Erg is designed to be a natural and concise description of programming with invariant objects.
+Erg is designed to be a natural succinct description of programming with immutable objects.
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/24_module.md b/doc/EN/syntax/24_module.md
index ba586185..c33a57dc 100644
--- a/doc/EN/syntax/24_module.md
+++ b/doc/EN/syntax/24_module.md
@@ -2,17 +2,17 @@
Erg allows you to think of the file itself as a single record. This is called a module.
-```erg: foo.er
+```python: foo.er
# foo.er
.i = 1
```
-``` erg
+```python
# Defining the foo module is almost the same as defining this record
foo = {.i = 1}
```
-```erg: bar.er
+```python: bar.er
#bar.er
foo = import "foo"
print! foo #
@@ -21,7 +21,7 @@ assert foo.i == 1
Since module types are also record types, deconstruction assignment is possible.
-``` erg
+```python
{sin; cos; ...} = import "math"
```
@@ -39,4 +39,4 @@ Since module types are also record types, deconstruction assignment is possible.
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/25_object_system.md b/doc/EN/syntax/25_object_system.md
index 7b85ea6f..ed398a98 100644
--- a/doc/EN/syntax/25_object_system.md
+++ b/doc/EN/syntax/25_object_system.md
@@ -1,64 +1,68 @@
# Object
-All data that can be assigned to a variable. The `Object` class has the following attributes.
+All data that can be assigned to a variable. The attributes of the `Object` class are as follows.
-* `. __repr__`: returns a (non-rich) string representation of the object.
-* `. __sizeof__`: returns the size of the object (including heap allocation).
-* `. __dir__`: return a list of attributes of the object.
-* `. __hash__`: return the hash value of the object.
-* `. __getattribute__`: retrieve and return an object's attributes * `.
-* `.clone`: create and return a clone of an object (an independent entity in memory).
-* `.copy`: return a copy of an object (identical in memory).
+* `.__repr__`: Returns a (non-rich) string representation of the object
+* `.__sizeof__`: Returns the size of the object (including heap allocation)
+* `.__dir__`: Returns a list of object attributes
+* `.__hash__`: returns the hash value of the object
+* `.__getattribute__`: Get and return an attribute of an object
+* `.clone`: Creates and returns a clone of an object (with an independent entity in memory)
+* `.copy`: Returns a copy of the object (pointing to the same thing in memory)
## Record
-An object created by a record literal (`{attr = value; ...}`).
-This object can be a `.clone` or a `. __sizeof__` and other basic methods.
+An object generated by a record literal (`{attr = value; ...}`).
+This object has basic methods such as `.clone` and `.__sizeof__`.
-```erg
+```python
obj = {.x = 1}
assert obj.x == 1
-obj2 = {. .x; .y = 2}
+obj2 = {...x; .y = 2}
assert obj2.x == 1 and obj2.y == 2
```
## Attribute
-An object associated with an object. In particular, a subroutine attribute that takes itself (`self`) as its implicit first argument is called a method.
+An object associated with an object. In particular, a subroutine attribute that takes self (`self`) as its implicit first argument is called a method.
-```erg
-# Note that private_attr does not have `. Note that there is no `.
+```python
+# note that there is no `.` in private_attr
record = {.public_attr = j; private_attr = 2; .method = self -> self.i + 1}
-record.public_attr == 2
+record. public_attr == 2
record.private_attr # AttributeError: private_attr is private
assert record.method() == 3
```
## Element
-An object belonging to a specific type (e.g. `1` is an element of type `Int`). All objects are at least `{=}` type.
-In the case of an element of a class, it is sometimes called an instance.
+An object belonging to a particular type (e.g. `1` is an element of type `Int`). All objects are at least elements of type `{=}`.
+Elements of classes are sometimes called instances.
## Subroutine
-An object that is an instance of a function or procedure (including methods). The class representing a subroutine is `Subroutine`.
-More generally, `.__call__` is called a `Callable`.
+Indicates an object that is an instance of a function or procedure (including methods). The class representing a subroutine is `Subroutine`.
+An object that implements `.__call__` is more commonly called a `Callable`.
## Callable
-Object that implements `.__call__`. Superclass of `Subroutine`.
+An object that implements `.__call__`. It is also the superclass of `Subroutine`.
## Type
-An object that defines required attributes and makes objects common.
-There are two main types: polymorphic type and monomorphic type. Typical monomorphic types are `Int`, `Str`, etc. Polymorphic types include `Option Int`, `[Int; 3]` and so on.
-In addition, types that define methods to change the state of an object are called mutable types, and require variable attributes marked with `!` (e.g., dynamic arrays: `[T; !_]`).
+An object that defines requirement attributes and commonizes objects.
+There are two main types: Polymorphic Type and Monomorphic Type. Typical monomorphic types are `Int`, `Str`, etc., and polymorphic types are `Option Int`, `[Int; 3]`, etc.
+Furthermore, a type that defines a method that changes the state of an object is called a Mutable type, and it is necessary to add `!` to the variable attribute (e.g. dynamic array: `[T; !_]`) .
+
+## Class
+
+A type that has `.__new__`, `.__init__` methods, etc. Implement class-based object orientation.
## Function
-Subroutines that have read permission for external variables (excluding static variables) but do not have read/write permission for external variables. In other words, it has no external side effects.
-Erg functions are defined differently than Python because they do not allow side effects.
+A subroutine that has read permission for external variables (excluding static variables) but does not have read/write permission for external variables. In other words, it has no external side effects.
+Erg functions are defined differently than Python's because they do not allow side effects.
## Procedure
@@ -71,8 +75,8 @@ A subroutine that implicitly takes `self` as the first argument. It is a differe
## Entity
Objects that are not subroutines and types.
-Monomorphic entities (`1`, `"a"`, etc.) are also called value objects, and polymorphic entities (`[1, 2, 3], {"a": 1}`) are also called container objects.
+Monomorphic entities (`1`, `"a"`, etc.) are also called value objects, polymorphic entities (`[1, 2, 3], {"a": 1}`) are also called container objects .
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/26_pattern_matching.md b/doc/EN/syntax/26_pattern_matching.md
index 80819de2..c48c07c7 100644
--- a/doc/EN/syntax/26_pattern_matching.md
+++ b/doc/EN/syntax/26_pattern_matching.md
@@ -1,52 +1,56 @@
-# Pattern matching, Irrefutability
+# pattern matching, refutable
-## Patterns Available in Erg
+## Patterns available in Erg
-### Variable Pattern
+### variable pattern
-```erg
-# basic assignment
+```python
+# basic assignments
i = 1
# with type
i: Int = 1
# with anonymous type
i: {1, 2, 3} = 2
-# function
+
+# functions
fn x = x + 1
# equals
fn x: Add(Int) = x + 1
# (anonymous) function
fn = x -> x + 1
fn: Int -> Int = x -> x + 1
+
# higher-order type
a: [Int; 4] = [0, 1, 2, 3]
# or
-a: Array Int, 4 = [0, 1, 2, 3] # or
+a: Array Int, 4 = [0, 1, 2, 3]
```
-### Literal Pattern
+### Literal patterns
-```erg
-# if `i` cannot be determined to be 1 at compile time, TypeError occurs.
-# short hand of `_: {1} = i`
+```python
+# Raise a TypeError if `i` cannot be determined to be 1 at compile time.
+# omit `_: {1} = i`
1 = i
+
# simple pattern matching
match x:
1 -> "1"
2 -> "2"
_ -> "other"
+
# fibonacci function
-fib 0 = 0
-fib 1 = 1
-fib n: Nat = fib n-1 + fib n-2
+fib0 = 0
+fib1 = 1
+fibn: Nat = fibn-1 + fibn-2
```
-### Constant Pattern
+### constant pattern
-```erg
-cond = False
+```python
+cond=False
match! cond:
- True => print!
+ True => print! "cond is True"
_ => print! "cond is False"
PI = 3.141592653589793
@@ -58,61 +62,61 @@ name = match num:
_ -> "unnamed"
```
-### Refinement Pattern
+### Sieve pattern
-```erg
+```python
+# these two are the same
Array(T, N: {N | N >= 3})
-# == ==
Array(T, N | N >= 3)
f M, N | M >= 0, N >= 1 = ...
f(1, 0) # TypeError: N (2nd parameter) must be 1 or more
```
-### Discard (Wildcard) Pattern
+### discard (wildcard) pattern
-```erg
+```python
_ = 1
_: Int = 1
-zero _ = 0
+zero_ = 0
right(_, r) = r
```
-### Varargs Patterns
+### Variable length patterns
-Used in combination with the tuple/array/record pattern described below.
+It is used in combination with the tuple/array/record pattern described later.
-```erg
-[i, . .j] = [1, 2, 3, 4]
-assert j == [2, 3, 4].
+```python
+[i,...j] = [1, 2, 3, 4]
+assert j == [2, 3, 4]
first|T|(fst: T, ...rest: T) = fst
assert first(1, 2, 3) == 1
```
-### Tuple Pattern
+### Tuple pattern
-```erg
+```python
(i, j) = (1, 2)
((k, l), _) = ((1, 2), (3, 4))
-# () can be omitted if not nested (1, 2 are treated as (1, 2))
+# If not nested, () can be omitted (1, 2 are treated as (1, 2))
m, n = 1, 2
f(x, y) = ...
```
-### Array Pattern
+### array pattern
-```erg
+```python
[i, j] = [1, 2]
[[k, l], _] = [[1, 2], [3, 4]]
-length [] = 0
-length [_, . .rest] = 1 + length rest
+length[] = 0
+length[_, ...rest] = 1 + lengthrest
```
-### Record Pattern
+#### record pattern
-```erg
+```python
record = {i = 1; j = 2; k = 3}
{j; ...} = record # i, k will be freed
@@ -127,9 +131,9 @@ age = match person:
f {x: Int; y: Int} = ...
```
-### Data Class Pattern
+### Data class pattern
-```erg
+```python
Point = Inherit {x = Int; y = Int}
p = Point::{x = 1; y = 2}
Point::{x; y} = p
@@ -144,46 +148,46 @@ List T.
_ -> ...
second self =
match self:
- Cons::{rest=Cons::{head; ...} ; ...} -> head
+ Cons::{rest=Cons::{head; ...}; ...} -> head
_ -> ...
```
-### Enumeration Pattern
+### enumeration pattern
-* actually just an enumerated type
+*Actually, it's just an enumeration type
-```erg
+```python
match x:
i: {1, 2} -> "one or two: {i}"
_ -> "other"
```
-### Range Pattern
+### range pattern
-* actually just an interval type
+*Actually, it is just an interval type.
-```erg
+```python
# 0 < i < 1
-i: 0<... <1 = 0.5
+i: 0<..<1 = 0.5
# 1 < j <= 2
-_: {[I, J] | I, J: 1<. .2} = [1, 2]
+_: {[I, J] | I, J: 1<..2} = [1, 2]
# 1 <= i <= 5
match i
i: 1..5 -> ...
```
-### Non-patterns and Non-patternable Items
+### Things that aren't patterns, things that can't be patterned
-A pattern is something that can be uniquely specified. In this respect, pattern matching differs from ordinary conditional branching.
+A pattern is something that can be uniquely specified. In this respect pattern matching differs from ordinary conditional branching.
-The specification of a condition is not unique. For example, to determine whether the number `n` is even, the orthodox way is `n % 2 == 0`, but it can also be written as `(n / 2).round() == n / 2`.
-The non-unique form is non-trivial, whether it works correctly or is equivalent to another condition.
+Condition specifications are not unique. For example, to check if the number `n` is even, the orthodox is `n % 2 == 0`, but you can also write `(n / 2).round() == n / 2`.
+A non-unique form is not trivial whether it works correctly or is equivalent to another condition.
-#### Set
+#### set
-There is no pattern for sets. There is no pattern for sets because there is no way to retrieve elements uniquely.
-They can be retrieved with an iterator, but the order is not guaranteed.
+There is no set pattern. Because the set has no way to uniquely retrieve the elements.
+You can retrieve them by iterator, but the order is not guaranteed.
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/27_comprehension.md b/doc/EN/syntax/27_comprehension.md
index 91a9a4b5..24c903e0 100644
--- a/doc/EN/syntax/27_comprehension.md
+++ b/doc/EN/syntax/27_comprehension.md
@@ -1,56 +1,65 @@
# Comprehension
-An array can be created by `[expr | (name <- iterable)+ (predicate)*]`,
-And a set can be created by `{expr | (name <- iterable)+ (predicate)*}`.
+Array with `[expr | (name <- iterable)+ (predicate)*]`,
+set with `{expr | (name <- iterable)+ (predicate)*}`,
+You can create a Dict with `{key: value | (name <- iterable)+ (predicate)*}`.
-Dict can be created by `{key: value | (name <- iterable)+ (predicate)*}`.
+The first part of the clauses separated by `|` is called the layout clause (location clause), the second part is called the bind clause (binding clause), and the third part is called the guard clause (conditional clause).
+A guard clause can be omitted, but a bind clause cannot be omitted, and a guard clause cannot precede a bind clause.
-The first part of a clause delimited by `|` is called a layout clause, the second part is called a bind clause, and the third part is called a guard clause.
-The guard clause can be omitted, but not the bind clause, and the guard clause cannot be placed before the bind clause.
+Comprehension example
-e.g.
+```python
+# the layout clause is i
+# bind clause is i <- [0, 1, 2]
+assert [i | i <- [0, 1, 2]] == [0, 1, 2]
-```erg
-assert [i | i <- [0, 1, 2]] == [0, 1, 2]]
-assert [i / 2 | i <- 0..2] == [0.0, 0.5, 1.0]]
+# layout clause is i / 2
+# bind clause is i <- 0..2
+assert [i/2 | i <- 0..2] == [0.0, 0.5, 1.0]
+
+# layout clause is (i, j)
+# bind clause i <- 0..2, j <- 0..2
+# guard clause is (i + j) % 2 == 0
assert [(i, j) | i <- 0..2; j <- 0..2; (i + j) % 2 == 0] == [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)]
+
assert {i % 2 | i <- 0..9} == {0, 1}
assert {k: v | k <- ["a", "b"]; v <- [1, 2]} == {"a": 1, "b": 2}
```
-Erg's comprehension notation is influenced by Haskell, but there are some differences.
-In Haskell's list comprehensions, the order of variables makes a difference in the result, but not in Erg.
+Erg comprehensions are inspired by Haskell, but with some differences.
+For Haskell list comprehensions, the order of variables makes a difference in the result, but in Erg it doesn't matter.
-```haskell
+``` haskell
-- Haskell
-[(i, j) | i <- [1..3], j <- [3..5]] == [(1,3),(1,4),(1,5),(2,3),(2,4),(2,5),(3,3),(3,4),(3,5)]
-[(i, j) | j <- [3..5], i <- [1..3]] == [(1,3),(2,3),(3,3),(1,4),(2,4),(3,4),(1,5),(2,5),(3,5)]
+[(i, j) | i <- [1..3], j <- [3..5]] == [(1,3),(1,4),(1,5),(2 ,3),(2,4),(2,5),(3,3),(3,4),(3,5)]
+[(i, j) | j <- [3..5], i <- [1..3]] == [(1,3),(2,3),(3,3),(1 ,4),(2,4),(3,4),(1,5),(2,5),(3,5)]
```
-```erg
+```python
# Erg
-assert [(i, j) | i <- 1. <3; j <- 3.. <5] == [(i, j) | j <- 3.. <5; i <- 1.. <3]
+assert [(i, j) | i <- 1..<3; j <- 3..<5] == [(i, j) | j <- 3..<5; i <- 1.. <3]
```
-これはPythonと同じである。
+This specification is the same as that of Python.
```python
# Python
assert [(i, j) for i in range(1, 3) for j in range(3, 5)] == [(i, j) for j in range(3, 5) for i in range(1, 3)]
```
-## Refinement type
+## Sieve type
-Similar to comprehensions are refinement types. A refinement type is a type (enumerated type) in the form `{Name: Type | Predicate}`.
-In the case of a refinement type, Name is limited to one and the layout cannot be specified (but multiple values can be handled by using a tuple type, for example), and Predicate must be a compile-time computation, i.e., a constant expression.
+Similar to comprehensions are sieve types. A sieve type is a type (enumerated type) created in the form `{Name: Type | Predicate}`.
+In the case of the sieve type, only one Name can be specified and the layout cannot be specified (however, multiple values can be handled if it is a tuple type), and the Predicate can be calculated at compile time, that is, only a constant expression can be specified.
-```erg
+```python
Nat = {I: Int | I >= 0}
-# If the predicate expression is and only, it can be replaced by ;.
+# If the predicate expression is only and, it can be replaced with ;
# Nat2D = {(I, J): (Int, Int) | I >= 0; J >= 0}
Nat2D = {(I, J): (Int, Int) | I >= 0 and J >= 0}
```
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/28_spread_syntax.md b/doc/EN/syntax/28_spread_syntax.md
index 74f54a12..5f8f760a 100644
--- a/doc/EN/syntax/28_spread_syntax.md
+++ b/doc/EN/syntax/28_spread_syntax.md
@@ -1,42 +1,42 @@
# Spread assignment
-In a spread assignment, a variable can be prefixed with `...` in front of the variable, all the remaining elements can be expanded into the variable. This is called a spread assignment.
+In a decomposing assignment, putting `...` in front of a variable expands all remaining elements into that variable. This is called expansion assignment.
-```erg
-[x, ... .y] = [1, 2, 3]
+```python
+[x,...y] = [1, 2, 3]
assert x == 1
-assert y == [2, 3].
-x, ... .y = (1, 2, 3)
+assert y == [2, 3]
+x, ...y = (1, 2, 3)
assert x == 1
assert y == (2, 3)
```
## Extract assignment
-If nothing is written after `...`, the remaining elements are ignored and an assignment is made. This type of expansion assignment is specifically called an extract assignment.
-Extract assignment is a useful syntax for bringing certain attributes local to a module or record.
+If nothing is written after `...`, the remaining elements are ignored and assigned. This type of expansion assignment is specifically called extractive assignment.
+Extraction assignment is a convenient syntax for localizing specific attributes within a module or record.
-```erg
-{sin; cos; tan; ...} = import "math"
+```python
+{sin; cos; tan; ..} = import "math"
```
-This way, `sin`, `cos`, `tan` can be used locally from then on.
+After that, you can use `sin, cos, tan` locally.
You can do the same with records.
-```erg
+```python
record = {x = 1; y = 2}
{x; y; ...} = record
```
-If you want to expand all of them, use `{*} = record`, this is equivalent to `open` in OCaml and so on.
+If you want to expand all, use `{*} = record`. It is `open` in OCaml.
-```erg
+```python
record = {x = 1; y = 2}
-{*} = record
+{*} = records
assert x == 1 and y == 2
```
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/29_decorator.md b/doc/EN/syntax/29_decorator.md
index 2e1889eb..243fe7f0 100644
--- a/doc/EN/syntax/29_decorator.md
+++ b/doc/EN/syntax/29_decorator.md
@@ -1,82 +1,81 @@
-# Decorator
+# decorator (modifier)
-Decorators are used to add or make explicit a specific state or behavior for a type or function.
-The syntax for decorators is as follows.
+Decorators are used to add or demonstrate a particular state or behavior to a type or function.
+The syntax of the decorator is as follows.
-```erg
+```python
@deco
-X = ...
+X=...
```
-There can be more than one decorator, as long as they do not conflict.
+You can have multiple decorators as long as they don't conflict.
-A decorator is not a special object; its entity is simply a single-argument function. A decorator is equivalent to the following pseudo code.
+A decorator is not a special object, it's just a one-argument function. The decorator is equivalent to the following pseudocode.
-```erg
-X = ...
+```python
+X=...
X = deco(X)
```
-Erg does not allow reassignment of variables, so the above code will not pass.
-For a simple variable, `X = deco(...)` is the same, but for instant blocks and subroutines, you can't do that, so you need decorators.
+Erg doesn't allow reassignment of variables, so code like the one above won't work.
+For simple variables it's the same as `X = deco(...)`, but for instant blocks and subroutines you can't do that, so you need a decorator.
-```erg
+```python
@deco
-f x = ...
+f x =
y = ...
x + y
-# Can also prevent code from going horizontal.
+# You can also prevent the code from becoming horizontal
@LongNameDeco1
@LongNameDeco2
-C = Class ...
+C = Class...
```
-Here are some frequently used built-in decorators.
+Below are some frequently used built-in decorators.
## Inheritable
-Indicates that the type being defined is an inheritable class. If the `scope` argument is set to `"public"`, the class can be inherited by classes in external modules. By default, it is `"private"` and cannot be inherited from outside.
+Indicates that the defining type is an inheritable class. If you specify `"public"` for the argument `scope`, it will be possible to inherit even the class of the external module. By default it is `"private"` and cannot be inherited externally.
-## Final
+##Final
-disables overriding the `"final"` method. If you attach it to a class, it becomes a non-inheritable class, but since it is the default, it is meaningless.
+Make the method non-overridable. Adding it to a class makes it a non-inheritable class, but since it's the default it doesn't make sense.
## Override
-Use to override an attribute, which by default Erg will fail if you try to define an attribute that is the same as the base class.
+Used when overriding attributes. By default, Erg will throw an error if you try to define the same attribute as the base class.
## Impl
-Indicates implementation of traits.
+Indicates that the argument trait is implemented.
-```erg
-ClosedAdd = Trait {
- . `_+_` = Self.(Self) -> Self
+```python
+Add = Trait {
+ .`_+_` = Self.(Self) -> Self
}
-ClosedSub = Trait {
- . `_-_` = Self.(Self) -> Self
+Sub = Trait {
+ .`_-_` = Self.(Self) -> Self
}
-C = Class {i = Int}
+C = Class({i = Int}, Impl := Add and Sub)
C.
- @Impl ClosedAdd
+ @Impl Add
`_+_` self, other = C.new {i = self::i + other::i}
- @Impl ClosedSub
+ @Impl Sub
`_-_` self, other = C.new {i = self::i - other::}
```
## Attach
Specifies the attachment patch that comes with the trait by default.
-This allows you to reproduce the same behavior as the Rust trait.
+This allows you to reproduce the same behavior as Rust traits.
-```erg
+```python
# foo.er
-
Add R = Trait {
- .`_+_` = Self.(R) -> Self.AddO
.AddO = Type
+ .`_+_` = Self.(R) -> Self.AddO
}
@Attach AddForInt, AddForOdd
ClosedAdd = Subsume Add(Self)
@@ -87,35 +86,35 @@ AddForOdd = Patch(Odd, Impl := ClosedAdd)
AddForOdd.AddO = Even
```
-This way, when you import traits from other modules, the attachment patch is automatically applied.
+This will automatically apply the attachment patch when importing traits from other modules.
-```erg
-# Originally IntIsBinAdd, OddIsBinAdd must be imported at the same time, but can be omitted with attachment patch
+```python
+# Originally, IntIsBinAdd and OddIsBinAdd should be imported at the same time, but if it's an attachment patch, you can omit it
{BinAdd; ...} = import "foo"
-assert Int.AddO == Int
+assert Int. AddO == Int
assert Odd.AddO == Even
```
-Internally, they are only connected together using the trait's `.attach` method. If there is a conflict, it can be removed using the trait's `.detach` method.
+Internally it's just attached using the trait's `.attach` method. Conflicts can be removed with the trait's `.detach` method.
-```erg
+```python
@Attach X
-T = Trait ...
-assert X in T.attaches
+T = Trait...
+assert X in T. attaches
U = T.detach(X).attach(Y)
-assert X not in U.attaches
-assert Y in U.attaches
+assert X not in U. attaches
+assert Y in U. attaches
```
-## Deprecated
+##Deprecated
-Indicates that the variable is outdated and deprecated.
+Indicates that the variable specification is obsolete and deprecated.
## Test
-Indicates a subroutine for tests. Test subroutines are executed with the `erg test` command.
+Indicates that this is a test subroutine. Test subroutines are run with the `erg test` command.
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/30_error_handling.md b/doc/EN/syntax/30_error_handling.md
index 1a45a675..c52d5cbf 100644
--- a/doc/EN/syntax/30_error_handling.md
+++ b/doc/EN/syntax/30_error_handling.md
@@ -1,22 +1,22 @@
-# Error Handling
+# error handling system
-Mainly uses Result type.
-Erg will throw away Error type objects (not supported at top level).
+Mainly use Result type.
+In Erg, an error occurs if you throw away an Error type object (not supported at the top level).
-## Exceptions, Interoperation with Python
+## Exceptions, interop with Python
-Erg does not have an exception mechanism (Exception).
+Erg does not have an exception mechanism (Exception). When importing a Python function
-* Set the return value as `T or Error` type.
-* set the return value to `T or Panic` type (which may raise an error at runtime).
+* Set return value to `T or Error` type
+* `T or Panic` type (may cause runtime error)
-The latter is the default for `pyimport`. If you want to import as the former, use
-If you want to import as the former, specify `Error` in `pyimport`'s `exception_type` (`exception_type: {Error, Panic}`).
+There are two options, `pyimport` defaults to the latter. If you want to import as the former, use
+Specify `Error` in `pyimport` `exception_type` (`exception_type: {Error, Panic}`).
## Exceptions and Result types
-The `Result` type represents a value that may be an error. Error handling with `Result` is superior to the exception mechanism in several ways.
-First, you can tell from the type definition that a subroutine may raise an error, and it is obvious when you actually use it.
+The `Result` type represents values that may be errors. Error handling with `Result` is superior to the exception mechanism in several ways.
+First of all, it's obvious from the type definition that the subroutine might throw an error, and it's also obvious when you actually use it.
```python
# Python
@@ -28,31 +28,31 @@ except e:
print(e)
```
-In the above example, it is not clear from the code alone which function sends the exception. Even going back to the function definition, it is difficult to determine if the function raises the exception.
+In the above example, it is not possible to tell from this code alone which function raised the exception. Even going back to the function definition, it's hard to tell if the function throws an exception.
-```erg
+```python
# Erg
-try!
- do!
- x = foo!()? .bar()?
- y = baz!
+try!:
+ do!:
+ x = foo!()?.bar()
+ y = baz!()
qux!()?
e =>
- print!
+ print! e
```
-On the flip side, we can see that `foo!` and `qux!` can produce errors in this example.
-To be precise, `y` could also be of type `Result`, but we will have to deal with that eventually in order to use the values inside.
+On the other hand, in this example we can see that `foo!` and `qux!` can raise an error.
+Precisely `y` could also be of type `Result`, but you'll have to deal with it eventually to use the value inside.
-That is not the only advantage of using the `Result` type. The `Result` type is also thread-safe. This means that error information can be passed around (easily) during parallel execution.
+The benefits of using the `Result` type don't stop there. The `Result` type is also thread-safe. This means that error information can be (easily) passed between parallel executions.
## Context
-Unlike exceptions, the `Error`/`Result` types by themselves do not have side-effects, so they do not have context, but the `.context` method can be used to add information to the `Error` object. The `.context` method is a type of method that creates a new `Error` object by consuming the `Error` object itself. It is chainable and can hold multiple contexts.
+Since the `Error`/`Result` type alone does not cause side effects, unlike exceptions, it cannot have information such as the sending location (Context), but if you use the `.context` method, you can put information in the `Error` object. can be added. The `.context` method is a type of method that consumes the `Error` object itself and creates a new `Error` object. They are chainable and can hold multiple contexts.
-```erg
+```python
f() =
- todo() \f}
+ todo() \
.context "to be implemented in ver 1.2" \
.context "and more hints ..."
@@ -62,23 +62,22 @@ f()
# hint: and more hints ...
```
-Note that `Error` attributes such as `.msg`, `.kind`, etc., are not secondary and are not context and cannot be overwritten as they were when they were first generated.
+Note that `Error` attributes such as `.msg` and `.kind` are not secondary, so they are not context and cannot be overridden as they were originally created.
-## Stack Trace
+## Stack trace
-The `Result` type has been adopted by many other languages because of its convenience, but it has the disadvantage that the source of the error is harder to identify than the exception mechanism.
-Therefore, Erg has an attribute `.stack` on the `Error` object to reproduce a pseudo-exception mechanism-like stack trace.
-
-`.stack` is an array of caller objects. Each time an Error object is `return`ed (including by `?`) it stacks its calling subroutine on the `.stack`.
+The `Result` type is often used in other languages because of its convenience, but it has the disadvantage of making it difficult to understand the source of an error compared to the exception mechanism.
+Therefore, in Erg, the `Error` object has an attribute called `.stack`, and reproduces a pseudo-exception mechanism-like stack trace.
+`.stack` is an array of caller objects. Each time an Error object is `returned` (including by `?`) it pushes its calling subroutine onto the `.stack`.
And if it is `?`ed or `.unwrap`ed in a context where `return` is not possible, it will panic with a traceback.
-```erg
+```python
f x =
...
y = foo.try_some(x)?
...
-g x = ...
+g x =
y = f(x)?
...
@@ -89,22 +88,22 @@ i = g(1)?
# 10 | y = foo.try_some(x)?
# module::f, line 23, file "foo.er"
# 23 | y = f(x)?
-# module::g, line 40, file "foo.er"?
+# module::g, line 40, file "foo.er"
# 40 | i = g(1)?
# Error: ...
```
## Panic
-Erg also has a mechanism called __panicking__ to deal with unrecoverable errors.
-Unrecoverable errors are errors caused by external factors such as software/hardware malfunctions, errors that are so fatal that it makes no sense to continue executing the code, or errors that the programmer did not anticipate. When such an error occurs, the program is terminated on the spot because it cannot be restored to the normal system through the programmer's efforts. This is called "panicking".
+Erg also has a mechanism for dealing with unrecoverable errors called __panicing__.
+An unrecoverable error is an error caused by an external factor such as a software/hardware malfunction, an error so fatal that it makes no sense to continue executing the code, or an error unexpected by the programmer. Etc. If this happens, the program will be terminated immediately, because the programmer's efforts cannot restore normal operation. This is called "panicing".
-Panicking is done with the `panic` function.
+Panic is done with the `panic` function.
-```erg
+```python
panic "something went wrong!"
```
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/31_pipeline.md b/doc/EN/syntax/31_pipeline.md
index 10ae5ace..258c7cc9 100644
--- a/doc/EN/syntax/31_pipeline.md
+++ b/doc/EN/syntax/31_pipeline.md
@@ -1,24 +1,27 @@
-# Pipeline Operator
+# pipeline operator
-The pipeline operator is used like this:
+Pipeline operators are used like this:
-``` erg
+```python
assert f(g(x)) == (x |> g |> f)
assert f(g(x, y)) == ((x, y) |> g |> f)
```
In other words, the order `Callable(object)` can be changed to `object |> Callable`.
-Pipeline operators can also be used on methods. For methods, `object.method(args)` changes to `object |>.method(args)`.
-It looks like just an increase in `|>`, but since the bond strength is low, the amount of `()` may be reduced.
+The pipeline operator can also be used on methods. For methods, `object.method(args)` changes to `object |>.method(args)`.
+It looks like just more `|>`, but since the bond strength is low, you may be able to reduce the amount of `()`.
-``` erg
+```python
rand = -1.0..1.0 |>.sample!()
log rand # 0.2597...
+
1+1*2 |>.times do log("a", end := "") # aaa
-# without `|>`, the following will be `evens = (1..100).iter().filter(i -> i % 2 == 0).collect(Array)`
+
evens = 1..100 |>.iter |>.filter i -> i % 2 == 0 |>.collect Array
+# When implemented without the pipeline operator,
+_evens = (1..100).iter().filter(i -> i % 2 == 0).collect(Array)
# or
-_evens = 1..100\
+__evens = 1..100 \
.iter() \
.filter i -> i % 2 == 0 \
.collect Array
@@ -26,4 +29,4 @@ _evens = 1..100\
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/EN/syntax/32_integration_with_Python.md b/doc/EN/syntax/32_integration_with_Python.md
index 1948466b..945379a2 100644
--- a/doc/EN/syntax/32_integration_with_Python.md
+++ b/doc/EN/syntax/32_integration_with_Python.md
@@ -5,7 +5,7 @@
When the Erg script is compiled, a .pyc file is generated, which can simply be imported as a Python module.
However, variables set to private on the Erg side cannot be accessed from Python.
-```erg
+```python
# foo.er
.public = "this is a public variable"
private = "this is a private variable"
@@ -30,7 +30,7 @@ All objects imported from Python are by default of type `Object`. Since no compa
All APIs in the Python standard library are type specified by the Erg development team.
-```erg
+```python
time = pyimport "time"
time.sleep! 1
```
@@ -50,7 +50,7 @@ def baz():
...
```
-```erg
+```python
# foo.d.er
foo = pyimport "foo"
.X = declare foo.'X', Int
@@ -58,14 +58,14 @@ foo = pyimport "foo"
.baz! = declare foo.'baz', () => Int
```
-```erg
+```python
foo = pyimport "foo"
assert foo.bar(1) in Int
```
This ensures type safety by performing type checking at runtime. The ``declare`` function works roughly as follows.
-```erg
+```python
declare|S: Subroutine| sub!: S, T =
# Actually, => can be cast to a function without block side effects
x =>
diff --git a/doc/EN/syntax/33_package_system.md b/doc/EN/syntax/33_package_system.md
index dded29be..23e5aff5 100644
--- a/doc/EN/syntax/33_package_system.md
+++ b/doc/EN/syntax/33_package_system.md
@@ -25,7 +25,7 @@ You can import `foo` and `bar` modules in `app.er`. The `bar` directory can be r
A `foo` module is a module consisting of files, and a `bar` module is a module consisting of directories. The `bar` module also contains `baz` and `qux` modules.
This module is simply an attribute of the `bar` module, and can be accessed from `app.er` as follows.
-```erg
+```python
# app.er
foo = import "foo"
bar = import "bar"
@@ -47,7 +47,7 @@ For example, a module for testing. A file ending with `.test.er` is a (white box
└─ foo.test.er
./src
-```erg
+```python
# app.er
foo = import "foo"
@@ -66,14 +66,14 @@ Also, files ending in ``.private.er`` are private modules and can only be access
└─ qux.er
```
-```erg
+```python
# foo.er
bar = import "bar"
bar.qux
bar.baz # AttributeError: module 'baz' is private
```
-```erg
+```python
# qux.er
baz = import "baz"
```
diff --git a/doc/EN/syntax/34_generator.md b/doc/EN/syntax/34_generator.md
index 1aef8649..12eba58e 100644
--- a/doc/EN/syntax/34_generator.md
+++ b/doc/EN/syntax/34_generator.md
@@ -2,7 +2,7 @@
Generators are special procedures that use the `yield!` procedure in a block.
-```erg
+```python
g!() =
yield! 1
yield! 2
@@ -12,7 +12,7 @@ g!() =
`yield!` is a procedure defined in a block of subroutines that calls `self!.yield!`. Like `return`, it returns the value passed to it as a return value, but it has the feature of saving the current execution state of the block and executing it from the beginning when it is called again.
A generator is both a procedure and an iterator; a Python generator is a function that creates an iterator, while Erg iterates directly. Procedures themselves are generally not mutable objects (no `!`), but a generator is a mutable object because its own contents can change with each execution.
-```erg
+```python
# Generator!
g!: Generator!((), Int)
assert g!() == 1
@@ -22,7 +22,7 @@ assert g!() == 3
A Python-style generator can be defined as follows.
-```erg
+```python
make_g() = () =>
yield! 1
yield! 2
diff --git a/doc/EN/syntax/container_ownership.md b/doc/EN/syntax/container_ownership.md
new file mode 100644
index 00000000..f9206220
--- /dev/null
+++ b/doc/EN/syntax/container_ownership.md
@@ -0,0 +1,42 @@
+# Subscript (index access)
+
+`[]` is different from normal methods.
+
+```python
+a = [!1, !2]
+a[0].inc!()
+assert a == [2, 2]
+```
+
+Recall that the return value of a subroutine cannot be a reference.
+The type of `a[0]` here should clearly be `Ref!(Int!)` (the type of `a[0]` depends on the context).
+So `[]` is actually part of a special syntax, just like `.`. Unlike Python, it cannot be overloaded.
+It is also not possible to reproduce the behavior of `[]` in a method.
+
+```python
+C = Class {i = Int!}
+C. get(ref self) =
+ self::i # TypeError: `self::i` is `Int!` (require ownership) but `get` doesn't own `self`
+C.steal(self) =
+ self::i
+#NG
+C.new({i = 1}).steal().inc!() # OwnershipWarning: `C.new({i = 1}).steal()` is not owned by anyone
+# hint: assign to a variable or use `uwn_do!`
+# OK (assigning)
+c = C.new({i = 1})
+i = c.steal()
+i.inc!()
+assert i == 2
+# or (own_do!)
+own_do! C.new({i = 1}).steal(), i => i.inc!()
+```
+
+Also, `[]` can be disowned, but the element is not shifted.
+
+```python
+a = [!1, !2]
+i = a[0]
+i.inc!()
+assert a[1] == 2
+a[0] # OwnershipError: `a[0]` is moved to `i`
+```
\ No newline at end of file
diff --git a/doc/JA/syntax/grammar.txt b/doc/EN/syntax/grammar.md
similarity index 99%
rename from doc/JA/syntax/grammar.txt
rename to doc/EN/syntax/grammar.md
index d9dbbb2a..06a6d6d2 100644
--- a/doc/JA/syntax/grammar.txt
+++ b/doc/EN/syntax/grammar.md
@@ -1,4 +1,5 @@
# The Grammar of Erg (ver 0.1.0, provisional)
+```
special_op ::= '=' | '->' | '=>' | '.' | ',' | ':' | '::' | '|>' | '&'
separator ::= ';' | '\n'
escape ::= '\'
@@ -86,3 +87,4 @@ expr ::= accessor | literal
| call | def | lambda
line ::= expr separator+
program ::= expr? | (line | comment)*
+```
\ No newline at end of file
diff --git a/doc/EN/syntax/indexes.md b/doc/EN/syntax/indexes.md
index fb591da9..9af73d64 100644
--- a/doc/EN/syntax/indexes.md
+++ b/doc/EN/syntax/indexes.md
@@ -1,12 +1,12 @@
-# Index
+# index
-For APIs not in this index, see [here](./API/index.md).
-For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of terms.
+See [here](../API/index.md) for APIs not in this index.
+See [here](../dev_guide/terms.md) for terminology.
-## Symbols
+## symbol
* !
- * !-type → [Mutable type](./type/mut.md)
+ * !-type → [mutable type](./type/mut.md)
* [#](./00_basic.md/#comment)
* $
* %
@@ -16,18 +16,18 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te
* ()
* *
* [*-less multiplication](./01_literal.md/#less-multiplication)
-* + (unary)
- * +_ → + (unary)
-* + (binary)
+* + (prefix)
+ * +_ → + (prefix)
+* + (infix)
* ,
-* − (unary)
- * −_ → − (unary)
-* − (binary)
+* − (prefix)
+ * −_ → − (prefix)
+* − (infix)
* −>
* . → [Visibility]
* /
* :
- * :]
+ * :: → [visibility]
* ;
* <
* <:
@@ -46,9 +46,9 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te
* ^
* ^^
* _
- * _+_ → + (binary)
- * _-_ → − (binary)
-* ``
+ * _+_ → + (infix)
+ * _-_ → − (infix)
+*``
* {}
* {} type
* {:}
@@ -58,39 +58,39 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te
* ||
* ~
-## Alphabet
+## alphabet
### A
-* [algebraic type]
-* [And]
-* [and]
-* [assert]
-* [attribute]
+* algebraic type
+* And
+* and
+* assert
+* attribute
### B
-* [Base]
-* [Bool]
+* Base
+* Bool
### C
-* [Class]
+* Class
### D
* Deprecated
-* [distinct]
+* distinct
### E
-* [enum type]
-* [Eq]
-* [Erg]
+* enum type
+* Eq
+* Erg
### F
-* [for]
+* for
### G
@@ -98,10 +98,10 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te
### I
-* [if]
-* [import]
-* [in]
-* [Int]
+* if
+* import
+* in
+* Int
### J
@@ -109,34 +109,34 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te
### L
-* let-polymorphism → [rank-1 polymorphism]
-* [log]
+* let-polymorphism → [rank 1 polymorphism]
+* log
### M
-* [match]
+* match
### N
-* [Nat]
+* Nat
* Never
* None
* None
-* [Not]
-* [not]
+* Not
+* not
### O
-* [Option]
-* [Or]
-* [or]
-* [Ord]
+* Option
+* Or
+* or
+* Ord
### P
* panic
* [print!](./../API/procs.md#print)
-* [Python]
+* Python
### Q
@@ -144,22 +144,22 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te
* ref
* ref!
-* [Result]
-* [rootobj]
+* Result
+* rootobj
### S
* self
* [Self](./type/special.md)
* [side-effect](./07_side_effect.md)
-* [Str]
+* Str
### T
-* Trait
-* [True]
-* [Type]
-* [type]
+* Traits
+* True
+* Type
+* type
### U
@@ -167,10 +167,11 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te
### W
-* [while!]
+* while!
### X
### Y
### Z
+
diff --git a/doc/EN/syntax/quick_tour.md b/doc/EN/syntax/quick_tour.md
index 12ecd719..eca193f8 100644
--- a/doc/EN/syntax/quick_tour.md
+++ b/doc/EN/syntax/quick_tour.md
@@ -1 +1,267 @@
# Quick Tour
+
+The documentation below `syntax` is written with the aim of being understandable even for programming beginners.
+For those who have already mastered languages such as Python, Rust, Haskell, etc., it may be a bit verbose.
+
+So, here's an overview of the Erg grammar.
+Please think that the parts not mentioned are the same as Python.
+
+## variables, constants
+
+Variables are defined with `=`. As with Haskell, variables once defined cannot be changed. However, it can be shadowed in another scope.
+
+```python
+i = 0
+if True:
+ i = 1
+assert i == 0
+```
+
+Anything starting with an uppercase letter is a constant. Only things that can be computed at compile time can be constants.
+Also, a constant is identical in all scopes since its definition.
+
+```python
+PI = 3.141592653589793
+match random.random!(0..10):
+ PIs:
+ log "You get PI, it's a miracle!"
+```
+
+## declaration
+
+Unlike Python, only the variable type can be declared first.
+Of course, the declared type and the type of the object actually assigned to must be compatible.
+
+```python
+i: Int
+i = 10
+```
+
+## Functions
+
+You can define it just like in Haskell.
+
+```python
+fib0 = 0
+fib1 = 1
+fibn = fib(n - 1) + fib(n - 2)
+```
+
+An anonymous function can be defined like this:
+
+```python
+i -> i + 1
+assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4]
+```
+
+## operator
+
+The Erg-specific operators are:
+
+### mutating operator (!)
+
+It's like `ref` in Ocaml.
+
+```python
+i = !0
+i.update! x -> x + 1
+assert i == 1
+```
+
+## procedures
+
+Subroutines with side effects are called procedures and are marked with `!`.
+
+```python
+print! 1 # 1
+```
+
+## generic function (polycorrelation)
+
+```python
+id|T|(x: T): T = x
+id(1): Int
+id("a"): Str
+```
+
+## Records
+
+You can use the equivalent of records in ML-like languages (or object literals in JS).
+
+```python
+p = {x = 1; y = 2}
+```
+
+## Ownership
+
+Ergs are owned by mutable objects (objects mutated with the `!` operator) and cannot be rewritten from multiple places.
+
+```python
+i = !0
+j = i
+assert j == 0
+i#MoveError
+```
+
+Immutable objects, on the other hand, can be referenced from multiple places.
+
+## Visibility
+
+Prefixing a variable with `.` makes it a public variable and allows it to be referenced from external modules.
+
+```python
+# foo.er
+.x = 1
+y = 1
+```
+
+```python
+foo = import "foo"
+assert foo.x == 1
+foo.y # VisibilityError
+```
+
+## pattern matching
+
+### variable pattern
+
+```python
+# basic assignments
+i = 1
+# with type
+i: Int = 1
+# functions
+fn x = x + 1
+fn: Int -> Int = x -> x + 1
+```
+
+### Literal patterns
+
+```python
+# if `i` cannot be determined to be 1 at compile time, TypeError occurs.
+# shorthand of `_: {1} = i`
+1 = i
+# simple pattern matching
+match x:
+ 1 -> "1"
+ 2 -> "2"
+ _ -> "other"
+# fibonacci function
+fib0 = 0
+fib1 = 1
+fibn: Nat = fibn-1 + fibn-2
+```
+
+### constant pattern
+
+```python
+PI = 3.141592653589793
+E = 2.718281828459045
+num = PI
+name = match num:
+ PI -> "pi"
+ E -> "e"
+ _ -> "unnamed"
+```
+
+### discard (wildcard) pattern
+
+```python
+_ = 1
+_: Int = 1
+right(_, r) = r
+```
+
+### Variable length patterns
+
+Used in combination with the tuple/array/record pattern described later.
+
+```python
+[i,...j] = [1, 2, 3, 4]
+assert j == [2, 3, 4]
+first|T|(fst: T, ...rest: T) = fst
+assert first(1, 2, 3) == 1
+```
+
+### Tuple pattern
+
+```python
+(i, j) = (1, 2)
+((k, l), _) = ((1, 2), (3, 4))
+# If not nested, () can be omitted (1, 2 are treated as (1, 2))
+m, n = 1, 2
+```
+
+### array pattern
+
+```python
+length[] = 0
+length[_, ...rest] = 1 + lengthrest
+```
+
+#### record pattern
+
+```python
+{sin; cos; tan; ...} = import "math"
+{*} = import "math" # import all
+
+person = {name = "John Smith"; age = 20}
+age = match person:
+ {name = "Alice"; _} -> 7
+ {_; age} -> age
+```
+
+### Data class pattern
+
+```python
+Point = Inherit {x = Int; y = Int}
+p = Point::{x = 1; y = 2}
+Point::{x; y} = p
+```
+
+## Comprehensions
+
+```python
+odds = [i | i <- 1..100; i % 2 == 0]
+```
+
+## class
+
+Erg does not support multiple/multilevel inheritance.
+
+## Traits
+
+They are similar to Rust traits, but in a more literal sense, allowing composition and decoupling, and treating attributes and methods as equals.
+Also, it does not involve implementation.
+
+```python
+XY = Trait {x = Int; y = Int}
+Z = Trait {z = Int}
+XYZ = XY and Z
+Show = Trait {show: Self.() -> Str}
+
+@Impl XYZ, Show
+Point = Class {x = Int; y = Int; z = Int}
+Point.
+ ...
+```
+
+## patch
+
+You can give implementations to classes and traits.
+
+## Sieve type
+
+A predicate expression can be type-restricted.
+
+```python
+Nat = {I: Int | I >= 0}
+```
+
+## parametric type with value (dependent type)
+
+```python
+a: [Int; 3]
+b: [Int; 4]
+a + b: [Int; 7]
+```
\ No newline at end of file
diff --git a/doc/EN/syntax/type/01_type_system.md b/doc/EN/syntax/type/01_type_system.md
index d45ede30..3f1ee80a 100644
--- a/doc/EN/syntax/type/01_type_system.md
+++ b/doc/EN/syntax/type/01_type_system.md
@@ -6,7 +6,7 @@ The following is a brief description of Erg's type system. Details are explained
One of the unique features of Erg is that there is not much difference in syntax between (normal) variable, function (subroutine), and type (Kind) definitions. All are defined according to the syntax of normal variable and function definitions.
-```erg
+```python
f i: Int = i + 1
f #
f(1) # 2
@@ -64,7 +64,7 @@ Erg's array (Array) is what Python calls a list. `[Int; 3]` is an array class th
> __Note__: `(Type; N)` is both a type and a value, so it can be used like this.
>
-> ```erg.
+> ```python.
> Types = (Int, Str, Bool)
>
> for! Types, T =>
@@ -73,7 +73,7 @@ Erg's array (Array) is what Python calls a list. `[Int; 3]` is an array class th
> a: Types = (1, "aaa", True)
> ```
-```erg
+```python
pop|T, N|(l: [T; N]): ([T; N-1], T) =
[...l, last] = l
(l, last)
@@ -86,7 +86,7 @@ lpop|T, N|(l: [T; N]): (T, [T; N-1]) =
A type ends with `!` can be rewritten internal structure. For example, the `[T; !N]` class is a dynamic array.
To create an object of type `T!` from an object of type `T`, use the unary operator `!`.
-```erg
+```python
i: Int! = !1
i.update! i -> i + 1
assert i == 2
@@ -101,7 +101,7 @@ assert mut_arr == [1, 2, 3, 4].
Types are defined as follows.
-```erg
+```python
Point2D = {.x = Int; .y = Int}
```
@@ -115,7 +115,7 @@ As mentioned earlier, a "type" in Erg roughly means a set of objects.
The following is a definition of the `Add` type, which requires `+` (the middle operator). `R, O` are the so-called type parameters, which can be a true type (class) such as `Int` or `Str`. In other languages, type parameters are given a special notation (generics, templates, etc.), but in Erg they can be defined just like normal parameters.
Type parameters can also be used for types other than type objects. For example, the array type `[Int; 3]` is a syntax sugar for `Array Int, 3`. If the type implementations overlap, the user must explicitly choose one.
-```erg
+```python
Add R = Trait {
.AddO = Type
. `_+_` = Self.(R) -> Self.AddO
@@ -124,7 +124,7 @@ Add R = Trait {
.`_+_` is an abbreviation for Add.`_+_`. The prefix operator .`+_` is a method of type `Num`.
-```erg
+```python
Num = Add and Sub and Mul and Eq
NumImpl = Patch Num
NumImpl.
@@ -134,7 +134,7 @@ NumImpl.
Polymorphic types can be treated like functions. They can be monomorphic by specifying them as `Mul Int, Str`, etc. (in many cases, they are inferred with real arguments without specifying them).
-```erg
+```python
1 + 1
`_+_` 1, 1
Nat.`_+_` 1, 1
@@ -146,7 +146,7 @@ The top four lines return the same result (to be exact, the bottom one returns `
This is because `Int <: Ratio`, so `1` is downcast to `Ratio`.
But this is not cast.
-```erg
+```python
i = 1
if i: # TypeError: i: Int cannot be cast to Bool, use Int.is_zero() instead.
log "a"
@@ -159,7 +159,7 @@ This is because `Bool <: Int` (`True == 1`, `False == 0`). Casts to subtypes gen
Erg uses static duck typing, so there is little need to explicitly specify the type.
-```erg
+```python
f x, y = x + y
```
@@ -168,7 +168,7 @@ If `{0}, {-1}`, it is monomorphic to `Int` since it does not match `Nat`. If the
`{0}` and `{1}` are enumerated types that are partial types such as `Int` and `Nat`.
Enumerated types, for example, can be given names and request/implementation methods. In namespaces that have access to that type, objects that satisfy the request can use the implementation method.
-```erg
+```python
Binary = Patch {0, 1}
Binary.
# self contains an instance. In this example, either 0 or 1.
@@ -185,7 +185,7 @@ Binary.
Thereafter, the code `0.to_bool()` is possible (although `0 as Bool == False` is defined built-in).
Here is an example of a type that can actually rewrite `self` as shown in the code.
-```erg
+```python
Binary! = Patch {0, 1}!
Binary!
switch! ref! self = match! self:
@@ -199,7 +199,7 @@ print! b # => 0
## Structure type (anonymous type)
-```erg
+```python
Binary = {0, 1}
```
@@ -212,14 +212,14 @@ Such types are called structural types. When we want to emphasize its use as the
The following cannot be specified. For example, you cannot specify `Int` and `Int` and `Int` and `Int` and `Int` and `Int`.
For example, `Int` and `Str` are both `Add`, but `Int` and `Str` cannot be added.
-```erg
+```python
add l: Add, r: Add =
l + r # TypeError: there is no implementation of `_+_`: |T, U <: Add| (T, U) ->
```
Also, the types `A` and `B` below are not considered the same type. However, the type `O` is considered to match.
-```erg
+```python
... |R1; R2; O; A <: Add(R1, O); B <: Add(R2, O)|
```
diff --git a/doc/EN/syntax/type/02_basic.md b/doc/EN/syntax/type/02_basic.md
index 3a270717..d555b8ce 100644
--- a/doc/EN/syntax/type/02_basic.md
+++ b/doc/EN/syntax/type/02_basic.md
@@ -4,7 +4,7 @@
In Erg, the type of a variable can be specified after `:` as follows. This can be done at the same time as an assignment.
-```erg
+```python
i: Int # Declare the variable i to be of type Int
i: Int = 1
j = 1 # type specification can be omitted
@@ -12,7 +12,7 @@ j = 1 # type specification can be omitted
You can also specify a type for ordinary expressions.
-```erg
+```python
i = 1: Int
f([1, "a"]: [Int or Str])
```
@@ -20,7 +20,7 @@ f([1, "a"]: [Int or Str])
For simple variable assignments, most type specifications can be omitted.
Type specifications are more useful when defining subroutines and types.
-```erg
+```python
# Type specification for parameters
f x, y: Array Int = ...
T X, Y: Array Int = ...
@@ -28,20 +28,20 @@ T X, Y: Array Int = ...
Note that in the above case, `x, y` are both `Array Int`.
-```erg
+```python
# The value of a capital variable must be a constant expression
f X: Int = X
```
Alternatively, if you don't need complete information about the type argument, you can omit it with `_`.
-```erg
+```python
g v: [T; _] = ...
```
Note, however, `_` at a type specification implies `Object`.
-```erg
+```python
f x: _, y: Int = x + y # TypeError: + is not implemented between Object and Int
```
@@ -52,7 +52,7 @@ The left side of `<:` can only specify a class. Use `Subtypeof` or similar opera
This is also often used when defining subroutines or types, rather than simply specifying variables.
-```erg
+```python
# Subtype specification of an argument
f X <: T = ...
@@ -66,7 +66,7 @@ Iterable T = Trait {
You can also use a subtype specification when defining a class to statically check whether the class is a subtype of the specified type.
-```erg
+```python
# Class C is a subtype of Show
C = Class Object, Impl := Show
C.show self = ... # Show's required attributes.
@@ -74,7 +74,7 @@ C.show self = ... # Show's required attributes.
You can also specify a subtype only in specific cases.
-```erg
+```python
K T: Eq
K Int <: Show and Eq
K T = Class Object
@@ -87,7 +87,7 @@ K(Int).
Subtype specification is recommended when implementing structural types.
This is because, due to the nature of structural subtyping, typo or type specification errors will not cause errors when implementing required attributes.
-```erg
+```python
C = Class Object
C.shoe self = ... # Show is not implemented due to Typo (it is considered just a unique method).
```
@@ -96,7 +96,7 @@ C.shoe self = ... # Show is not implemented due to Typo (it is considered just a
Attributes can be defined for traits and classes only in modules.
-```erg
+```python
C = Class()
C.pub_attr = "this is public"
C::private_attr = "this is private"
@@ -107,7 +107,7 @@ assert c.pub_attr == "this is public"
The syntax for defining a batch definition is called a batch definition, in which a newline is added after `C.` or `C::` and the definitions are grouped together below the indentation.
-```erg
+```python
C = Class()
C.pub1 = ...
C.pub2 = ...
@@ -127,7 +127,7 @@ C::
Types can be aliased. This allows long types, such as record types, to be shortened.
-```erg
+```python
Id = Int
Point3D = {x = Int; y = Int; z = Int}
IorS = Int or Str
@@ -140,7 +140,7 @@ However, only one alias of the same type is allowed per module, and multiple ali
This means that types with different purposes should be defined as separate types.
The purpose is also to prevent adding aliases on top of types that already have aliases.
-```erg
+```python
Id = Int
UserId = Int # TypeWarning: duplicate aliases: Id and UserId
diff --git a/doc/EN/syntax/type/03_trait.md b/doc/EN/syntax/type/03_trait.md
index 9fcf79b0..ea1fb991 100644
--- a/doc/EN/syntax/type/03_trait.md
+++ b/doc/EN/syntax/type/03_trait.md
@@ -3,7 +3,7 @@
Trait is a nominal type that adds a type attribute requirement to record types.
It is similar to the Abstract Base Class (ABC) in Python, but with the distinction of being able to perform algebraic operations.
-```erg
+```python
Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int}
```
@@ -12,7 +12,7 @@ Trait does not distinguish between attributes and methods.
Note that traits can only be declared, not implemented (implementation is achieved by a feature called patching, which will be discussed later).
Traits can be checked for implementation in a class by specifying a partial type.
-```erg
+```python
Point2D <: Norm
Point2D = Class {.x = Int; .y = Int}
Point2D.norm self = self.x**2 + self.y**2
@@ -20,14 +20,14 @@ Point2D.norm self = self.x**2 + self.y**2
Error if the required attributes are not implemented.
-```erg
+```python
Point2D <: Norm # TypeError: Point2D is not a subtype of Norm
Point2D = Class {.x = Int; .y = Int}
```
Traits, like structural types, can apply operations such as composition, substitution, and elimination (e.g. `T and U`). The resulting trait is called an instant trait.
-```erg
+```python
T = Trait {.x = Int}
U = Trait {.y = Int}
V = Trait {.x = Int; y: Int}
@@ -40,7 +40,7 @@ assert Structural(W) == Structural(T.replace {.x = Ratio})
Trait is also a type, so it can be used for normal type specification.
-```erg
+```python
points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)]
assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25].
```
@@ -51,7 +51,7 @@ The expansion operator `...` allows you to define a trait that contains a certai
In the example below, `BinAddSub` subsumes `BinAdd` and `BinSub`.
This corresponds to Inheritance in a class, but unlike Inheritance, multiple base types can be combined using `and`. Traits that are partially excluded by `not` are also allowed.
-```erg
+```python
Add R = Trait {
.AddO = Type
. `_+_` = Self.(R) -> Self.AddO
@@ -69,7 +69,7 @@ BinAddSub = Subsume Add(Self) and Sub(Self)
Traits can be structured.
-```erg
+```python
SAdd = Structural Trait {
. `_+_` = Self.(Self) -> Self
}
@@ -87,7 +87,7 @@ assert add(C.new(1), C.new(2)) == C.new(3)
Nominal traits cannot be used simply by implementing a request method, but must be explicitly declared to have been implemented.
In the following example, `add` cannot be used with an argument of type `C` because there is no explicit declaration of implementation. It must be `C = Class {i = Int}, Impl := Add`.
-```erg
+```python
Add = Trait {
.`_+_` = Self.(Self) -> Self
}
@@ -109,7 +109,7 @@ Structural traits do not need to be declared for this implementation, but instea
Traits can take parameters. This is the same as for polymorphic types.
-```erg
+```python
Mapper T: Type = Trait {
.mapIter = {Iterator}
.map = Self(T). (T -> U) -> Self.MapIter U
@@ -127,7 +127,7 @@ assert [1, 2, 3].iter().map(x -> "{x}").collect(Array) == ["1", "2", "3"].
Derived traits can override the type definitions of the base trait.
In this case, the type of the overriding method must be a subtype of the base method type.
-```erg
+```python
# `Self.(R) -> O` is a subtype of ``Self.(R) -> O or Panic
Div R, O: Type = Trait {
. `/` = Self.(R) -> O or Panic
@@ -142,7 +142,7 @@ SafeDiv R, O = Subsume Div, {
The actual definitions of `Add`, `Sub`, and `Mul` look like this.
-```erg
+```python
Add R = Trait {
.Output = Type
. `_+_` = Self.(R) -> .Output
@@ -159,7 +159,7 @@ Mul R = Trait {
`.Output` is duplicated. If you want to implement these multiple traits at the same time, specify the following.
-```erg
+```python
P = Class {.x = Int; .y = Int}
# P|Self <: Add(P)| can be abbreviated to P|<: Add(P)|
P|Self <: Add(P)|.
@@ -172,7 +172,7 @@ P|Self <: Mul(Int)|.
Duplicate APIs implemented in this way are almost always type inferred when used, but can also be resolved by explicitly specifying the type with `||`.
-```erg
+```python
print! P.Output # TypeError: ambiguous type
print! P|<: Mul(Int)|.Output #
```
diff --git a/doc/EN/syntax/type/04_class.md b/doc/EN/syntax/type/04_class.md
index f582937a..b345aa65 100644
--- a/doc/EN/syntax/type/04_class.md
+++ b/doc/EN/syntax/type/04_class.md
@@ -3,7 +3,7 @@
A class in Erg is roughly a type that can create its own elements (instances).
Here is an example of a simple class.
-```erg
+```python
Person = Class {.name = Str; .age = Nat}
# If `.new` is not defined, then Erg will create `Person.new = Person::__new__`
Person.
@@ -22,7 +22,7 @@ In the class above, the `.new` method is defined so that field names, etc. can b
Note that the following definition without line breaks will result in a syntax error.
-```erg
+```python
Person.new name, age = ... # SyntaxError: cannot define attributes directly on an object
```
@@ -39,7 +39,7 @@ class Person:
age: int
```
-```erg
+```python
# In Erg, this notation implies the declaration of a class attribute (not an instance attribute)
Person = Class()
Person.
@@ -47,7 +47,7 @@ Person.
age: Int
```
-```erg
+```python
# Erg code for the Python code above
Person = Class {
.name = Str
@@ -61,7 +61,7 @@ In addition, dividing the attributes in this way clarifies roles such as "this a
The example below illustrates this. The attribute `species` is common to all instances, so it is more natural to use it as a class attribute. However, the attribute `name` should be an instance attribute because each instance should have it individually.
-```erg
+```python
Person = Class {name = Str}
Person::
species = "human"
@@ -85,7 +85,7 @@ alice.greet() # Hello, My name is Alice.
Incidentally, if an instance attribute and a type attribute have the same name and the same type, a compile error occurs. This is to avoid confusion.
-```erg
+```python
C = Class {.i = Int}
C.i = 1 # AttributeError: `.i` is already defined in instance fields
```
@@ -102,7 +102,7 @@ Erg does not allow you to add class methods, but you can use [patch](./07_patch.
You can also inherit from existing classes ([Inheritable](./../27_decorator.md/#inheritable) class).
You can create an inherited class by using `Inherit`. The type on the left-hand side is called the derived class, and the argument type of `Inherit` on the right-hand side is called the base class (inherited class).
-```erg
+```python
MyStr = Inherit Str
# other: You can use MyStr if you set ``other: Str''.
MyStr.
@@ -117,7 +117,7 @@ Unlike Python, the defined Erg classes are `final` (non-inheritable) by default.
To make a class inheritable, an `Inheritable` decorator must be attached to the class.
Str` is one of the inheritable classes.
-```erg
+```python
MyStr = Inherit Str # OK
MyStr2 = Inherit MyStr # NG
@@ -131,7 +131,7 @@ MyStr3 = Inherit InheritableMyStr # OK
Classes have a different equivalence checking mechanism than types.
Types are equivalence tested based on their structure.
-```erg
+```python
Person = {.name = Str; .age = Nat}
Human = {.name = Str; .age = Nat}
@@ -140,7 +140,7 @@ assert Person == Human
class has no equivalence relation defined.
-```erg
+```python
Person = Class {.name = Str; .age = Nat}
Human = Class {.name = Str; .age = Nat}
@@ -151,7 +151,7 @@ Person == Human # TypeError: cannot compare classes
We said that a class is a type that can generate its own elements, but that is not a strict description. In fact, a record type + patch can do the same thing.
-```erg
+```python
Person = {.name = Str; .age = Nat}
PersonImpl = Patch Person
PersonImpl.
@@ -174,7 +174,7 @@ Type checking for classes is simply a matter of checking the object's `. __class
Erg enables NSTs in classes; the advantages of NSTs include robustness.
When writing large programs, it is often the case that the structure of an object is coincidentally matched.
-```erg
+```python
Dog = {.name = Str; .age = Nat}
DogImpl = Patch Dog
DogImpl.
@@ -192,7 +192,7 @@ john.bark() # "Yelp!"
The structure of `Dog` and `Person` is exactly the same, but it is obviously nonsense to allow animals to greet and humans to bark.
The former is impossible, so it is safer to make it inapplicable. In such cases, it is better to use classes.
-```erg
+```python
Dog = Class {.name = Str; .age = Nat}
Dog.bark = log "Yelp!"
...
@@ -207,7 +207,7 @@ Another feature is that the type attributes added by the patch are virtual and a
That is, `T.x`, `T.bar` are objects that can be accessed (compile-time bound) by types compatible with `{i = Int}`, and are not defined in `{i = Int}` or `C`.
In contrast, class attributes are held by the class itself. Therefore, they cannot be accessed by classes that are not in an inheritance relationship, even if they have the same structure.
-```erg
+```python
C = Class {i = Int}
C.
foo self = ...
@@ -233,7 +233,7 @@ There are two types of classes: regular classes, which are record classes throug
The data class inherits the functionality of the record class and has features such as decomposition assignment, `==` and `hash` implemented by default, etc. On the other hand, the data class has its own equivalence relation and format display.
On the other hand, if you want to define your own equivalence relations or formatting displays, you should use the normal class.
-```erg
+```python
C = Class {i = Int}
c = C.new {i = 1}
d = C.new {i = 2}
@@ -251,7 +251,7 @@ assert e ! = f
To facilitate defining classes of type `Or`, an `Enum` is provided.
-```erg
+```python
X = Class()
Y = Class()
XorY = Enum X, Y
@@ -260,7 +260,7 @@ XorY = Enum X, Y
Each type can be accessed as `XorY.X`, `XorY.Y` and the constructor can be obtained as `XorY.cons(X)`.
`.cons` is a method that takes a class and returns its constructor.
-```erg
+```python
x1 = XorY.new X.new()
x2 = XorY.cons(X)()
assert x1 == x2
@@ -270,7 +270,7 @@ assert x1 == x2
A class is a subtype of a requirement type. methods (including patch methods) of the requirement type can be used in the class.
-```erg
+```python
T = Trait {.foo = Foo}
C = Class(... , impl: T)
C.
diff --git a/doc/EN/syntax/type/05_inheritance.md b/doc/EN/syntax/type/05_inheritance.md
index bb8c78f1..92607492 100644
--- a/doc/EN/syntax/type/05_inheritance.md
+++ b/doc/EN/syntax/type/05_inheritance.md
@@ -3,7 +3,7 @@
Inheritance allows you to define a new class that adds functionality or specialization to an existing class.
Inheritance is similar to inclusion in a trait. The inherited class becomes a subtype of the original class.
-```erg
+```python
NewInt = Inherit Int
NewInt.
plus1 self = self + 1
@@ -16,7 +16,7 @@ If you want the newly defined class to be inheritable, you must give it the `Inh
You can specify an optional argument `additional` to allow the class to have additional instance attributes, but only if the class is a value class. However, you cannot add instance attributes if the class is a value class.
-```erg
+```python
@Inheritable
Person = Class {name = Str}
Student = Inherit Person, additional: {id = Int}
@@ -34,7 +34,7 @@ Erg is exceptionally designed not to allow inheritance of type ``Never``. Erg is
[Or type](./13_algebraic.md) can also be inherited. In this case, you can remove any of the choices (multiple choices are possible with `or`) by specifying the optional argument `Excluding`.
No additional choices can be added. The class to which you add an option is not a subtype of the original class.
-```erg
+```python
Number = Class Int or Float or Complex
Number.abs(self): Float =
match self:
@@ -48,7 +48,7 @@ RealNumber = Inherit Number, Excluding: Complex
Similarly, [refinement type](./12_refinement.md) can also be specified.
-```erg
+```python
Months = Class 0..12
MonthsNot31Days = Inherit Months, Excluding: {1, 3, 5, 7, 8, 10, 12}
@@ -73,7 +73,7 @@ Next, consider the second condition. This is for type consistency. Since the der
Finally, consider the third condition. This condition is unique to Erg and not often found in other object-oriented languages, again for safety. Let's look at what could go wrong if this were not the case.
-```erg
+```python
# Bad example
@Inheritable
Base! = Class {x = Int!}
@@ -94,7 +94,7 @@ In the inherited class `Inherited!`, the `.g!` method is overridden to transfer
Erg has built this rule into the specification.
-```erg
+```python
# OK.
@Inheritable
Base! = Class {x = Int!}
@@ -123,7 +123,7 @@ Although it is not possible to replace traits at inheritance time, there are exa
For example, `Int`, a subtype of `Real` (which implements `Add()`), appears to reimplement `Add()`.
-```erg
+```python
Int = Class ... , Impl := Add() and ...
```
@@ -134,13 +134,13 @@ They are two different traits (`Add` is a [covariate](./advanced/variance.md), s
Erg does not allow intersection, diff, and complement between normal classes.
-```erg
+```python
Int and Str # TypeError: cannot unite classes
```
This rule prevents inheritance from multiple classes, i.e., multiple inheritance.
-```erg
+```python
IntAndStr = Inherit Int and Str # SyntaxError: multiple inheritance of classes is not allowed
```
@@ -161,7 +161,7 @@ The first is an update operation on the inherited source class attribute. It can
Overriding is different from rewriting because it is an operation to override with a more specialized method. Overrides must also be replaced by compatible types.
-```erg
+```python
@Inheritable
Base! = Class {.pub = !Int; pri = !Int}
Base!
@@ -180,7 +180,7 @@ Inherited!
The second is an update operation on the (variable) instance attribute of the inherited source. This is also prohibited. Instance attributes of the base class may only be updated from methods provided by the base class.
Regardless of the visibility of the attribute, it cannot be updated directly. However, they can be read.
-```erg
+```python
@Inheritable
Base! = Class {.pub = !Int; pri = !Int}
Base!
@@ -209,7 +209,7 @@ So, conversely, where should inheritance be used? One indicator is when "semanti
Erg allows the type system to automatically do part of the subtype determination (e.g., Nat, where Int is greater than or equal to 0).
However, for example, it is difficult to create a "string type representing a valid e-mail address" relying solely on Erg's type system. You should probably perform validation on a normal string. Then, we would like to add some kind of "warrant" to the string object that has passed validation. That is the equivalent of downcasting to an inherited class. Downcasting a `Str object` to `ValidMailAddressStr` is a one-to-one correspondence with validating that the string is in the correct email address format.
-```erg
+```python
ValidMailAddressStr = Inherit Str
ValidMailAddressStr.
init s: Str =
@@ -229,7 +229,7 @@ But obviously it is wrong to apply a `Dog` type object. So we will use the `Pers
This way, only `Person` objects, classes that inherit from them, and `Student` objects will be accepted as arguments.
This is more conservative and avoids unnecessarily assuming too much responsibility.
-```erg
+```python
Named = {name = Str; ...}
Dog = Class {name = Str; breed = Str}
Person = Class {name = Str}
diff --git a/doc/EN/syntax/type/06_nst_vs_sst.md b/doc/EN/syntax/type/06_nst_vs_sst.md
index 8cc422cc..2738cf7f 100644
--- a/doc/EN/syntax/type/06_nst_vs_sst.md
+++ b/doc/EN/syntax/type/06_nst_vs_sst.md
@@ -1,6 +1,6 @@
# Nominal Subtyping vs. Structural Subtyping
-```erg
+```python
Months = 0..12
# NST
diff --git a/doc/EN/syntax/type/07_patch.md b/doc/EN/syntax/type/07_patch.md
index 79795524..80c0b8eb 100644
--- a/doc/EN/syntax/type/07_patch.md
+++ b/doc/EN/syntax/type/07_patch.md
@@ -4,7 +4,7 @@ Erg does not allow modification of existing types and classes.
This means, it is not possible to define additional methods in a class, nor to perform specialization (a language feature that monomorphizes a polymorphically declared type and defines a dedicated method, as in C++).
However, there are many situations where you may want to add feature to an existing type or class, and there is a function called "patching" that allows you to do this.
-```erg
+```python
StrReverse = Patch Str
StrReverse.
reverse self = self.iter().rev().collect(Str)
@@ -18,7 +18,7 @@ In fact, built-in method `.reverse` is not a method of `Str`, but a method added
However, patch methods have lower precedence than methods of the nominal type (class/trait) and cannot override methods of existing types.
-```erg
+```python
StrangeInt = Patch Int
StrangeInt.
`_+_` = Int.`_-_` # AssignError: . `_+_` is already defined in Int
@@ -28,7 +28,7 @@ If you want to override, you must inherit from the class.
However, it is basically recommended not to override and to define a method with a different name.
Overriding is not very easy to do because of some safety restrictions.
-```erg
+```python
StrangeInt = Inherit Int
StrangeInt.
# Overriding methods must be given Override decorators.
@@ -41,7 +41,7 @@ StrangeInt.
Patches can be defined for a single type, and can be grouped together.
-```erg
+```python
# foo.er
StrReverse = Patch(Str)
@@ -61,7 +61,7 @@ StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKeba
StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase
```
-```erg
+```python
{StrBoosterPack; ...} = import "foo"
assert "abc".reverse() == "cba"
@@ -72,7 +72,7 @@ assert "to kebab case".to_kebab_case() == "to-kebab-case"
If multiple patches are defined, some of them may result in duplicate implementations.
-```erg
+```python
# foo.er
StrReverse = Patch(Str)
@@ -88,13 +88,13 @@ StrReverseMk2.
In such a case, you can make it unique by using the __related function__ form instead of the method form.
-```erg
+```python
assert StrReverseMk2.reverse("hello") == "olleh"
```
You can also make it unique by selectively importing.
-```erg
+```python
{StrReverseMk2; ...} = import "foo"
assert "hello".reverse() == "olleh"
@@ -106,7 +106,7 @@ Patches can also relate types to each other. The `StrReverse` patch relates `Str
Such a patch is called a __glue patch__.
Because `Str` is a built-in type, a glue patch is necessary for users to retrofit traits.
-```erg
+```python
Reverse = Trait {
.reverse = Self.() -> Self
}
@@ -121,7 +121,7 @@ Only one glue patch can be defined per type/trait pair.
This is because if multiple glue patches were "visible" at the same time, it would not be possible to uniquely determine which implementation to choose.
However, you can swap patches when moving to another scope (module).
-```erg
+```python
NumericStr = Inherit Str
NumericStr.
...
@@ -152,7 +152,7 @@ impl Reverse for String {
You could say that Rust's traits are features of Erg's traits and patches. This makes Rust's traits sound more convenient, but that is not necessarily the case.
-```erg
+```python
# Erg
Reverse = Trait {
.reverse = Self.() -> Self
@@ -167,7 +167,7 @@ StrReverse.
Because the `impl` block is objectized as a patch in Erg, selective inclusion is possible when importing from other modules. As a side-effect, it also allows implementation of external traits to external structures.
Also, syntaxes such as `dyn trait` and `impl trait` are no longer required by the structure type.
-```erg
+```python
# Erg
reversible: [Reverse; 2] = [[1, 2, 3], "hello"]
@@ -189,7 +189,7 @@ A patch can be defined not only for one specific type, but also for "function ty
In this case, the term to which the degree of freedom is to be given is given as an argument (in the case below, `T: Type`). A patch defined in this way is called an all-symmetric patch.
As you can see, an all-symmetric patch is precisely a function that returns a patch, but it can also be considered a patch in its own right.
-```erg
+```python
FnType T: Type = Patch(T -> T)
FnType(T).
type = T
@@ -204,7 +204,7 @@ However, this has a lower priority than nominal patches and class methods.
Careful design should be used when defining structural patches, as some properties are lost by extension, such as the following.
-```erg
+```python
# This should not be `Structural`
Norm = Structural Patch {x = Int; y = Int}
Norm.
diff --git a/doc/EN/syntax/type/08_value.md b/doc/EN/syntax/type/08_value.md
index 21db678b..9f0bf89c 100644
--- a/doc/EN/syntax/type/08_value.md
+++ b/doc/EN/syntax/type/08_value.md
@@ -2,7 +2,7 @@
Value types are Erg built-in types that can be evaluated at compile time, specifically:
-``` erg
+```python
Value = (
Int
or Nat
@@ -23,7 +23,7 @@ Value = (
Value-type objects, constants, and compile-time subroutines applied to them are called __constant expressions__.
-``` erg
+```python
1, 1.0, 1+2im, True, None, "aaa", [1, 2, 3], Fib(12)
```
diff --git a/doc/EN/syntax/type/10_interval.md b/doc/EN/syntax/type/10_interval.md
index 4c71ed4f..3d48f0b1 100644
--- a/doc/EN/syntax/type/10_interval.md
+++ b/doc/EN/syntax/type/10_interval.md
@@ -2,7 +2,7 @@
The most basic use of `Range` objects is as iterator.
-```erg
+```python
for! 0..9, i =>
print! i
```
@@ -11,7 +11,7 @@ Note that unlike Python, it includes a end number.
However, this is not only use for the `Range` objects. It can also be used the type. Such a type is called the Interval type.
-```erg
+```python
i: 0..10 = 2
```
@@ -20,7 +20,7 @@ The `Nat` type is equivalent to `0.. ExtraStatus, and elements of Status can use methods of ExtraStatus.
Status = Trait {"Ok", "Error"}
# ...
@@ -65,7 +65,7 @@ Methods can also be added by patching.
Use the `or` operator to explicitly indicate inclusion or to add a choice to an existing Enum type.
-```erg
+```python
ExtraStatus = Status or {"Unknown"}
```
@@ -75,7 +75,7 @@ By default, a class whose requirement type is an homogeneous enumerated type can
If you do not wish to do so, you can make it a wrapper class.
-```erg
+```python
Abc = Class {"A", "B", "C"}
Abc.new("A").is_uppercase()
diff --git a/doc/EN/syntax/type/12_refinement.md b/doc/EN/syntax/type/12_refinement.md
index 2aac3db8..f8df698d 100644
--- a/doc/EN/syntax/type/12_refinement.md
+++ b/doc/EN/syntax/type/12_refinement.md
@@ -5,7 +5,7 @@ Refinement type is a type constrained by a predicate expression. Enumeration typ
The standard form of a refinement type is `{Elem: Type | (Pred)*}`. This means that the type is a type whose elements are `Elem` satisfying `Pred`.
The type that can be used for the sifting type is [Const type](./advanced/const.md) only.
-```erg
+```python
Nat = 0.. _
Odd = {N: Int | N % 2 == 1}
Char = StrWithLen 1
@@ -22,7 +22,7 @@ It is called a refinement type because it is a type whose elements are part of a
The `Pred` is called a (left-hand side) predicate expression. Like assignment expressions, it does not return a meaningful value, and only a pattern can be placed on the left-hand side.
That is, expressions such as `X**2 - 5X + 6 == 0` cannot be used as refinement-type predicate expressions. In this respect, it differs from a right-hand-side predicate expression.
-```erg
+```python
{X: Int | X**2 - 5X + 6 == 0} # SyntaxError: the predicate form is invalid. Only names can be on the left-hand side
```
@@ -34,14 +34,14 @@ However, the Erg compiler has very little knowledge of algebra, so it cannot sol
It's nice that you defined `Odd`, but as it is, it doesn't look like it can be used much outside of literals. To promote an odd number in a normal `Int` object to `Odd`, i.e., to downcast an `Int` to `Odd`, you need to pass the constructor of `Odd`.
For refinement types, the normal constructor `.new` may panic, and there is an auxiliary constructor called `.try_new` that returns a `Result` type.
-```erg
+```python
i = Odd.new (0..10).sample!()
i: Odd # or Panic
```
It can also be used as a type specification in `match`.
-```erg
+```python
# i: 0..10
i = (0..10).sample!
match i:
@@ -58,7 +58,7 @@ However, Erg cannot currently make sub-decisions such as `Even` because it was n
The enumerative/interval types introduced before are syntax sugar of the refinement type.
`{a, b, ...}` is `{I: Typeof(a) | I == a or I == b or ... }`, and `a..b` is desugarized to `{I: Typeof(a) | I >= a and I <= b}`.
-```erg
+```python
{1, 2} == {I: Int | I == 1 or I == 2}
1..10 == {I: Int | I >= 1 and I <= 10}
1... <10 == {I: Int | I >= 1 and I < 10}
@@ -68,7 +68,7 @@ The enumerative/interval types introduced before are syntax sugar of the refinem
Just as `_: {X}` can be rewritten as `X` (constant pattern), `_: {X: T | Pred}` can be rewritten as `X: T | Pred`.
-```erg
+```python
# method `.m` is defined for arrays of length 3 or greater
Array(T, N | N >= 3)
.m(&self) = ...
diff --git a/doc/EN/syntax/type/13_algebraic.md b/doc/EN/syntax/type/13_algebraic.md
index f910147a..042d6607 100644
--- a/doc/EN/syntax/type/13_algebraic.md
+++ b/doc/EN/syntax/type/13_algebraic.md
@@ -9,8 +9,7 @@ Normal classes can only perform Union, and other operations will result in a typ
Union types can give multiple possibilities for types. As the name suggests, they are generated by the `or` operator.
A typical Union is the `Option` type. The `Option` type is a `T or NoneType` patch type, primarily representing values that may fail.
-
-```erg
+```python
IntOrStr = Int or Str
assert dict.get("some key") in (Int or NoneType)
@@ -22,7 +21,7 @@ Option T = T or NoneType
Intersection types are got by combining types with the `and` operation.
-```erg
+```python
Num = Add and Sub and Mul and Eq
```
@@ -33,7 +32,7 @@ As mentioned above, normal classes cannot be combined with the `and` operation.
Diff types are got by `not` operation.
It is better to use `and not` as a closer notation to English text, but it is recommended to use just `not` because it fits better alongside `and` and `or`.
-```erg
+```python
CompleteNum = Add and Sub and Mul and Div and Eq and Ord
Num = CompleteNum not Div not Ord
@@ -47,7 +46,7 @@ Complement types is got by the `not` operation, which is a unary operation. The
Intersection with type `not T` is equivalent to Diff, and Diff with type `not T` is equivalent to Intersection.
However, this way of writing is not recommended.
-```erg
+```python
# the simplest definition of the non-zero number type
NonZero = Not {0}
# deprecated styles
@@ -61,7 +60,7 @@ There are two algebraic types: apparent algebraic types that can be simplified a
The "apparent algebraic types" include `or` and `and` of Enum, Interval, and the Record types.
These are not true algebraic types because they are simplified, and using them as type specifiers will result in a Warning; to eliminate the Warning, you must either simplify them or define their types.
-```erg
+```python
assert {1, 2, 3} or {2, 3} == {1, 2, 3}
assert {1, 2, 3} and {2, 3} == {2, 3}
assert -2..-1 or 1..2 == {-2, -1, 1, 2}
@@ -77,7 +76,7 @@ q: Point2D = {x = 1; y = 2; z = 3}
True algebraic types include the types `Or` and `And`. Classes such as `or` between classes are of type `Or`.
-```erg
+```python
assert Int or Str == Or(Int, Str)
assert Int and Marker == And(Int, Marker)
```
diff --git a/doc/EN/syntax/type/14_dependent.md b/doc/EN/syntax/type/14_dependent.md
index 3108fd7c..4871c095 100644
--- a/doc/EN/syntax/type/14_dependent.md
+++ b/doc/EN/syntax/type/14_dependent.md
@@ -1,37 +1,37 @@
-# Dependent Types
+# dependent type
-Dependent types are one of the most important features of Erg.
-Dependent types are types that take values as arguments. Normal polymorphic types can take only types as arguments, but dependent types loosen that restriction.
+Dependent types are a feature that can be said to be the biggest feature of Erg.
+A dependent type is a type that takes a value as an argument. Ordinary polymorphic types can take only types as arguments, but dependent types relax that restriction.
-Dependent types, such as `[T; N]`(`Array(T, N)`), are equivalent.
-This type depends not only on the type `T` of the contents, but also on the number `N` of the contents. `N` contains objects of type `Nat`.
+Dependent types are equivalent to `[T; N]` (`Array(T, N)`).
+This type is determined not only by the content type `T` but also by the number of contents `N`. `N` contains an object of type `Nat`.
-```erg
-a1 = [1, 2, 3].
-assert a1 in [Nat; 3].
+```python
+a1 = [1, 2, 3]
+assert a1 in [Nat; 3]
a2 = [4, 5, 6, 7]
-assert a1 in [Nat; 4].
-assert a1 + a2 in [Nat; 7].
+assert a1 in [Nat; 4]
+assert a1 + a2 in [Nat; 7]
```
-If the type object passed as a function argument is related to a return type, write the following
+If the type object passed in the function argument is related to the return type, write:
-```erg
+```python
narray: |N: Nat| {N} -> [{N}; N]
narray(N: Nat): [N; N] = [N; N]
-assert narray(3) == [3, 3, 3].
+assert array(3) == [3, 3, 3]
```
When defining a dependent type, all type arguments must be constants.
-Dependent types already exist in some languages, but Erg has the unique feature of allowing you to define procedural methods on dependent types.
+Dependent types themselves exist in existing languages, but Erg has the feature of defining procedural methods on dependent types.
-```erg
-x = 1
+```python
+x=1
f x =
print! f::x, module::x
-# Phantom types have an attribute called Phantom that has the same value as the type argument
+# The Phantom type has an attribute called Phantom whose value is the same as the type argument
T X: Int = Class Impl := Phantom X
T(X).
x self = self::Phantom
@@ -39,36 +39,36 @@ T(X).
T(1).x() # 1
```
-Type arguments of variable-dependent types can be transitioned by applying methods.
-Transitions are specified with `~>`.
+Type arguments of mutable dependent types can be transitioned by method application.
+Transition specification is done with `~>`.
-```erg
-# Note that `Id` is an immutable type and cannot be transitioned.
-VM!(State: {"stopped", "running"}! := _, Id: Nat := _) = Class(... State).
+```python
+# Note that `Id` is an immutable type and cannot be transitioned
+VM!(State: {"stopped", "running"}! := _, Id: Nat := _) = Class(..., Impl := Phantom! State)
VM!().
# Variables that do not change can be omitted by passing `_`.
start! ref! self("stopped" ~> "running") =
- self.initialize_something!
+ self.initialize_something!()
self::set_phantom!("running")
-# You can also cut out each type argument (only within the defined module)
-VM!.new() = VM!(!" stopped", 1).new()
-VM!("running" ~> "running").stop! ref! self =
+# You can also cut out by type argument (only in the module where it's defined)
+VM!.new() = VM!(!"stopped", 1).new()
+VM!("running" ~> "running").stop!ref!self =
self.close_something!()
- self::set_phantom!("stopped"))
+ self::set_phantom!("stopped")
vm = VM!.new()
vm.start!()
vm.stop!()
-vm.stop!() # TypeError: VM! stopped", 1) doesn't have .stop!
-# TypeError: VM! running", 1) has .stop!
+vm.stop!() # TypeError: VM!(!"stopped", 1) doesn't have .stop!()
+# hint: VM!(!"running", 1) has .stop!()
```
-You can also create dependent types by incorporating or inheriting from existing types.
+You can also embed or inherit existing types to create dependent types.
-```erg
-MyArray(T, N) = Inherit [T; N].
+```python
+MyArray(T, N) = Inherit[T; N]
-# type of self: Self(T, N) in conjunction with .array!
+# The type of self: Self(T, N) changes in conjunction with .array
MyStruct!(T, N: Nat!) = Class {.array: [T; !N]}
-```
+```
\ No newline at end of file
diff --git a/doc/EN/syntax/type/15_quantified.md b/doc/EN/syntax/type/15_quantified.md
index 368aaaf5..9c76157a 100644
--- a/doc/EN/syntax/type/15_quantified.md
+++ b/doc/EN/syntax/type/15_quantified.md
@@ -3,14 +3,14 @@
A type variable is a variable used, for example, to specify the type of subroutine arguments, and its type is arbitrary (not monomorphic).
First, as motivation for introducing type variables, consider the `id` function, which returns input as is.
-```erg
+```python
id x: Int = x
```
The `id` function that returns the input as is is defined for the type `Int`, but this function can obviously be defined for any type.
Let's use `Object` for the largest class.
-```erg
+```python
id x: Object = x
i = id 1
@@ -21,7 +21,7 @@ b = id True
Sure, it now accepts arbitrary types, but there is one problem: the return type is expanded to `Object`. The return type is expanded to `Object`.
I would like to see the return type `Int` if the input is of type `Int`, and `Str` if it is of type `Str`.
-```erg
+```python
print! id 1 #
id(1) + 1 # TypeError: cannot add `Object` and `Int
```
@@ -29,7 +29,7 @@ id(1) + 1 # TypeError: cannot add `Object` and `Int
To ensure that the type of the input is the same as the type of the return value, use a __type variable__.
Type variables are declared in `||`(type variable list).
-```erg
+```python
id|T: Type| x: T = x
assert id(1) == 1
assert id("foo") == "foo"
@@ -39,7 +39,7 @@ assert id(True) == True
This is called the __universal quantification (universalization)__ of the function. There are minor differences, but it corresponds to the function called generics in other languages. A universalized function is called a __polymorphic function__.
Defining a polymorphic function is like defining a function of the same form for all types (Erg prohibits overloading, so the code below cannot really be written).
-```erg
+```python
id|T: Type| x: T = x
# pseudo code
id x: Int = x
@@ -56,7 +56,7 @@ You can also omit `|T, N| foo: [T; N]` if it can be inferred to be other than a
You can also provide constraints if the type is too large for an arbitrary type.
Constraints also have advantages, for example, a subtype specification allows certain methods to be used.
-```erg
+```python
# T <: Add
# => T is a subclass of Add
# => can do addition
@@ -68,7 +68,7 @@ In this case, `T` is satisfied by `Int`, `Ratio`, etc. So, the addition of `Int`
You can also type it like this.
-```erg
+```python
f|
Y, Z: Type
X <: Add Y, O1
@@ -80,7 +80,7 @@ f|
If the annotation list is long, you may want to pre-declare it.
-```erg
+```python
f: |Y, Z: Type, X <: Add(Y, O1), O1 <: Add(Z, O2), O2 <: Add(X, O3)| (X, Y, Z) -> O3
f|X, Y, Z| x: X, y: Y, z: Z =
x + y + z + x
@@ -90,7 +90,7 @@ Unlike many languages with generics, all declared type variables must be used ei
This is a requirement from Erg's language design that all type variables are inferrable from real arguments.
So information that cannot be inferred, such as the return type, is passed from real arguments; Erg allows types to be passed from real arguments.
-```erg
+```python
Iterator T = Trait {
# Passing return types from arguments.
# .collect: |K: Type -> Type| Self(T). ({K}) -> K(T)
@@ -104,7 +104,7 @@ it.collect(Array) # [2, 3, 4].
Type variables can only be declared during `||`. However, once declared, they can be used anywhere until they exit scope.
-```erg
+```python
f|X|(x: X): () =
y: X = x.clone()
log X.__name__
@@ -117,14 +117,14 @@ f 1
You can also explicitly monophasize at the time of use as follows
-```erg
+```python
f: Int -> Int = id|Int|
```
In that case, the specified type takes precedence over the type of the actual argument (failure to match will result in a type error that the type of the actual argument is wrong).
That is, if the actual object passed can be converted to the specified type, it will be converted; otherwise, a compile error will result.
-```erg
+```python
assert id(1) == 1
assert id|Int|(1) in Int
assert id|Ratio|(1) in Ratio
@@ -135,14 +135,14 @@ id|Int|("str") # TypeError: id|Int| is type `Int -> Int` but got Str
When this syntax is batting against comprehensions, you need to enclose it in `()`.
-```erg
+```python
# {id|Int| x | x <- 1..10} would be interpreted as {id | ...} will be interpreted as.
{(id|Int| x) | x <- 1..10}
```
A type variable cannot be declared with the same name as a type that already exists. This is because all type variables are constants.
-```erg
+```python
I: Type
# ↓ invalid type variable, already exists
f|I: Type| ... = ...
@@ -152,7 +152,7 @@ f|I: Type| ... = ...
Type arguments on the left-hand side are treated as bound variables by default.
-```erg
+```python
K(T: Type, N: Nat) = ...
K(T, N).
foo(x) = ...
@@ -160,7 +160,7 @@ K(T, N).
Using another type variable name will result in a warning.
-```erg
+```python
K(T: Type, N: Nat) = ...
K(U, M). # Warning: K's type variable names are 'T' and 'N'
foo(x) = ...
@@ -168,7 +168,7 @@ K(U, M). # Warning: K's type variable names are 'T' and 'N'
Constants are the same in all namespaces since their definition, so of course they cannot be used for type variable names.
-```erg
+```python
N = 1
K(N: Nat) = ... # NameError: N is already defined
@@ -183,7 +183,7 @@ L(M).
You cannot have multiple definitions for each type argument, but you can define methods with the same name because there is no relationship between dependent types that are not assigned type arguments (non-primitive-kind) and dependent types that are assigned (primitive-kind).
-```erg
+```python
K(I: Int) = ...
K.
# K is not a true type (atomic Kind), so we cannot define a method
@@ -197,7 +197,7 @@ K(0).
The `id` function defined in the previous section is a function that can be of any type. So what is the type of the `id` function itself?
-```erg
+```python
print! classof(id) # |T: Type| T -> T
```
@@ -207,7 +207,7 @@ There is a restriction on the closed universal quantified type: only subroutine
Like anonymous functions, polymorphic types have arbitrary type variable names, but they all have the same value.
-```erg
+```python
assert (|T: Type| T -> T) == (|U: Type| U -> U)
```
@@ -222,14 +222,14 @@ In contrast, a type in which type variables are defined and used on the right-ha
An open universal type is a supertype of all isomorphic "true" types. In contrast, a closed universal type is a subtype of all isomorphic true types.
-```erg
+```python
(|T: Type| T -> T) < (Int -> Int) < (T -> T)
```
You may remember that closed ones are smaller/open ones are larger.
But why is this so? For a better understanding, let's consider an instance of each.
-```erg
+```python
# id: |T: Type| T -> T
id|T|(x: T): T = x
@@ -265,7 +265,7 @@ The important point is that there are no type arguments in the closed, polymorph
In Erg, the type itself is also a value, so types that take arguments, such as function types, will probably be dependent types. In other words, polymorphic function types are both a quantified type and a dependent type.
-```erg
+```python
PolyFn = Patch(|T| T -> T)
PolyFn.
type self = T # NameError: cannot find 'T'
diff --git a/doc/EN/syntax/type/16_subtyping.md b/doc/EN/syntax/type/16_subtyping.md
index e5ed7cf9..ca71245c 100644
--- a/doc/EN/syntax/type/16_subtyping.md
+++ b/doc/EN/syntax/type/16_subtyping.md
@@ -2,7 +2,7 @@
In Erg, class inclusion can be determined with the comparison operators `<`, `>`.
-```erg
+```python
Nat < Int
Int < Object
1... _ < Nat
@@ -13,7 +13,7 @@ Int < Object
Note that this has a different meaning than the `<:` operator. It declares that the class on the left-hand side is a subtype of the type on the right-hand side, and is meaningful only at compile-time.
-```erg
+```python
C <: T # T: StructuralType
f|D <: E| ...
@@ -26,7 +26,7 @@ You can also specify `Self <: Add` for a polymorphic subtype specification, for
Structural types are types for structural typing and are considered to be the same object if they have the same structure.
-```erg
+```python
T = Structural {i = Int}
U = Structural {i = Int}
@@ -38,7 +38,7 @@ assert t in U
In contrast, classes are types for notational typing and cannot be compared structurally to types and instances.
-```erg
+```python
C = Class {i = Int}
D = Class {i = Int}
@@ -54,7 +54,7 @@ Arguments and return values of subroutines take only a single class.
In other words, you cannot directly specify a structural type or a trait as the type of a function.
It must be specified as "a single class that is a subtype of that type" using the partial type specification.
-```erg
+```python
# OK
f1 x, y: Int = x + y
# NG
@@ -68,7 +68,7 @@ Type inference in subroutines also follows this rule. When a variable in a subro
## Class upcasting
-```erg
+```python
i: Int
i as (Int or Str)
i as (1..10)
diff --git a/doc/EN/syntax/type/17_type_casting.md b/doc/EN/syntax/type/17_type_casting.md
index 65ef9207..f1465b5c 100644
--- a/doc/EN/syntax/type/17_type_casting.md
+++ b/doc/EN/syntax/type/17_type_casting.md
@@ -8,7 +8,7 @@ A simple example is `1 + 2.0`: the `+`(Int, Ratio), or Int(<: Add(Ratio, Ratio))
~~The Erg extended bytecode adds type information to BINARY_ADD, in which case the type information is Ratio-Ratio. In this case, the BINARY_ADD instruction does the casting of Int, so no special instruction specifying the cast is inserted. So, for example, even if you override a method in a child class, if you specify the parent as the type, type coercion is performed and the method is executed in the parent's method (name modification is performed at compile time to refer to the parent's method). The compiler only performs type coercion validation and name modification. The runtime does not cast objects (currently. Cast instructions may be implemented for execution optimization). ~~
-```erg
+```python
@Inheritable
Parent = Class()
Parent.
@@ -31,7 +31,7 @@ child # "Hello from Parent"
This behavior does not create an incompatibility with Python. In the first place, Python does not specify the type of a variable, so that all variables are typed as type variables, so to speak. Since type variables choose the smallest type they can fit, the same behavior as in Python is achieved if you do not specify a type in Erg.
-```erg
+```python
@Inheritable
Parent = Class()
Parent.
@@ -52,7 +52,7 @@ child # "Hello from Child"
You can also use `.from` and `.into`, which are automatically implemented for types that are inherited from each other.
-```erg
+```python
assert 1 == 1.0
assert Ratio.from(1) == 1.0
assert 1.into() == 1.0
@@ -62,7 +62,7 @@ assert 1.into() == 1.0
Since downcasting is generally unsafe and the conversion method is non-trivial, we instead implement ``TryFrom.try_from``.
-```erg
+```python
IntTryFromFloat = Patch Int
IntTryFromFloat.
try_from r: Float =
diff --git a/doc/EN/syntax/type/18_mut.md b/doc/EN/syntax/type/18_mut.md
index e6a9c083..137e1954 100644
--- a/doc/EN/syntax/type/18_mut.md
+++ b/doc/EN/syntax/type/18_mut.md
@@ -1,79 +1,79 @@
# Mutable Type
-> __Warning__: The information in this section is out of date and contains some errors.
+> __Warning__: The information in this section is old and contains some errors.
-In Erg, by default, all types are immutable, i.e., their internal state cannot be updated.
-However, variable types can of course be defined. Variable types are declared with `!`.
+By default all types in Erg are immutable, i.e. their internal state cannot be updated.
+But you can of course also define mutable types. Variable types are declared with `!`.
-```erg
+```python
Person! = Class({name = Str; age = Nat!})
-Person!
+Person!.
greet! ref! self = print! "Hello, my name is {self::name}. I am {self::age}."
- inc_age! ref! self = self::name.update! old -> old + 1
+ inc_age!ref!self = self::name.update!old -> old + 1
```
-To be precise, types whose base type is a variable type or a composite type that contains a variable type must end the type name with `!`! Types without `!` may exist in the same namespace and be treated as separate types.
-In the example above, the `.age` attribute is variable and the `.name` attribute is immutable. If any one attribute is variable, the whole is a variable type.
+To be precise, a type whose base type is a mutable type, or a composite type containing mutable types, must have a `!` at the end of the type name. Types without `!` can exist in the same namespace and are treated as separate types.
+In the example above, the `.age` attribute is mutable and the `.name` attribute is immutable. If even one attribute is mutable, the whole is mutable.
-A variable type can define procedural methods to rewrite instances, but just because it has procedural methods does not necessarily make it a variable type. For example, the array type `[T; N]` implements a `sample!` method that randomly selects elements, but this of course does not make destructive changes to the array.
+Mutable types can define procedural methods that rewrite instances, but having procedural methods does not necessarily make them mutable. For example, the array type `[T; N]` implements a `sample!` method that randomly selects an element, but of course does not destructively modify the array.
-Destructive manipulation of variable type objects is done primarily via the `.update!` method. The `.update!` method is a higher-order procedure that applies the function `f` to `self` to update it.
+Destructive operations on mutable objects are primarily done via the `.update!` method. The `.update!` method is a higher-order procedure that updates `self` by applying the function `f`.
-```erg
+```python
i = !1
i.update! old -> old + 1
assert i == 2
```
-The `.set!` method simply discards the old content and replaces it with the new value. `.set! x = .update! _ -> x`.
+The `.set!` method simply discards the old content and replaces it with the new value. .set!x = .update!_ -> x.
-```erg
+```python
i = !1
i.set! 2
assert i == 2
```
-The `.freeze_map` method invariantizes the value and performs the operation.
+The `.freeze_map` method operates on values unchanged.
-```erg
+```python
a = [1, 2, 3].into [Nat; !3]
x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(Array)
```
-In polymorphic invariant types, the type parameter `T` of a type is implicitly assumed to be an invariant type.
+In a polymorphic immutable type the type argument `T` of the type is implicitly assumed to be immutable.
-```erg
+```python
# ImmutType < Type
-K T: ImmutType = Class ...
-K! T: Type = Class ...
+KT: ImmutType = Class ...
+K!T: Type = Class ...
```
-In the standard library, mutable types `T!` are often based on immutable types `T`. However, `T!` and `T` types have no special linguistic relationship, and may not be constructed as such [1 ](#1) .
+In the standard library, variable `(...)!` types are often based on immutable `(...)` types. However, `T!` and `T` types have no special linguistic relationship, and may not be constructed as such [1 ](#1) .
Note that there are several types of object mutability.
Below we will review the immutable/mutable semantics of the built-in collection types.
-``` erg
+```python
# array type
## immutable types
[T; N] # Cannot perform mutable operations
## mutable types
[T!; N] # can change contents one by one
[T; !N] # variable length, content is immutable but can be modified by adding/deleting elements
-[!T; N] # The content is an immutable object, but it can be replaced with an object whose type has been changed.
-[!T; !N] # type and length can be changed.
-[T!; !N] # contents and length can be changed.
-[T!; N] # contents and type can be changed.
-[T!; !N] # any variable operation can be performed
+[!T; N] # The content is an immutable object, but it can be replaced by a different type (actually replaceable by not changing the type)
+[!T; !N] # type and length can be changed
+[T!; !N] # content and length can be changed
+[!T!; N] # content and type can be changed
+[!T!; !N] # Can perform all sorts of mutable operations
```
-Of course, it is not necessary to memorize and use all of these.
-For variable array types, all you have to do is append `!`, and for practical use, `[T; N]`, `[T!; N]`, `[T; !N]`, and `[T!; !N]` can cover most cases.
+Of course, you don't have to memorize and use all of them.
+For variable array types, just add `!` to the part you want to be variable, and practically `[T; N]`, `[T!; N]`, `[T; !N]`, ` [T!; !N]` can cover most cases.
-These array types are sugar-coated, and the actual types are as follows.
+These array types are syntactic sugar, the actual types are:
-```erg
-# There are actually 4 types.
+```python
+# actually 4 types
[T; N] = Array(T, N)
[T; !N] = Array!(T, !N)
[!T; N] = ArrayWithMutType!(!T, N)
@@ -83,81 +83,81 @@ These array types are sugar-coated, and the actual types are as follows.
[!T!; !N] = ArrayWithMutTypeAndLength!(!T!, !N)
```
-Note that type changeable means this.
+This is what it means to be able to change the type.
-```erg
-a = [1, 2, 3].into [!Nat; 3].
+```python
+a = [1, 2, 3].into [!Nat; 3]
a.map!(_ -> "a")
-a: [!Str; 3].
+a: [!Str; 3]
```
The same is true for other collection types.
-```erg
-## tuple types
+```python
+# tuple type
## immutable types
-(T, U) ## immutable types: number of elements, contents unchangeable
+(T, U) # No change in number of elements, contents cannot be changed
## mutable types
-(T!, U) # number of elements immutable, first element can be changed
-(T, U)! # number of elements invariant, contents can be replaced
+(T!, U) # constant number of elements, first element can be changed
+(T, U)! # No change in number of elements, content can be replaced
...
```
-```erg
-## set types
+```python
+# Set type
## immutable types
-{T; N} ## number of immutable elements, contents cannot be changed
+{T; N} # number of immutable elements, contents cannot be changed
## mutable types
-{T!; N} ## number of immutable types, contents can be changed (one by one)
-{T; N}! ## variable number of elements, contents are unchangeable, but can be changed by adding or deleting elements, and the type inside can be changed.
-{T!; N}! # variable number of elements, contents can be changed
+{T!; N} # number of immutable elements, content can be changed (one by one)
+{T; N}! # Number of variable elements, content cannot be changed
+{T!; N}! # Number of variable elements, content can be changed
...
```
-```erg
-# dictionary types.
+```python
+# Dictionary type
## immutable types
-{K: V} ## invariant length, contents cannot be changed
+{K: V} # immutable length, contents cannot be changed
## mutable types
-{K: V!} ## invariant length, can change values (one by one)
-{K: V}! ## variable length, cannot change content, but can add/delete elements, can change type inside
+{K: V!} # constant length, values can be changed (one by one)
+{K: V}! # Variable length, content cannot be changed, but can be added or deleted by adding or removing elements, content type can also be changed
...
```
-```erg
-# Record type.
+```python
+# Record type
## immutable types
-{x = Int; y = Str} ## cannot change content
+{x = Int; y = Str} # content cannot be changed
## mutable types
-{x = Int!; y = Str} # The value of x can be changed
-{x = Int; y = Str}! ## can replace any instance of {x = Int; y = Str}!
+{x = Int!; y = Str} # can change the value of x
+{x = Int; y = Str}! # replace any instance of {x = Int; y = Str}
...
```
-If `T = (...)` and simply `T! = (...)!`, The type `(...)` is called a simple structural type. A simple structural type can also be said to be a type that (semantically) has no internal structure.
-Arrays, tuples, sets, dictionaries, and record types are not all simple structure types, but Int and sieve types are.
+A type `(...)` that simply becomes `T! = (...)!` when `T = (...)` is called a simple structured type. A simple structured type can also be said (semantically) to be a type that has no internal structure.
+Arrays, tuples, sets, dictionaries, and record types are all non-simple structured types, but Int and Sieve types are.
-```erg
-## refinement type
-## enumerated types
-{1, 2, 3} # one of 1, 2, 3, cannot change
-{1, 2, 3}! ## any of 1, 2, or 3, can be changed
-## Interval type
-1..12 # one of 1~12, cannot be changed
-1..12! # any of 1~12, can be changed
-## Sieve type (general form)
-{I: Int | I % 2 == 0} # even type, cannot change
+```python
+# Sieve type
+## Enums
+{1, 2, 3} # one of 1, 2, 3, cannot be changed
+{1, 2, 3}! # 1, 2, 3, you can change
+## interval type
+1..12 # 1 to 12, cannot be changed
+1..12! # Any of 1-12, you can change
+## Sieve type (general type)
+{I: Int | I % 2 == 0} # even type, immutable
{I: Int! | I % 2 == 0} # even type, can be changed
-{I: Int | I % 2 == 0}! # exactly the same type as above, but the notation above is recommended
+{I: Int | I % 2 == 0}! # Exactly the same type as above, but the above notation is preferred
```
-From the above explanation, a variable type is not only one that is variable itself, but also one whose internal type is variable.
-Types such as `{x: Int!}` and `[Int!; 3]` are internal variable types in which the inner object is variable and not the instance itself.
+From the above explanation, mutable types include not only those that are themselves mutable, but also those whose internal types are mutable.
+Types such as `{x: Int!}` and `[Int!; 3]` are internal mutable types where the object inside is mutable and the instance itself is not mutable.
-Types that have an internal structure and the type constructor itself is `! In the case of the type `K!(T, U)` with `! Local modifications are also possible.
-However, since it is desirable to keep modification privileges as local as possible, it is better to use `K(T!, U)` when only `T` can be changed.
-And in the case of type `T!`, which has no internal structure, this instance is simply a replaceable `T` box. The type cannot be changed by methods.
+For a type `K!(T, U)` that has internal structure and has a `!` on the type constructor itself, `*self` can change the whole object. Local changes are also possible.
+However, it is desirable to keep the change authority as local as possible, so if only `T` can be changed, it is better to use `K(T!, U)`.
+And for the type `T!` which has no internal structure, this instance is simply a box of `T` which can be swapped. A method cannot change the type.
---
-1 It is intentional that `T!` and `T` types have no special linguistic relationship. It is a design. If there is a relationship, for example, if the `T`/`T!` type exists in the namespace, it will not be possible to introduce the `T!`/`T` type from another module. Also, the mutable type is not uniquely defined for the immutable type. Given the definition `T = (U, V)`, the possible variable subtypes of `T!` are `(U!, V)` and `(U, V!)`. [↩](#f1)
+1 It is intentional that `T!` and `T` types have no special linguistic relationship. It's a design. If there is a relationship, for example, if the `T`/`T!` type exists in the namespace, it will not be possible to introduce the `T!`/`T` type from another module. Also, the mutable type is not uniquely defined for the immutable type. Given the definition `T = (U, V)`, the possible variable subtypes of `T!` are `(U!, V)` and `(U, V!)`. [↩](#f1)
\ No newline at end of file
diff --git a/doc/EN/syntax/type/19_bound.md b/doc/EN/syntax/type/19_bound.md
index 42de3272..c3365d95 100644
--- a/doc/EN/syntax/type/19_bound.md
+++ b/doc/EN/syntax/type/19_bound.md
@@ -1,18 +1,18 @@
# Type Bound
-A type boundary is a condition on the type specification. The guard (guard clause) is the function that makes this possible.
-In addition to function signatures and anonymous function signatures, sieve types can also use this feature.
-The guard is described after the return type.
+Type bounds add conditions to type specifications. A function that realizes this is a guard (guard clause).
+This feature is available for function signatures, anonymous function signatures, as well as sieve types.
+Guards are written after the return type.
-## Predicate Expressions (Predicate)
+## Predicate
-The condition that a variable satisfies can be specified by an expression (predicate) that returns a `Bool`.
-You can use [value object](./08_value.md) and operators. Compile-time functions may be supported in future versions.
+You can specify the condition that the variable satisfies with an expression (predicate expression) that returns `Bool`.
+Only [value objects](./08_value.md) and operators can be used. Compile-time functions may be supported in future versions.
-```erg
+```python
f a: [T; N] | T, N, N > 5 = ...
g a: [T; N | N > 5] | T, N = ...
Odd = {I: Int | I % 2 == 1}
R2Plus = {(L, R) | L, R: Ratio; L > 0 and R > 0}
GeneralizedOdd = {I | U; I <: Div(Nat, U); I % 2 == 0}
-```
+```
\ No newline at end of file
diff --git a/doc/EN/syntax/type/advanced.md b/doc/EN/syntax/type/advanced.md
index 6849961d..1fdeed74 100644
--- a/doc/EN/syntax/type/advanced.md
+++ b/doc/EN/syntax/type/advanced.md
@@ -1,2 +1 @@
-The following sections describe more advanced type systems. Beginners do not need to read the entire section.
-
+In the following, we will discuss more advanced type systems. Beginners do not have to read all the sections.
\ No newline at end of file
diff --git a/doc/EN/syntax/type/advanced/GADTs.md b/doc/EN/syntax/type/advanced/GADTs.md
index f869085e..4d6cc616 100644
--- a/doc/EN/syntax/type/advanced/GADTs.md
+++ b/doc/EN/syntax/type/advanced/GADTs.md
@@ -1,8 +1,8 @@
# Generalized Algebraic Data Types (GADTs)
-Erg can create Generalized Algebraic Data Types (GADTs) by classifying Or (Union) types.
+Erg can create Generalized Algebraic Data Types (GADTs) by classifying Or types.
-```erg
+```python
Nil T = Class(Impl := Phantom T)
Cons T = Class {head = T; rest = List T}, Impl := Unpack
List T: Type = Class(Nil T or Cons T)
@@ -10,7 +10,7 @@ List.
nil|T|() = Self(T).new Nil(T).new()
cons head, rest | T = Self(T).new Cons(T).new(head, rest)
head self = match self:
- {head; ...} : Cons _ -> head
+ {head; ...}: Cons_ -> head
_: Nil -> panic "empty list"
{nil; cons; ...} = List
@@ -18,17 +18,17 @@ print! cons(1, cons(2, nil())).head() # 1
print! nil.head() # RuntimeError: "empty list"
```
-not `List(T).nil() = ...`, but `List.nil|T|() = ...`. This is because the type specification is no longer needed when using it.
+The reason we say `List.nil|T|() = ...` instead of `List(T).nil() = ...` is that we don't need to specify the type when using it.
-```erg
+```python
i = List.nil()
_: List Int = cons 1, i
```
-The `List T` defined here is a GADTs, but it is a naive implementation and does not demonstrate the true value of GADTs.
-For example, the `.head` method above will give a runtime error if the contents are empty, but this check can be done at compile time.
+The `List T` defined here is GADTs, but it's a naive implementation and doesn't show the true value of GADTs.
+For example, the `.head` method above will throw a runtime error if the body is empty, but this check can be done at compile time.
-```erg
+```python
List: (Type, {"Empty", "Nonempty"}) -> Type
List T, "Empty" = Class(Impl := Phantom T)
List T, "Nonempty" = Class {head = T; rest = List(T, _)}, Impl := Unpack
@@ -43,10 +43,10 @@ print! cons(1, cons(2, nil())).head() # 1
print! nil().head() # TypeError
```
-The GADTs example often described is a list whose contents can be judged as empty or not by type, as shown above.
-Erg allows for further refinement, defining a list with length.
+An example of GADTs that is often explained on the street is a list that can judge whether the contents are empty or not by type as above.
+Erg can be further refined to define a list with length.
-```erg
+```python
List: (Type, Nat) -> Type
List T, 0 = Class(Impl := Phantom T)
List T, N = Class {head = T; rest = List(T, N-1)}, Impl := Unpack
@@ -56,11 +56,11 @@ List.
List(_, N | N >= 1).
head {head; ...} = head
List(_, N | N >= 2).
- pair {head = first; rest = {head = second; ...}} = [first, second].
+ pair {head = first; rest = {head = second; ...}} = [first, second]
{nil; cons; ...} = List
-print! cons(1, cons(2, nil)).pair() # [1, 2].
-cons(1, nil).pair() # TypeError
-cons(1, nil).head() # 1
-print! nil.head() # TypeError
-```
+print! cons(1, cons(2, nil)).pair() # [1, 2]
+print! cons(1, nil).pair() # TypeError
+print! cons(1, nil).head() # 1
+print! nil. head() # TypeError
+```
\ No newline at end of file
diff --git a/doc/EN/syntax/type/advanced/_rank2type.md b/doc/EN/syntax/type/advanced/_rank2type.md
new file mode 100644
index 00000000..c46fc43b
--- /dev/null
+++ b/doc/EN/syntax/type/advanced/_rank2type.md
@@ -0,0 +1,142 @@
+# rank-2 polymorphism
+
+> __Warning__: This document is out of date and contains errors in general.
+
+Erg allows you to define functions that accept various types such as `id|T|(x: T): T = x`, ie polycorrelations.
+So, can we define a function that accepts polycorrelations?
+For example, a function like this (note that this definition is erroneous):
+
+```python
+# I want tuple_map(i -> i * 2, (1, "a")) == (2, "aa")
+tuple_map|T|(f: T -> T, tup: (Int, Str)): (Int, Str) = (f(tup.0), f(tup.1))
+```
+
+Note that `1` and `"a"` have different types, so the anonymous function is not monomorphic once. Needs to be single-phased twice.
+Such a function cannot be defined within the scope of the types we have discussed so far. This is because type variables have no notion of scope.
+Let's leave the types for a moment and see the concept of scope at the value level.
+
+```python
+arr = [1, 2, 3]
+arr.map i -> i + 1
+```
+
+`arr` and `i` in the code above are variables in different scopes. Therefore, each life span is different (`i` is shorter).
+
+The types so far have the same lifetime for all type variables. In other words, `T`, `X`, and `Y` must be determined at the same time and remain unchanged thereafter.
+Conversely, if we can think of `T` as a type variable in the "inner scope", we can compose a `tuple_map` function. __Rank 2 type__ was prepared for that purpose.
+
+```python
+# tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str)
+tuple_map f: (|T: Type| T -> T), tup: (Int, Str) = (f(tup.0), f(tup.1))
+assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa")
+```
+
+A type of the form `{(type) | (list of type variables)}` is called a universal type (see [Universal type](./../quantified.md) for details).
+The `id` function we have seen so far is a typical universal function = polycorrelation function.
+
+```python
+id x = x
+id: |T: Type| T -> T
+```
+
+A universal type has special rules for association with the function type constructor `->`, and the semantics of the type are completely different depending on the way of association.
+
+Think about this in terms of simple one-argument functions.
+
+```python
+f1: (T -> T) -> Int | T # a function that takes any function and returns an Int
+f2: (|T: Type| T -> T) -> Int # Function that receives polycorrelation and returns Int
+f3: Int -> (|T: Type| T -> T) # A function that takes an Int and returns a closed universal function
+f4: |T: Type|(Int -> (T -> T)) # Same as above (preferred)
+```
+
+It seems strange that `f1` and `f2` are different, while `f3` and `f4` are the same. Let's actually construct a function of such a type.
+
+```python
+# id: |T: Type| T -> T
+id x = x
+# same type as `f1`
+take_univq_f_and_return_i(_: (|T: Type| T -> T), i: Int): Int = i
+# same type as `f2`
+take_arbit_f_and_return_i|T: Type|(_: T -> T, i: Int): Int = i
+# same type as `f3`
+take_i_and_return_univq_f(_: Int): (|T: Type| T -> T) = id
+# same type as `f4`
+take_i_and_return_arbit_f|T: Type|(_: Int): (T -> T) = id
+```
+
+After applying it, you will notice the difference.
+
+```python
+_ = take_univq_f_and_return_i(x -> x, 1) # OK
+_ = take_univq_f_and_return_i(x: Int -> x, 1) #NG
+_ = take_univq_f_and_return_i(x: Str -> x, 1) # NG
+_ = take_arbit_f_and_return_i(x -> x, 1) # OK
+_ = take_arbit_f_and_return_i(x: Int -> x, 1) # OK
+_ = take_arbit_f_anf_return_i(x: Str -> x, 1) # OK
+
+f: |T| T -> T = take_i_and_return_univq_f(1)
+g: |T| T -> T = take_i_and_return_arbit_f(1)
+assert f == g
+f2: Int -> Int = take_i_and_return_univq_f|Int|(1)
+g2: Int -> Int = take_i_and_return_arbit_f|Int|(1)
+assert f2 == g2
+```
+
+An open polycorrelation function type is specifically called an __arbitrary function type__. Arbitrary function types have an infinite number of possibilities: `Int -> Int`, `Str -> Str`, `Bool -> Bool`, `|T: Type| T -> T`, ... be.
+On the other hand, there is only one closed (returning an object of the same type as the argument) polymorphic type `|T: Type| T -> T`. Such types are specifically called __polymorphic function types__.
+In other words, `f1` can be passed `x: Int -> x+1`, `x: Bool -> not x`, `x -> x`, etc. = `f1` is a polycorrelated number Yes, but you can only pass `x -> x` etc. to `f2` = `f2` is not __a polycorrelation__.
+But the types of functions like `f2` are clearly different from normal types, and we need new concepts to handle them well. That is the "rank" of the type.
+
+Regarding the definition of rank, types that are not quantified, such as `Int`, `Str`, `Bool`, `T`, `Int -> Int`, `Option Int`, etc., are treated as "rank 0".
+
+```python
+# K is a polynomial kind such as Option
+R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0)
+```
+
+Next, types with first-order universal quantification, such as `|T| T -> T`, or types that include them in the return value type are “rank 1”.
+In addition, types with second-order universal quantification (types that have rank 1 types as arguments such as `(|T| T -> T) -> Int`) or types that include them in the return type are called "rank 2 ”.
+The above is repeated to define the “Rank N” type. Also, the rank-N types include all types with a rank of N or less. Therefore, a type with mixed ranks has the same rank as the highest among them.
+
+```python
+R1 = (|...| R0) or (R0 -> R1) or K(R1) or R0
+R2 = (|...| R1) or (R1 -> R2) or K(R2) or R1
+...
+Rn = (|...| Rn-1) or (Rn-1 -> Rn) or K(Rn) or Rn-1
+```
+
+Let's look at some examples.
+
+```python
+ (|T: Type| T -> T) -> (|U: Type| U -> U)
+=> R1 -> R1
+=> R1 -> R2
+=> R2
+
+Option(|T: Type| T -> T)
+=> Option(R1)
+=> K(R1)
+=> R1
+```
+
+By definition, `tuple_map` is a rank-2 type.
+
+```python
+tuple_map:
+ ((|T: Type| T -> T), (Int, Str)) -> (Int, Str)
+=> (R1, R0) -> R0
+=> R1 -> R2
+=> R2
+```
+
+Erg can handle types up to rank 2 (because rank N types include all types with rank N or less, to be exact, all Erg types are rank 2 types). Attempting to construct a function of more types is an error.
+For example, all functions that handle polycorrelations as they are require specification of other argument types. Also, such a function is not configurable.
+
+```python
+# this is a rank-3 type function
+# |X, Y: Type|((|T: Type| T -> T), (X, Y)) -> (X, Y)
+generic_tuple_map|X, Y: Type| f: (|T: Type| T -> T), tup: (X, Y) = (f(tup.0), f(tup.1))
+```
+
+It is known that types with rank 3 or higher are theoretically undecidable by type inference. However, most practical needs can be covered by the rank 2 type.
\ No newline at end of file
diff --git a/doc/EN/syntax/type/advanced/default_param.md b/doc/EN/syntax/type/advanced/default_param.md
index e8108ea6..d7bf81ab 100644
--- a/doc/EN/syntax/type/advanced/default_param.md
+++ b/doc/EN/syntax/type/advanced/default_param.md
@@ -1,8 +1,8 @@
-# Function type with default parameter
+# Function type with default arguments
-First, let's look at an example of the use of default parameters.
+First, let's look at an example of using default arguments.
-```erg
+```python
f: (Int, Int, z := Int) -> Int
f(x, y, z := 0) = x + y + z
@@ -11,18 +11,18 @@ g(x, y, z := 0, w := 1) = x + y + z + w
fold: ((Int, Int) -> Int, [Int], acc := Int) -> Int
fold(f, [], acc) = acc
-fold(f, arr, acc := 0) = fold(f, arr[1...]) , f(acc, arr[0]))
+fold(f, arr, acc := 0) = fold(f, arr[1..], f(acc, arr[0]))
assert fold(f, [1, 2, 3]) == 6
assert fold(g, [1, 2, 3]) == 8
```
-The parameters after `:=` are default parameters.
+Arguments after `:=` are default arguments.
The subtyping rules are as follows.
-```erg
+```python
((X, y := Y) -> Z) <: (X -> Z)
-((X, y := Y, ...) -> Z) -> Z) <: ((X, ...) -> Z)
+((X, y := Y, ...) -> Z) <: ((X, ...) -> Z)
```
-The first means that a function with a default parameter is identical to a function without it.
-The second means that any default parameter can be omitted.
+The first means that a function with default arguments can be identified with a function without.
+The second means that any default argument can be omitted.
\ No newline at end of file
diff --git a/doc/EN/syntax/type/advanced/erasure.md b/doc/EN/syntax/type/advanced/erasure.md
index 94f9e01a..ff485c46 100644
--- a/doc/EN/syntax/type/advanced/erasure.md
+++ b/doc/EN/syntax/type/advanced/erasure.md
@@ -6,7 +6,7 @@ The most common example of a type that has been type-erased is `[T, _]`. Arrays
However, a type that has been type-erased becomes a supertype of a type that has not been (e.g. `[T; N] <: [T; _]`), so it can accept more objects.
Objects of type `[T; N]` can of course use methods of type `[T; _]`, but the `N` information is erased after use. If the length does not change, then it is possible to use `[T; N]` in the signature. If the length remains the same, it must be indicated by a signature.
-```erg
+```python
# Functions that are guaranteed to not change the length of the array (e.g., sort)
f: [T; N] -> [T; N] # functions that do not (f: [T; N])
# functions that do not (e.g. filter)
@@ -16,14 +16,14 @@ g: [T; n] -> [T; _]
If you use `_` in the type specification itself, the type is upcast to `Object`.
For non-type type arguments (Int, Bool, etc.), the parameter with `_` will be undefined.
-```erg
+```python
i: _ # i: Object
[_; _] == [Object; _] == Array
```
Type erasure is not the same as omitting a type specification. Once the type argument information has been erased, it will not be returned unless you assert it again.
-```erg
+```python
implicit = (1..5).iter().map(i -> i * 2).to_arr()
explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat))
```
@@ -36,7 +36,7 @@ let partial = (1..6).iter().map(|i| i * 2).collect::>();
Erg does not allow partial omission of types, but uses higher-order kind polymorphism instead.
-```erg
+```python
# collect is a higher-order Kind method that takes Kind
hk = (1..5).iter().map(i -> i * 2).collect(Array)
hk: Array(Int)
diff --git a/doc/EN/syntax/type/advanced/existential.md b/doc/EN/syntax/type/advanced/existential.md
index 5cc1ef99..34c385fa 100644
--- a/doc/EN/syntax/type/advanced/existential.md
+++ b/doc/EN/syntax/type/advanced/existential.md
@@ -3,7 +3,7 @@
If there is a for-all type corresponding to ∀, it is natural to assume that there is an existential type corresponding to ∃.
Existential types are not difficult. You already know the existential type, just not consciously aware of it as such.
-```erg
+```python
T: Trait
f x: T = ...
```
@@ -11,7 +11,7 @@ f x: T = ...
The trait `T` above is used as the existential type.
In contrast, `T` in the lower case is only a trait, and `X` is an for-all type.
-```erg
+```python
f|X <: T| x: X = ...
```
@@ -19,7 +19,7 @@ In fact, the existential type is replaced by an for-all type. So why is there su
First of all, as we saw above, existential types do not involve type variables, which simplifies type specification.
Also, since the type variable can be removed, it is possible to construct a type that would have rank 2 or higher if it were an all-presumptive type.
-```erg
+```python
show_map f: (|T| T -> T), arr: [Show; _] =
arr.map x ->
y = f x
@@ -30,7 +30,7 @@ show_map f: (|T| T -> T), arr: [Show; _] =
However, as you can see, the existential type forgets or expands the original type, so if you do not want to expand the return type, you must use the for-all type.
Conversely, types that are only taken as arguments and are not relevant to the return value may be written as existential types.
-```erg
+```python
# id(1): I want it to be Int
id|T|(x: T): T = x
# |S <: Show|(s: S) -> () is redundant
diff --git a/doc/EN/syntax/type/advanced/keyword_param.md b/doc/EN/syntax/type/advanced/keyword_param.md
index debadb33..789fbe7e 100644
--- a/doc/EN/syntax/type/advanced/keyword_param.md
+++ b/doc/EN/syntax/type/advanced/keyword_param.md
@@ -1,26 +1,26 @@
# Function type with keyword arguments
-```erg
+```python
h(f) = f(y: 1, x: 2)
h: |T: Type|((y: Int, x: Int) -> T) -> T
```
The subtyping rules for functions with keyword arguments are as follows.
-```erg
+```python
((x: T, y: U) -> V) <: ((T, U) -> V) # x, y are arbitrary keyword parameters
((y: U, x: T) -> V) <: ((x: T, y: U) -> V)
((x: T, y: U) -> V) <: ((y: U, x: T) -> V)
```
-This means that keyword arguments can be eliminated or replaced.
-However, it is not possible to do both at the same time.
-That is, `(x: T, y: U) -> V` cannot be cast to `(U, T) -> V`.
-Note that keyword arguments are only available in top-level tuples, not in arrays or nested tuples.
+This means that keyword arguments can be deleted or replaced.
+But you can't do both at the same time.
+That is, you cannot cast `(x: T, y: U) -> V` to `(U, T) -> V`.
+Note that keyword arguments are attached only to top-level tuples, and not to arrays or nested tuples.
-```erg
+```python
Valid: [T, U] -> V
Invalid: [x: T, y: U] -> V
Valid: (x: T, ys: (U,)) -> V
Invalid: (x: T, ys: (y: U,)) -> V
-```
+```
\ No newline at end of file
diff --git a/doc/EN/syntax/type/advanced/kind.md b/doc/EN/syntax/type/advanced/kind.md
index 9639faf5..a8a9fd77 100644
--- a/doc/EN/syntax/type/advanced/kind.md
+++ b/doc/EN/syntax/type/advanced/kind.md
@@ -9,7 +9,7 @@ Note that `->` itself, which is an anonymous function operator, can also be seen
Also note that a kind that is not an atomic kind is not a type. Just as `-1` is a number but `-` is not, `Option Int` is a type but `Option` is not. `Option` etc. are sometimes called type constructors.
-```erg
+```python
assert not Option in Type
assert Option in Type -> Type
```
@@ -17,7 +17,7 @@ assert Option in Type -> Type
So code like the following will result in an error:
In Erg, methods can only be defined in atomic kinds, and the name `self` cannot be used anywhere other than the first argument of a method.
-```erg
+```python
#K is an unary kind
K: Type -> Type
K T = Class...
@@ -32,7 +32,7 @@ Examples of binary or higher kinds are `{T: U}`(: `(Type, Type) -> Type`), `(T,
There is also a zero-term kind `() -> Type`. This is sometimes equated with an atomic kind in type theory, but is distinguished in Erg. An example is `Class`.
-```erg
+```python
Nil = Class()
```
@@ -40,23 +40,23 @@ Nil = Class()
There is also a partial type relation, or rather a partial kind relation, between multinomial kinds.
-```erg
+```python
K T = ...
L = Inherit K
-L <: K
+L<: K
```
That is, for any `T`, if `L T <: K T`, then `L <: K`, and vice versa.
-```console
+```python
∀T. L T <: K T <=> L <: K
```
-## Higher-order Kind
+## higher kind
There is also a higher-order kind. This is a kind of the same concept as a higher-order function, a kind that receives a kind itself. `(Type -> Type) -> Type` is a higher kind. Let's define an object that belongs to a higher kind.
-```erg
+```python
IntContainerOf K: Type -> Type = K Int
assert IntContainerOf Option == Option Int
assert IntContainerOf Result == Result Int
@@ -65,30 +65,30 @@ assert IntContainerOf in (Type -> Type) -> Type
The bound variables of a polynomial kind are usually denoted as K, L, ..., where K is K for Kind.
-## Set kind
+## set kind
In type theory, there is the concept of a record. This is almost the same as the Erg record [2 ](#2).
-```erg
+```python
# This is a record, and it corresponds to what is called a record in type theory
{x = 1; y = 2}
```
When all record values were types, it was a kind of type called a record type.
-```erg
+```python
assert {x = 1; y = 2} in {x = Int; y = Int}
```
A record type types a record. A good guesser might have thought that there should be a "record kind" to type the record type. Actually it exists.
-```erg
+```python
log Typeof {x = Int; y = Int} # {{x = Int; y = Int}}
```
A type like `{{x = Int; y = Int}}` is a record kind. This is not a special notation. It is simply an enumeration type that has only `{x = Int; y = Int}` as an element.
-```erg
+```python
Point = {x = Int; y = Int}
Pointy = {Point}
```
@@ -96,7 +96,7 @@ Pointy = {Point}
An important property of record kind is that if `T: |T|` and `U <: T` then `U: |T|`.
This is also evident from the fact that enums are actually syntactic sugar for sieve types.
-```erg
+```python
# {c} == {X: T | X == c} for normal objects, but
# Equality may not be defined for types, so |T| == {X | X <: T}
{Point} == {P | P <: Point}
@@ -105,7 +105,7 @@ This is also evident from the fact that enums are actually syntactic sugar for s
`U <: T` in type constraints is actually syntactic sugar for `U: |T|`.
A kind that is a set of such types is commonly called a set kind. Setkind also appears in the Iterator pattern.
-```erg
+```python
Iterable T = Trait {
.Iterator = {Iterator}
.iter = Self(T).() -> Self.Iterator T
@@ -114,7 +114,7 @@ Iterable T = Trait {
## Type inference for polynomial kinds
-```erg
+```python
Container K: Type -> Type, T: Type = Patch K(T, T)
Container (K).
f self = ...
@@ -146,4 +146,4 @@ In this case, patches are selected according to the following priority criteria.
1 In type theory notation, `*=>*` [↩](#f1)
-2 There are subtle differences such as visibility. [↩](#f2)
+2 There are subtle differences such as visibility. [↩](#f2)
\ No newline at end of file
diff --git a/doc/EN/syntax/type/advanced/marker_trait.md b/doc/EN/syntax/type/advanced/marker_trait.md
index 2c3af3f8..bbf90ad4 100644
--- a/doc/EN/syntax/type/advanced/marker_trait.md
+++ b/doc/EN/syntax/type/advanced/marker_trait.md
@@ -1,20 +1,20 @@
# Marker Trait
-A marker trait is a trait with no required attributes. That is, it can be Impl without implementing a method.
-It may seem meaningless without the required attribute, but it registers the information that it belongs to that trait, so that patch methods can be used and the compiler can give it special treatment.
+Marker traits are traits without required attributes. That is, you can Impl without implementing any method.
+It seems meaningless without the required attribute, but since the information that it belongs to the trait is registered, you can use the patch method or get special treatment by the compiler.
-All marker traits are encompassed by the `Marker` trait.
-The `Light` provided in the standard is a kind of marker trait.
+All marker traits are subsumed by the `Marker` trait.
+`Light` provided as standard is a kind of marker trait.
-```erg
+```python
Light = Subsume Marker
```
-```erg
+```python
Person = Class {.name = Str; .age = Nat} and Light
```
-```erg
+```python
M = Subsume Marker
MarkedInt = Inherit Int, Impl := M
@@ -24,8 +24,8 @@ assert i + 1 == 2
assert i in M
```
-The marker class can also be removed with the `Excluding` argument.
+Marker classes can also be excluded with the `Excluding` argument.
-```erg
+```python
NInt = Inherit MarkedInt, Impl := N, Excluding: M
-```
+```
\ No newline at end of file
diff --git a/doc/EN/syntax/type/advanced/mut_struct.md b/doc/EN/syntax/type/advanced/mut_struct.md
index 9fdd8479..b23de3c9 100644
--- a/doc/EN/syntax/type/advanced/mut_struct.md
+++ b/doc/EN/syntax/type/advanced/mut_struct.md
@@ -2,7 +2,7 @@
The ``T!`` type is described as a box type that can be replaced by any ``T`` type object.
-```erg
+```python
Particle!State: {"base", "excited"}! = Class(... Impl := Phantom State)
Particle!
# This method moves the State from "base" to "excited".
@@ -19,7 +19,7 @@ In other words, the length cannot be changed. To change the length, the structur
This is achieved by Mutable structure (mutable) types.
-```erg
+```python
v = [Str; !0].new()
v.push! "Hello"
v: [Str; !1].
@@ -30,7 +30,7 @@ Incidentally, the `[T; !N]` type is the sugar-coated syntax of the `ArrayWithLen
Mutable structure types can of course be user-defined. Note, however, that there are some differences from invariant structure types in terms of the construction method.
-```erg
+```python
Nil T = Class(Impl := Phantom T)
List T, !0 = Inherit Nil T
List T, N: Nat! = Class {head = T; rest = List(T, !N-1)}
diff --git a/doc/EN/syntax/type/advanced/newtype.md b/doc/EN/syntax/type/advanced/newtype.md
index bf08c2a0..96d65399 100644
--- a/doc/EN/syntax/type/advanced/newtype.md
+++ b/doc/EN/syntax/type/advanced/newtype.md
@@ -4,7 +4,7 @@ Here is the Erg version of the newtype pattern commonly used in Rust.
Erg allows type aliases to be defined as follows, but they only refer to the same type.
-```erg
+```python
UserId = Int
```
@@ -14,7 +14,7 @@ Also, for example, when designing a database system, suppose there are several t
The newtype pattern is a good design pattern for such cases.
-```erg
+```python
UserId = Class {id = Nat}
UserId.
new id: Nat =
diff --git a/doc/EN/syntax/type/advanced/overloading.md b/doc/EN/syntax/type/advanced/overloading.md
index 6f621555..99740240 100644
--- a/doc/EN/syntax/type/advanced/overloading.md
+++ b/doc/EN/syntax/type/advanced/overloading.md
@@ -3,7 +3,7 @@
Erg does not support __ad hoc polymorphism__. That is, multiple definitions of functions and Kinds (overloading) are not possible. However, you can reproduce the overloading behavior by using a combination of a trait and a patch.
You can use traits instead of trait classes, but then all types that implement `.add1` will be covered.
-```erg
+```python
Add1 = Trait {
.add1: Self.() -> Self
}
@@ -24,7 +24,7 @@ Such a polymorphism by accepting all subtypes of a type is called __subtyping po
If the process is exactly the same for each type, it can be written as below. The above is used when the behavior changes from class to class (but the return type is the same).
A polymorphism that uses type arguments is called __parametric polymorphism__. Parametric polymorphism is often used in conjunction with subtyping, as shown below, in which case it is a combination of parametric and subtyping polymorphism.
-```erg
+```python
add1|T <: Int or Str| x: T = x + 1
assert add1(1) == 2
assert add1(1.0) == 2.0
@@ -32,7 +32,7 @@ assert add1(1.0) == 2.0
Also, overloading of types with different numbers of arguments can be reproduced with default arguments.
-```erg
+```python
C = Class {.x = Int; .y = Int}
C.
new(x, y := 0) = Self::__new__ {.x; .y}
@@ -47,7 +47,7 @@ In conclusion, Erg prohibits overloading and adopts subtyping plus parametric po
First, overloaded functions are distributed in their definitions. This makes it difficult to report the cause of an error when it occurs.
Also, importing a subroutine may change the behavior of already defined subroutines.
-```erg
+```python
{id; ...} = import "foo"
...
id x: Int = x
@@ -60,7 +60,7 @@ id "str" # TypeError: id is not implemented for Str
Second, it is incompatible with default arguments. When a function with default arguments is overloaded, there is a problem with which one takes precedence.
-```erg
+```python
f x: Int = ...
f(x: Int, y := 0) = ...
@@ -70,7 +70,7 @@ f(1) # which is chosen?
Furthermore, it is incompatible with the declaration.
The declaration `f: Num -> Num` cannot specify which definition it refers to. This is because `Int -> Ratio` and `Ratio -> Int` are not inclusive.
-```erg
+```python
f: Num -> Num
f(x: Int): Ratio = ...
f(x: Ratio): Int = ...
@@ -79,7 +79,7 @@ f(x: Ratio): Int = ...
And the grammar is inconsistent: Erg prohibits variable reassignment, but the overloaded grammar looks like reassignment.
Nor can it be replaced by an anonymous function.
-```erg
+```python
# same as `f = x -> body`
f x = body
diff --git a/doc/EN/syntax/type/advanced/phantom.md b/doc/EN/syntax/type/advanced/phantom.md
index 9abfeade..b36d8b5e 100644
--- a/doc/EN/syntax/type/advanced/phantom.md
+++ b/doc/EN/syntax/type/advanced/phantom.md
@@ -3,7 +3,7 @@
Phantom types are marker traits that exist only to provide annotations to the compiler.
As a usage of phantom types, let's look at the structure of a list.
-```erg
+```python
Nil = Class()
List T, 0 = Inherit Nil
List T, N: Nat = Class {head = T; rest = List(T, N-1)}
@@ -11,7 +11,7 @@ List T, N: Nat = Class {head = T; rest = List(T, N-1)}
This code results in an error.
-```erg
+```python
3 | List T, 0 = Inherit Nil
^^^
TypeConstructionError: since Nil does not have a parameter T, it is not possible to construct List(T, 0) with Nil
@@ -21,7 +21,7 @@ hint: use 'Phantom' trait to consume T
This error is a complaint that `T` cannot be type inferred when `List(_, 0).new Nil.new()` is used.
In such a case, whatever the `T` type is, it must be consumed on the right-hand side. A type of size zero, such as a tuple of length zero, is convenient because it has no runtime overhead.
-```erg
+```python
Nil T = Class((T; 0))
List T, 0 = Inherit Nil T
List T, N: Nat = Class {head = T; rest = List(T, N-1)}
@@ -31,7 +31,7 @@ This code passes compilation. But it's a little tricky to understand the intent,
In such a case, a phantom type is just what you need. A phantom type is a generalized type of size 0.
-```erg
+```python
Nil T = Class(Impl := Phantom T)
List T, 0 = Inherit Nil T
List T, N: Nat = Class {head = T; rest = List(T, N-1)}
@@ -45,7 +45,7 @@ assert nil.__size__ == 0
Also, `Phantom` can consume arbitrary type arguments in addition to its type. In the following example, `Phantom` holds a type argument called `State`, which is a subtype object of `Str`.
Again, `State` is a fake type variable that does not appear in the object's entity.
-```erg
+```python
VM! State: {"stopped", "running"}! = Class(... State)
VM!("stopped").
start ref! self("stopped" ~> "running") =
diff --git a/doc/EN/syntax/type/advanced/projection.md b/doc/EN/syntax/type/advanced/projection.md
index e9ce3ae4..57668930 100644
--- a/doc/EN/syntax/type/advanced/projection.md
+++ b/doc/EN/syntax/type/advanced/projection.md
@@ -2,7 +2,7 @@
A projection type represents a type such as ``Self.AddO`` in the following code.
-```erg
+```python
Add R = Trait {
. `_+_` = Self, R -> Self.AddO
.AddO = Type
@@ -16,7 +16,7 @@ AddForInt.
The type ``Add(R)`` can be said to be a type that defines addition with some object. Since the method should be a type attribute, the `+` type declaration should be written below the indentation.
The mise-en-scène of the `Add` type is the declaration `.AddO = Type`, and the entity of the `.AddO` type, which is a projective type, is held by a type that is a subtype of `Add`. For example, `Int.AddO = Int`, `Odd.AddO = Even`.
-```erg
+```python
assert Int < Add
assert Int.AddO == Int
assert Odd < Add
diff --git a/doc/EN/syntax/type/advanced/quantified_dependent.md b/doc/EN/syntax/type/advanced/quantified_dependent.md
index 28afb5ed..623f206f 100644
--- a/doc/EN/syntax/type/advanced/quantified_dependent.md
+++ b/doc/EN/syntax/type/advanced/quantified_dependent.md
@@ -2,7 +2,7 @@
Erg has quantified and dependent types. Then naturally, it is possible to create a type that combines the two. That is the quantified dependent type.
-```erg
+```python
NonNullStr = |N: Nat| StrWithLen N | N ! = 0 # same as {S | N: Nat; S: StrWithLen N; N ! = 0}
NonEmptyArray = |N: Nat| [_; N | N > 0] # same as {A | N: Nat; A: Array(_, N); N > 0}
```
@@ -11,7 +11,7 @@ The standard form of quantified dependent types are `K(A, ... | Pred)`. ``K`` is
Quantified dependent types as left-hand side values can only define methods in the same module as the original type.
-```erg
+```python
K A: Nat = Class ...
K(A).
...
@@ -21,7 +21,7 @@ K(A | A >= 1).
Quantified dependent types as right-hand side values require that the type variable to be used be declared in the type variable list (`||`).
-```erg
+```python
# T is a concrete type
a: |N: Nat| [T; N | N > 1]
```
diff --git a/doc/EN/syntax/type/advanced/shared.md b/doc/EN/syntax/type/advanced/shared.md
index ccc907ae..69b7cb7e 100644
--- a/doc/EN/syntax/type/advanced/shared.md
+++ b/doc/EN/syntax/type/advanced/shared.md
@@ -21,7 +21,7 @@ The relation `VIPMember[] <: NormalMember[]` is fine for immutable objects. Howe
In Erg, such code is played back due to the ownership system.
-```erg
+```python
NormalMember = Class()
VIPMember = Class()
@@ -35,7 +35,7 @@ log vip_area # OwnershipError: `vip_room` was moved to `normal_room`
However, it can be inconvenient for an object to be owned by only one place.
For this reason, Erg has a type `SharedCell!T!`, which represents a shared state.
-```erg
+```python
$p1 = SharedCell!.new(!1)
$p2 = $p1.mirror!()
$p3 = SharedCell!.new(!1)
@@ -57,7 +57,7 @@ The `SharedCell! T!` type is also a subtype of `T!` and can call methods of type
An important fact is that `SharedCell! T!` is non-variant, i.e., no inclusions are defined for different type arguments.
-```erg
+```python
$vip_area = SharedCell!.new([].into [VIPMember; !_])
$normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError: expected SharedCell!([NormalMember; !_]), but got SharedCell!([VIPMember; !_])
# hint: SharedCell!(T) is non-variant, which means it cannot have a supertype or a subtype.
@@ -65,7 +65,7 @@ $normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError:
However, the following code have not problem. In the last line, it's the `VIPMember` argument that has been typed converted.
-```erg
+```python
$normal_area = SharedCell!.new([].into [NormalMember; !_])
$normal_area.push!(NormalMember.new()) # OK
$normal_area.push!(VIPMember.new()) # OK
diff --git a/doc/EN/syntax/type/advanced/special.md b/doc/EN/syntax/type/advanced/special.md
index 12f164a8..800e37bb 100644
--- a/doc/EN/syntax/type/advanced/special.md
+++ b/doc/EN/syntax/type/advanced/special.md
@@ -1,22 +1,22 @@
-# Special Type(Self, Super)
+# Special types (Self, Super)
-`Self` represents itself types. It can be used simply as an alias, however note that its meaning changes in derived types (it refers to the derived own type).
+`Self` represents its own type. You can just use it as an alias, but note that the meaning changes in derived types (refers to the own type).
-```erg
+```python
@Inheritable
C = Class()
C.
- new_self() = Self.new()
+ new_self() = Self. new()
new_c() = C.new()
D = Inherit C
-classof D.new_self() # D
-classof D.new_c() # C
+classof D. new_self() # D
+classof D. new_c() # C
```
-`Super` represents types of base classes. The method itself refers to the base class, however the instance uses its own type.
+`Super` represents the type of the base class. The method itself refers to the base class, but the instance uses its own type.
-```erg
+```python
@Inheritable
C = Class()
@@ -25,15 +25,15 @@ D.
new_super() = Super.new()
new_c() = C.new()
-classof D.new_super() # D
-classof D.new_c() # C
+classof D. new_super() # D
+classof D. new_c() # C
```
-## Special Type Variable
+## special type variables
-`Self` and `Super` can be used as type variables in structural types and traits. It refers to a class, which is a subtype of that type. That is, `Self` in type `T` means `Self <: T`.
+`Self` and `Super` can be used as type variables in structured types and traits. This refers to classes that are subtypes of that type. That is, `Self` in type `T` means `Self <: T`.
-```erg
+```python
Add R = Trait {
.AddO = Type
.`_+_`: Self, R -> Self.AddO
@@ -48,4 +48,4 @@ assert 1 in Add(Int, Int)
assert 1 in ClosedAdd
assert Int < Add(Int, Int)
assert Int < ClosedAdd
-```
+```
\ No newline at end of file
diff --git a/doc/EN/syntax/type/advanced/typeof.md b/doc/EN/syntax/type/advanced/typeof.md
new file mode 100644
index 00000000..b320d7a0
--- /dev/null
+++ b/doc/EN/syntax/type/advanced/typeof.md
@@ -0,0 +1,65 @@
+# Typeof, classof
+
+`Typeof` is a function that can peek into Erg's type inference system, and its behavior is complex.
+
+```python
+assert Typeof(1) == {I: Int | I == 1}
+i: 1..3 or 5..10 = ...
+assert Typeof(i) == {I: Int | (I >= 1 and I <= 3) or (I >= 5 and I <= 10)}
+
+C = Class {i = Int}
+I = C. new {i = 1}
+assert Typeof(I) == {X: C | X == I}
+J: C = ...
+assert Typeof(J) == {i = Int}
+
+assert {X: C | X == I} < C and C <= {i = Int}
+```
+
+The `Typeof` function returns the derived type, not the class of the object.
+So for instance `I: C` of class `C = Class T`, `Typeof(I) == T`.
+A value class does not have a corresponding record type. To solve this problem, value classes are supposed to be record types that have a `__valueclass_tag__` attribute.
+Note that you cannot access this attribute, nor can you define a `__valueclass_tag__` attribute on a user-defined type.
+
+```python
+i: Int = ...
+assert Typeof(i) == {__valueclass_tag__ = Phantom Int}
+s: Str = ...
+assert Typeof(s) == {__valueclass_tag__ = Phantom Str}
+```
+
+`Typeof` outputs only structured types. I explained that structured types include attribute types, sieve types, and (true) algebraic types.
+These are independent types (inference precedence exists) and inference conflicts do not occur.
+Attribute types and algebraic types can span multiple classes, while sieve types are subtypes of a single class.
+Erg infers object types as sieve types as much as possible, and when that is not possible, expands sieve base classes to structured types (see below).
+
+## structured
+
+All classes can be converted to derived types. This is called __structuring__. The structured type of a class can be obtained with the `Structure` function.
+If a class is defined with `C = Class T` (all classes are defined in this form) then `Structure(C) == T`.
+
+```python
+C = Class {i = Int}
+assert Structure(C) == {i = Int}
+D = Inherit C
+assert Structure(D) == {i = Int}
+Nat = Class {I: Int | I >= 0}
+assert Structure(Nat) == {I: Int | I >= 0}
+Option T = Class (T or NoneType)
+assert Structure(Option Int) == Or(Int, NoneType)
+assert Structure(Option) # TypeError: only monomorphized types can be structured
+# You can't actually define a record with __valueclass_tag__, but conceptually
+assert Structure(Int) == {__valueclass_tag__ = Phantom Int}
+assert Structure(Str) == {__valueclass_tag__ = Phantom Str}
+assert Structure((Nat, Nat)) == {__valueclass_tag__ = Phantom(Tuple(Nat, Nat))}
+assert Structure(Nat -> Nat) == {__valueclass_tag__ = Phantom(Func(Nat, Nat))}
+# Marker classes are also record types with __valueclass_tag__
+M = Inherit Marker
+assert Structure(M) == {__valueclass_tag__ = Phantom M}
+D = Inherit(C and M)
+assert Structure(D) == {i = Int; __valueclass_tag__ = Phantom M}
+E = Inherit(Int and M)
+assert Structure(E) == {__valueclass_tag__ = Phantom(And(Int, M))}
+F = Inherit(E not M)
+assert Structure(F) == {__valueclass_tag__ = Phantom Int}
+```
\ No newline at end of file
diff --git a/doc/EN/syntax/type/advanced/variance.md b/doc/EN/syntax/type/advanced/variance.md
new file mode 100644
index 00000000..eaa300cf
--- /dev/null
+++ b/doc/EN/syntax/type/advanced/variance.md
@@ -0,0 +1,143 @@
+# variation
+
+Erg can subtype polymorphic types, but there are some caveats.
+
+First, consider the inclusion relation of ordinary polymorphic types. In general, there is a container `K` and a type `A, B` to which it assigns, and when `A < B`, `K A < K B`.
+For example, `Option Int < Option Object`. Therefore, methods defined in `Option Object` can also be used in `Option Int`.
+
+Consider the typical polymorphic type `Array!(T)`.
+Note that this time it's not `Array!(T, N)` because we don't care about the number of elements.
+Now, the `Array!(T)` type has methods called `.push!` and `.pop!`, which mean adding and removing elements, respectively. Here is the type:
+
+Array.push!: Self(T).(T) => NoneType
+Array.pop!: Self(T).() => T
+
+As can be intuitively understood,
+
+* `Array!(Object).push!(s)` is OK when `s: Str` (just upcast `Str` to `Object`)
+* When `o: Object`, `Array!(Str).push!(o)` is NG
+* `Array!(Object).pop!().into(Str)` is NG
+* `Array!(Str).pop!().into(Object)` is OK
+
+is. In terms of the type system, this is
+
+* (Self(Object).(Object) => NoneType) < (Self(Str).(Str) => NoneType)
+* (Self(Str).() => Str) < (Self(Object).() => Object)
+
+means
+
+The former may seem strange. Even though `Str < Object`, the inclusion relation is reversed in the function that takes it as an argument.
+In type theory, such a relation (the type relation of `.push!`) is called contravariant, and vice versa, the type relation of `.pop!` is called covariant.
+In other words, function types are contravariant with respect to their argument types and covariant with respect to their return types.
+It sounds complicated, but as we saw earlier, it's a reasonable rule if you apply it to an actual example.
+If you still don't quite get it, consider the following.
+
+One of Erg's design principles is "large input types, small output types". This is precisely the case for function mutability.
+Looking at the rules above, the larger the input type, the smaller the overall type.
+This is because general-purpose functions are clearly rarer than special-purpose functions.
+And the smaller the output type, the smaller the whole.
+
+As a result, the above policy is equivalent to saying "minimize the type of the function".
+
+## Immutability
+
+Erg has another modification. It is non-variance.
+This is a modification that built-in types such as `SharedCell! T!` have. This means that for two types `T!, U!` where `T! != U!`, casts between `SharedCell! T!` and `SharedCell! means that
+This is because `SharedCell! T!` is a shared reference. See [shared references](shared.md) for details.
+
+## Mutated generic type
+
+A universal type variable can specify its upper and lower bounds.
+
+```python
+|A <: T| K(A)
+|B :> T| K(B)
+```
+
+In the type variable list, the __variant specification__ of the type variable is performed. In the above variant specification, the type variable `A` is declared to be any subclass of type `T` and the type variable `B` is declared to be any superclass of type `T`.
+In this case, `T` is also called the upper type for `A` and the lower type for `B`.
+
+Mutation specifications can also overlap.
+
+```python
+# U U}
+```
+
+Here is an example of code that uses a variable specification.
+
+```python
+show|S <: Show| s: S = log s
+
+Nil T = Class(Impl = Phantom T)
+Cons T = Class(Nil T or List T)
+List T = Class {head = T; rest = Cons T}
+List(T).
+ push|U <: T|(self, x: U): List T = Self. new {head = x; rest = self}
+ upcast(self, U :> T): List U = self
+```
+
+## Change specification
+
+The `List T` example is tricky, so let's go into a little more detail.
+To understand the code above, you need to know about polymorphic type degeneration. Variance is discussed in detail in [this section](./variance.md), but for now we need three facts:
+
+* Ordinary polymorphic types, such as `List T`, are covariant with `T` (`List U > List T` when `U > T`)
+* The function `T -> U` is contravariant with respect to the argument type `T` (`(S -> U) < (T -> U)` when `S > T`)
+* Function `T -> U` is covariant with return type `U` (`(T -> U) > (T -> S)` when `U > S`)
+
+For example, `List Int` can be upcast to `List Object` and `Obj -> Obj` can be upcast to `Int -> Obj`.
+
+Now let's consider what happens if we omit the variable specification of the method.
+
+```python
+...
+List T = Class {head = T; rest = Cons T}
+List(T).
+ # List T can be pushed U if T > U
+ push|U|(self, x: U): List T = Self. new {head = x; rest = self}
+ # List T can be List U if T < U
+ upcast(self, U): List U = self
+```
+
+Even in this case, the Erg compiler does a good job of inferring the upper and lower types of `U`.
+Note, however, that the Erg compiler doesn't understand the semantics of methods. The compiler simply infers and derives type relationships mechanically according to how variables and type variables are used.
+
+As written in the comments, the type `U` put in the `head` of `List T` is a subclass of `T` (`T: Int`, such as `Nat`). That is, it is inferred as `U <: T`. This constraint changes the argument type of `.push{U}` upcast `(List(T), U) -> List(T) to (List(T), T) -> List(T)`( e.g. disallow `List(Int).push{Object}`). Note, however, that the `U <: T` constraint does not alter the type containment of the function. The fact that `(List(Int), Object) -> List(Int) to (List(Int), Int) -> List(Int)` does not change, just in `.push` method It means that the cast cannot be performed.
+Similarly, a cast from `List T` to `List U` is possible subject to the constraint `U :> T`, so the variation specification is inferred. This constraint changes the return type of `.upcast(U)` to upcast `List(T) -> List(T) to List(T) -> List(T)` (e.g. `List(Object) .upcast(Int)`) is prohibited.
+
+Now let's see what happens if we allow this upcast.
+Let's invert the denaturation designation.
+
+```python
+...
+List T = Class {head = T; rest = Cons T}
+List(T).
+ push|U :> T|(self, x: U): List T = Self. new {head = x; rest = self}
+ upcast(self, U :> T): List U = self
+# TypeWarning: `U` in the `.push` cannot take anything other than `U == T`. Replace `U` with `T`.
+# TypeWarning: `U` in the `.upcast` cannot take anything other than `U == T`. Replace `U` with `T`.
+```
+
+Both the constraint `U <: T` and the modification specification `U :> T` are satisfied only when `U == T`. So this designation doesn't make much sense.
+Only "upcasts such that `U == T`" = "upcasts that do not change where `U`" are actually allowed.
+
+## Appendix: Modification of user-defined types
+
+Mutations of user-defined types are immutable by default. However, you can also specify mutability with the `Inputs/Outputs` marker trait.
+If you specify `Inputs(T)`, the type is contravariant with respect to `T`.
+If you specify `Outputs(T)`, the type is covariant with respect to `T`.
+
+```python
+K T = Class(...)
+assert not K(Str) <= K(Object)
+assert not K(Str) >= K(Object)
+
+InputStream T = Class ..., Impl := Inputs(T)
+# A stream that accepts Objects can also be considered to accept Strs
+assert InputStream(Str) > InputStream(Object)
+
+OutputStream T = Class ..., Impl := Outputs(T)
+# A stream that outputs a Str can also be considered to output an Object
+assert OutputStream(Str) < OutputStream(Object)
+```
\ No newline at end of file
diff --git a/doc/EN/syntax/type/advanced/widening.md b/doc/EN/syntax/type/advanced/widening.md
new file mode 100644
index 00000000..d29e27cf
--- /dev/null
+++ b/doc/EN/syntax/type/advanced/widening.md
@@ -0,0 +1,92 @@
+# Type Widening
+
+For example, define the polycorrelation coefficient as follows.
+
+```python
+ids|T|(x: T, y: T) = x, y
+```
+
+There's nothing wrong with assigning a pair of instances of the same class.
+When you assign an instance pair of another class that has a containment relationship, it is upcast to the larger one and becomes the same type.
+Also, it is easy to understand that an error will occur if another class that is not in the containment relationship is assigned.
+
+```python
+assert ids(1, 2) == (1, 2)
+assert ids(1, 2.0) == (1.0, 2.0)
+ids(1, "a") #TypeError
+```
+
+Now, what about types that have different derived types?
+
+```python
+i: Int or Str
+j: Int or NoneType
+ids(i, j) # ?
+```
+
+Before explaining this, we have to focus on the fact that Erg's type system doesn't actually look at (runtime) classes.
+
+```python
+1: {__valueclass_tag__ = Phantom Int}
+2: {__valueclass_tag__ = Phantom Int}
+2.0: {__valueclass_tag__ = Phantom Ratio}
+"a": {__valueclass_tag__ = Phantom Str}
+ids(1, 2): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Int} == {__valueclass_tag__ = Phantom Int}
+ids(1, 2.0): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Ratio} == {__valueclass_tag__ = Phantom Ratio} # Int < Ratio
+ids(1, "a"): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Str} == Never # TypeError
+```
+
+I don't see the class because it may not be seen exactly, because in Erg the class of an object belongs to runtime information.
+For example, the class of an `Int or Str` type object is either `Int` or `Str`, but you can only know which one it is by executing it.
+Of course, the class of an object of type `Int` is defined as `Int`, but in this case as well, what is visible from the type system is the structural type `{__valueclass_tag__ = Int}` of `Int`.
+
+Now let's go back to another structured type example. In conclusion, the above code will result in a TypeError as the type does not match.
+However, if you do type expansion with type annotations, compilation will pass.
+
+```python
+i: Int or Str
+j: Int or NoneType
+ids(i, j) # TypeError: types of i and j not matched
+# hint: try type widening (e.g. ids)
+ids(i, j) # OK
+```
+
+`A and B` have the following possibilities.
+
+* `A and B == A`: when `A <: B` or `A == B`.
+* `A and B == B`: when `A :> B` or `A == B`.
+* `A and B == {}`: when `!(A :> B)` and `!(A <: B)`.
+
+`A or B` has the following possibilities.
+
+* `A or B == A`: when `A :> B` or `A == B`.
+* `A or B == B`: when `A <: B` or `A == B`.
+* `A or B` is irreducible (independent types): if `!(A :> B)` and `!(A <: B)`.
+
+## Type widening in subroutine definitions
+
+Erg defaults to an error if return types do not match.
+
+```python
+parse_to_int s: Str =
+ if not s.is_numeric():
+ do parse_to_int::return error("not numeric")
+ ... # return Int object
+# TypeError: mismatched types of return values
+# 3 | do parse_to_int::return error("not numeric")
+# └─ Error
+# 4 | ...
+# └ Int
+```
+
+In order to solve this, it is necessary to explicitly specify the return type as Or type.
+
+```python
+parse_to_int(s: Str): Int or Error =
+ if not s.is_numeric():
+ do parse_to_int::return error("not numeric")
+ ... # return Int object
+```
+
+This is by design so that you don't unintentionally mix a subroutine's return type with another type.
+However, if the return value type option is a type with an inclusion relationship such as `Int` or `Nat`, it will be aligned to the larger one.
\ No newline at end of file
diff --git a/doc/EN/tips.md b/doc/EN/tips.md
index b90de192..1baf322d 100644
--- a/doc/EN/tips.md
+++ b/doc/EN/tips.md
@@ -7,7 +7,7 @@ However, external libraries may not support multiple languages.
## Want to change only certain attributes of a record
-```erg
+```python
record: {.name = Str; .age = Nat; .height = CentiMeter}
{height; rest; ...} = record
mut_record = {.height = !height; ...rest}
@@ -17,7 +17,7 @@ mut_record = {.height = !height; ...rest}
Shadowing in the same scope is not possible with Erg. However, you can redefine them if the scope changes (This is a syntax called instance block).
-````erg
+````python
## Get a T!-type object and finally assign it to a variable as type T
x: T =
x: T! = foo()
@@ -29,7 +29,7 @@ x: T =
You can create a wrapper class. This is a so-called composition pattern.
-```erg
+```python
FinalWrapper = Class {inner = FinalClass}
FinalWrapper.
method self =
@@ -43,7 +43,7 @@ You can define a traditional enumerated type (algebraic data type) commonly foun
If you implement `Singleton`, classes and instances are identical.
Also, if you use `Enum`, the type of choice is automatically defined as a redirect attribute.
-```erg
+```python
Ok = Class Impl := Singleton
Err = Class Impl := Singleton
ErrWithInfo = Inherit {info = Str}
@@ -55,7 +55,7 @@ match! stat:
Status.ErrWithInfo::{info} -> ...
```
-```erg
+```python
Status = Enum Ok, Err, ErrWithInfo
# is equivalent to
Status = Class Ok or Err or ErrWithInfo
@@ -69,7 +69,7 @@ Status.
method 1:
-```erg
+```python
arr = [...]
for! arr.iter().enumerate(start: 1), i =>
...
@@ -77,7 +77,7 @@ for! arr.iter().enumerate(start: 1), i =>
method 2:
-```erg
+```python
arr = [...]
for! arr.iter().zip(1...) , i =>
...
@@ -88,12 +88,12 @@ for! arr.iter().zip(1...) , i =>
The private API in `foo.er` is specially accessible in the module `foo.test.er`.
The `foo.test.er` module cannot be imported, so it remains hidden.
-```erg
+```python
# foo.er
private x = ...
```
-```erg
+```python
# foo.test.er
foo = import "foo"
@@ -108,7 +108,7 @@ foo = import "foo"
You can make the attribute private and define a getter.
-```erg
+```python
C = Class {v = Int!}
C::
inc_v!(ref! self) = self::v.inc!()
@@ -122,7 +122,7 @@ C.
You can receive arguments by record.
-```erg
+```python
Point = {x = Int; y = Int}
norm: Point -> Int
diff --git a/doc/EN/tools/build.md b/doc/EN/tools/build.md
new file mode 100644
index 00000000..e8df33b7
--- /dev/null
+++ b/doc/EN/tools/build.md
@@ -0,0 +1,14 @@
+# build subcommand
+
+The build subcommand builds the package.
+The steps performed in the default build are as follows:
+
+1. Inspect code in comments/documentation (md files under doc).
+2. Compile the code needed for the package.
+3. For application packages, generate batch files or shell scripts equivalent to commands.
+4. Run the test.
+
+The deliverables after the build is completed are output to the following directory.
+
+* During debug build: build/debug
+* For release build: build/release
\ No newline at end of file
diff --git a/doc/EN/tools/env.md b/doc/EN/tools/env.md
new file mode 100644
index 00000000..19673686
--- /dev/null
+++ b/doc/EN/tools/env.md
@@ -0,0 +1,7 @@
+# env subcommand
+
+The env subcommand specifies the erg execution environment.
+Create a new execution environment with `erg env new [env name]`. An interactive tool opens, and when you specify an erg version, that version of erg will be installed (if it already exists, it will be used), and you will be able to use it as a new environment.
+You can switch the environment with `erg env switch [env name]`.
+The created environment can be edited with `erg env edit` to pre-install packages and specify dependencies for other languages.
+The biggest feature of this command is that `erg env export` can output the information that reproduces the environment as `[env name].env.er` file. This allows you to immediately start developing in the same environment as others. Furthermore, `erg env publish` can publish the environment like a package.
\ No newline at end of file
diff --git a/doc/EN/tools/fmt.md b/doc/EN/tools/fmt.md
new file mode 100644
index 00000000..49f22b63
--- /dev/null
+++ b/doc/EN/tools/fmt.md
@@ -0,0 +1,6 @@
+# fmt
+
+Code formatting can be done with the fmt subcommand.
+Commonly used flags are:
+
+* explicit-type: Automatically completes where the type specification is omitted.
\ No newline at end of file
diff --git a/doc/EN/tools/index.md b/doc/EN/tools/index.md
new file mode 100644
index 00000000..e69de29b
diff --git a/doc/EN/tools/install.md b/doc/EN/tools/install.md
new file mode 100644
index 00000000..0343a0ca
--- /dev/null
+++ b/doc/EN/tools/install.md
@@ -0,0 +1,10 @@
+# install subcommand
+
+You can install packages registered on the registry site with install.
+The basic usage is the same as package managers such as cargo.
+
+## Convenience functions
+
+* If there is a package name with a similar name and the number of downloads is more than 10 times that of that one, a suggestion will appear that you may have entered it incorrectly. This prevents typo squatting.
+* If the package size is large (more than 50MB), display the size and suggest if you really want to install it.
+* Suggest an alternative package if the package is duplicated.
\ No newline at end of file
diff --git a/doc/EN/tools/pack.md b/doc/EN/tools/pack.md
new file mode 100644
index 00000000..0e3b23b3
--- /dev/null
+++ b/doc/EN/tools/pack.md
@@ -0,0 +1,100 @@
+# package manager
+
+Erg comes standard with a package manager, which you can invoke with the `pack` subcommand.
+The following are typical options.
+
+* `erg pack init`: Initialize the current directory as a package. A `package.er` file and a `src` directory are generated. Specifying `app` will result in an executable package, `lib` will result in a library package, and `hybrid` will result in both packages. If `--license` is specified, the license file will be placed automatically.
+* `erg pack build`: Build a package. With `--release` the tests are run and optimized. Artifacts are placed in `build/debug` or `build/release`.
+* `erg pack install`: Install a package. In the case of libraries, `src` is placed in `.erg/lib`, and applications are placed in `.erg/app` as shell scripts. Optimize with `--release`.
+* `erg pack run`: Build the package and run the application (app package only).
+* `erg pack clean`: Delete the contents of the build directory.
+* `erg pack test`: Run a package test. See [test.md](./test.md) for details.
+* `erg pack publish`: Publish/release the package. You will need a GitHub account and public key.
+
+This document explains how to manage your own packages.
+See [install.md](./install.md) if you want to install or search for external packages.
+Also see [package_system.md](../syntax/33_package_system.md) for the Erg package system.
+
+## Standard directory structure for the whole package (for application packages)
+
+```console
+/package # package root directory
+ /build # Directory to store build results
+ /debug # Artifacts during debug build
+ /release # Artifacts of release build
+ /doc # Documents (in addition, by dividing into subdirectories such as `en`, `ja` etc., it is possible to correspond to each language)
+ /src # source code
+ /main.er # file that defines the main function
+ /tests # Directory to store (black box) test files
+ /package.er # file that defines package settings
+```
+
+## package.er
+
+`erg pack init` will generate `package.er` file like below. `package.er` describes the configuration of the package.
+Below is an example of `package.er`.
+
+```python
+name = "example" # package name
+author = "John Smith" # package author name
+version="0.1.0"
+description = "An awesome package"
+categories = ["cli"] # package categories
+type = "app" # "app" or "lib"
+license = "" # e.g. "MIT", "APACHE-2.0", "MIT OR Apache-2.0"
+pre_build = "" # script filename to be executed before build
+post_build = "" # script filename to be executed after build
+dependencies = {
+ # The latest one is selected if the version is not specified
+ # If the version specification is omitted, the package manager automatically adds the version of the last successful build to the comments
+ foo = pack("foo") # [INFO] the last successfully built version: 1.2.1
+ # Packages can be renamed
+ bar1 = pack("bar", "1.*.*") # [INFO] the last successfully built version: 1.2.0
+ bar2 = pack("bar", "2.*.*") # [INFO] the last successfully built version: 2.0.0
+ baz = pack("baz", "1.1.0")
+}
+deprecated=False
+successors = [] # alternative packages (when a package is deprecated)
+```
+
+## Semantic versioning
+
+Erg packages are versioned based on [semantic versioning](https://semver.org/lang/en/).
+Semantic versioning is roughly specified in the format `x.y.z` (x, y, z are integers greater than or equal to 0).
+The meaning of each number is as follows.
+
+* x: major version (increase by 1 when updating breaking compatibility)
+* y: minor version (increase by 1 when performing compatible updates (API addition, deprecation, etc.), bug fixes etc. are handled by patch version upgrade)
+* z: patch version (increase by 1 when minor changes to fix bugs or maintain compatibility are made, serious fixes that break compatibility are handled by major version upgrades)
+
+However, changes in version `0.*.*` are always incompatible by default. If you want to upgrade while maintaining compatibility, specify `-compatible` after it (Erg's own rule). For example, if you want to add functions while maintaining compatibility with `0.2.1`, that is, if you want to upgrade to `0.3.0`, specify `0.3.0-compatible`. Also specify `0.2.2-compatible` if you have fixed bugs.
+That version will then be considered compatible with the previous version.
+This works even if you want to upgrade `0.*.*` to `1.0.0`. That is, `1.0.0-compatible` is compatible with the previous version `0.y.z`.
+
+Semantic versioning is very important when generating lockfiles. Lockfiles are files generated to keep dependencies compatible, so that newer releases of dependents depend on older packages unless explicitly updated.
+Lockfiles are useful when multiple people are developing a package that has dependent packages. It also saves local storage by allowing packages that depend on them to reuse packages if they are compatible.
+
+Erg's package manager strictly enforces these rules and will reject package updates that violate them.
+The Erg package manager works with version control systems (such as git) to detect code differences and verify the correctness of versioning when a package is published.
+Specifically, the package manager looks at the types of the API. A change is considered compatible if the type is a subtype of an older version (note that this is not a full verification; type-compatible but semantically-incompatible significant changes are possible, it is the developer's job to determine this).
+
+Furthermore, since the entire package repository is registered in the registry, even developers cannot update the package without going through the package manager.
+Also, packages can be deprecated but not removed.
+
+### Appendix: Semantic Versioning Issues and Countermeasures
+
+There are (at least) two known problems with semantic versioning.
+First, semantic versioning can be too restrictive.
+With semantic versioning, a single incompatible API change increments the major version of the entire package.
+When this happens, things like "I wanted to try a new API, but I have to deal with another incompatible API change, so I won't upgrade".
+Second, semantic versioning can promise too much.
+As mentioned in the previous section, "compatible changes" to APIs are not theoretically provable. If you specify that you want a package with version `1.0.1`, you can instead use any package between `1.0.1` and `2.0.0` in terms of semantic versioning (`1.0.0` is It can't be used because a bug has been fixed), but there is a possibility that the build will not succeed due to unintended use of the API by the package developer.
+
+Erg addresses this issue by allowing different versions of a package to be used at the same time (by renaming). This makes it possible to continue using the ver1 API while partially introducing the ver2 API.
+Additionally, although it's not a very desirable state, if only a certain minor version of the API can be used without bugs, it's possible to leave it alone and move on to the next version.
+
+## publish
+
+Packages can be published with the `publish` subcommand. Publishing requires a GitHub account.
+Packages are registered with `(owner_name)/(package_name)` by default. If you meet certain conditions (number of downloads, frequency of maintenance, etc.), you can apply to register an alias that omits the owner name.
+Note that package names are case-insensitive and delimiters such as `_` and `-` are not distinguished.
\ No newline at end of file
diff --git a/doc/EN/tools/repl.md b/doc/EN/tools/repl.md
new file mode 100644
index 00000000..84e87e24
--- /dev/null
+++ b/doc/EN/tools/repl.md
@@ -0,0 +1,15 @@
+# REPL
+
+Running the `erg` command with no arguments invokes the REPL. It can also be invoked with the `repl` subcommand.
+Additionally, you can specify the following flags:
+
+* typed: Show objects and their types.
+
+```console
+$ erg repl --typed
+Erg interpreter ... (tags/?:, ...) on ...
+>>> 1
+1: {1}
+>>> id x = x
+id = : |T: Type| T -> T
+```
\ No newline at end of file
diff --git a/doc/EN/tools/test.md b/doc/EN/tools/test.md
new file mode 100644
index 00000000..5844047c
--- /dev/null
+++ b/doc/EN/tools/test.md
@@ -0,0 +1,45 @@
+# test subcommand
+
+The erg command has a subcommand called test, which supports test implementation and execution.
+
+## Test decorator (@Test)
+
+Erg tests the `@Test` subroutine in the `tests` directory in the package or in the `*.test.er` file with the `erg test` command.
+`tests` subroutines are in charge of black-box testing (not testing private functions), and `*.test.er` subroutines are in charge of white-box testing (testing private functions as well).
+
+```python
+# tests/test1.er
+{add; ...} = import "foo"
+
+@Test
+test_1_plus_n(n: Nat) =
+ assert add(1, n) == n + 1
+```
+
+The execution result is displayed as a summary and can be output in various file formats (.md, .csv, etc.).
+
+## Doc Test
+
+In Erg, `#` and `#[` are comment lines, but `##` and `#[[` are doc comments, and comments can be displayed as markdown from editors such as VSCode.
+Furthermore, the source code in the doc comment is automatically tested with the erg test command if erg is specified.
+Below is an example test.
+
+```python
+VMs =...
+ ...
+ #[[
+ execute commands.
+ ```python
+ # VM in standard configuration
+ {vm1; ...} = import "tests/mock"
+
+ assert vm1.exec!("i = 0") == None
+ assert vm1.exec!("i").try_into(Int)? == 0
+ ```
+ ]]#
+ .exec! ref self, src =
+ ...
+ ...
+```
+
+Mock objects (mock objects) used for testing are defined in the `tests/mock` module.
\ No newline at end of file
diff --git a/doc/JA/API/consts.md b/doc/JA/API/consts.md
index 60453cd8..d208c55c 100644
--- a/doc/JA/API/consts.md
+++ b/doc/JA/API/consts.md
@@ -1,5 +1,7 @@
# 組み込み定数
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/consts.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
## True
## False
diff --git a/doc/JA/API/funcs.md b/doc/JA/API/funcs.md
index 3c99f88d..e96b00cd 100644
--- a/doc/JA/API/funcs.md
+++ b/doc/JA/API/funcs.md
@@ -1,5 +1,7 @@
# 関数
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/funcs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
## 基本関数
### if|T; U|(cond: Bool, then: T, else: U) -> T or U
@@ -27,7 +29,7 @@ msgを表示して停止する。
`x`を捨てる。戻り値を使用しないときなどに使う。`del`とは違い、変数`x`を参照できなくするわけではない。
-```erg
+```python
p! x =
# q!は何らかのNoneや()でない値を返すとする
# 要らない場合は`discard`を使う
@@ -56,7 +58,7 @@ codeをコードとして評価し返す。
### repeat|T|(x: T) -> RepeatIterator T
-```erg
+```python
rep = repeat 1 # Repeater(1)
for! rep, i =>
print! i
@@ -65,7 +67,7 @@ for! rep, i =>
### dup|T; N|(x: T, N: Nat) -> [T; N]
-```erg
+```python
[a, b, c] = dup new(), 3
print! a #
print! a == b # False
@@ -73,7 +75,7 @@ print! a == b # False
### cycle|T|(it: Iterable T) -> CycleIterator T
-```erg
+```python
cycle([0, 1]).take 4 # [0, 1, 0, 1]
cycle("hello").take 3 # "hellohellohello"
```
@@ -85,7 +87,7 @@ cycle("hello").take 3 # "hellohellohello"
クラスを新しく生成する。`Inherit`とは違い、`Class`を通すとベース型からは独立し、メソッドは失われる。
比較もできなくなるが、パターンマッチなどは行える。
-```erg
+```python
C = Class {i = Int}
NewInt = Class Int
Months = Class 1..12
@@ -111,7 +113,7 @@ match jan:
引数の型を返す。実行時のクラスを得たい場合は`classof`を使う。
型指定に使うとWarningが出る。
-```erg
+```python
x: Typeof i = ...
# TypeWarning: Typeof(i) == Int, please replace it
```
diff --git a/doc/JA/API/index.md b/doc/JA/API/index.md
index e69de29b..77223195 100644
--- a/doc/JA/API/index.md
+++ b/doc/JA/API/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/API/modules/external/alstruct.md b/doc/JA/API/modules/external/alstruct.md
index 7542d9f3..70f194e4 100644
--- a/doc/JA/API/modules/external/alstruct.md
+++ b/doc/JA/API/modules/external/alstruct.md
@@ -1,12 +1,14 @@
# alstruct
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/external/alstruct.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
代数的構造を表すトレイトや、それにかかるパッチを提供するモジュール。
* member
## BinOp
-```erg
+```python
BinOp Op: Kind 2 = Subsume Op(Self, Self.ReturnTypeOf Op), Additional: {
.ReturnTypeof = TraitType -> Type
}
@@ -20,7 +22,7 @@ assert Nat.ReturnTypeof(Div) == Positive Ratio
## SemiGroup
-```erg
+```python
SemiGroup Op: Kind 2 = Op(Self, Self)
IntIsSemiGroupAdd = Patch Int, Impl=SemiGroup Add
@@ -30,7 +32,7 @@ Int <: SemiGroup Add
## Functor
-```erg
+```python
## * Identity law: x.map(id) == x
## * Composition law: x.map(f).map(g) == x.map(f.then g)
Functor = Trait {
@@ -40,7 +42,7 @@ Functor = Trait {
## Applicative
-```erg
+```python
## * Identity law: x.app(X.pure(id)) == x
Applicative = Subsume Functor, Additional: {
.pure|T: Type| = T -> Self T
@@ -50,7 +52,7 @@ Applicative = Subsume Functor, Additional: {
## Monad
-```erg
+```python
Monad = Subsume Applicative, Additional: {
.bind|T, U: Type| = (Self(T), T -> Self U) -> Self U
}
diff --git a/doc/JA/API/modules/repl.md b/doc/JA/API/modules/repl.md
index f2ee4894..5199ad86 100644
--- a/doc/JA/API/modules/repl.md
+++ b/doc/JA/API/modules/repl.md
@@ -1,5 +1,7 @@
# module `repl`
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/repl.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
provides REPL(Read-Eval-Print-Loop)-related APIs.
## functions
@@ -18,7 +20,7 @@ provides REPL(Read-Eval-Print-Loop)-related APIs.
与えられた引数と戻り値から、関数を推測する。
-```erg
+```python
1.guess((1,), 2) #
[1, 2].guess((3, 4), [1, 2, 3, 4]) #
```
diff --git a/doc/JA/API/modules/status.md b/doc/JA/API/modules/status.md
index 345da026..a08c1c87 100644
--- a/doc/JA/API/modules/status.md
+++ b/doc/JA/API/modules/status.md
@@ -1,5 +1,7 @@
# module `status`
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/status.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
状態を表す型が定義されています。状況に応じて選択肢を外したりして使用してください。
* ExecResult = {"success", "warning", "failure", "fatal", "unknown"}
diff --git a/doc/JA/API/modules/unit.md b/doc/JA/API/modules/unit.md
index fa14eac6..36b90682 100644
--- a/doc/JA/API/modules/unit.md
+++ b/doc/JA/API/modules/unit.md
@@ -1,12 +1,14 @@
# module `unit`
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unit.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
`unit`モジュールは数値計算でよく使われる単位を型として定義したモジュールです。
Ergの数値型は`Nat`, `Int`, `Ratio`などがあります。しかしこれらの型は「何を意味する数値なのか」という情報を持っておらず、メートルとヤード同士の足し算などといったナンセンスな計算を行えてしまいます。
`unit`モジュールを使うことにより、単位の違う数値を関数に渡すといったミスを防げます。
このようなミスは実際に起っており、[単位系の取り間違いで火星探査機が行方不明](http://www.sydrose.com/case100/287/)になるなど、深刻なバグを引き起こしかねません。
数値計算を行う上でコードの堅牢性を高めたいならばこのモジュールを使用しておくべきです。
-```erg
+```python
{*} = import "unit"
x = 6m # `x = Meter.new(6)`と等価
@@ -33,7 +35,7 @@ unitでは以下の単位を型として定義しています。SI(国際単位
例えば、振動数の単位ヘルツ(hertz)は振動周期(秒)の逆数で定義されているので、`UnitDiv(Unit1, Sec)`です。
この型を意味のある型とみなしたい(専用のメソッドを加えたい、など)ときは、[パッチ](./../../syntax/type/07_patch.md)を作成すると良いでしょう。
-```erg
+```python
Hertz = Patch UnitDiv(Unit1, Sec)
SquareMeter = Patch UnitMul(Meter, Meter)
```
@@ -47,8 +49,8 @@ SquareMeter = Patch UnitMul(Meter, Meter)
* 電位: Volt(v)
* 電気抵抗: Ohm(ohm)
* 速度: Velocity(m/s)
-* 面積: SquareMeter(m**2)
-* 体積: CubicMeter(m**3) (litre = 10e-3 m**3)
+* 面積: SquareMeter(m^2)
+* 体積: CubicMeter(m^3) (litre = 10e-3 m^3)
* 角度: Degree(deg) (rad = 180/pi deg)
* 長さ: Feet, Yard, Inch, Mile, Ly, Au, Angstrom
* 重さ: Pond
diff --git a/doc/JA/API/modules/unsound.md b/doc/JA/API/modules/unsound.md
index 59bc56b7..ad026aa6 100644
--- a/doc/JA/API/modules/unsound.md
+++ b/doc/JA/API/modules/unsound.md
@@ -1,12 +1,14 @@
# module `unsound`
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unsound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
Provides APIs perform unsound and unsafe operations that cannot be guaranteed safe in Erg's type system.
## `unsafe!`
Executes a `Unsafe` procedure. Just like Rust, `Unsafe` APIs cannot be called directly, but are all passed as higher-order functions to this procedure.
-```erg
+```python
unsound = import "unsound"
i = unsound.unsafe! do!:
diff --git a/doc/JA/API/operators.md b/doc/JA/API/operators.md
index 66dbade4..37de6705 100644
--- a/doc/JA/API/operators.md
+++ b/doc/JA/API/operators.md
@@ -1,5 +1,7 @@
# 演算子
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/operators.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
## 中置演算子
### `_+_`|R; O; A <: Add(R, O)|(x: A, y: R) -> O
diff --git a/doc/JA/API/procs.md b/doc/JA/API/procs.md
index 852369c9..a0cb26a3 100644
--- a/doc/JA/API/procs.md
+++ b/doc/JA/API/procs.md
@@ -1,8 +1,10 @@
# プロシージャ
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/procs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
## print!
-```erg
+```python
print!(x) -> NoneType
```
@@ -10,7 +12,7 @@ print!(x) -> NoneType
## debug!
-```erg
+```python
debug!(x, type = Info) -> NoneType
```
diff --git a/doc/JA/API/special.md b/doc/JA/API/special.md
index 8ded9cc0..7841e142 100644
--- a/doc/JA/API/special.md
+++ b/doc/JA/API/special.md
@@ -1,5 +1,7 @@
# 特殊形式(Special form)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
特殊形式は、Ergの型システムでは表現ができない演算子、サブルーチン(のようなもの)である。``で囲っているが、実際は捕捉できない。
また、`Pattern`や`Body`, `Conv`といった型が便宜上登場するが、そのような型が存在するわけではない。その意味もコンテクストによって異なる。
@@ -9,7 +11,7 @@
bodyをpatに変数として代入する。同じスコープにすでに変数が存在する場合と、patにマッチしなかった場合にエラーを送出する。
また、レコードの属性定義やデフォルト引数にも使われる。
-```erg
+```python
record = {i = 1; j = 2}
f(x: Int, y = 2) = ...
```
@@ -17,7 +19,7 @@ f(x: Int, y = 2) = ...
bodyが型か関数であるときに`=`は特殊な振る舞いをする。
左辺の変数名を右辺のオブジェクトに埋め込むのである。
-```erg
+```python
print! Class() # >
print! x: Int -> x + 1 # >
C = Class()
@@ -35,7 +37,7 @@ print! L #
`=`演算子は、戻り値が「未定義」である。
多重代入、関数中での`=`は文法エラーとなる。
-```erg
+```python
i = j = 1 # SyntaxError: multiple assignments are not allowed
print!(x=1) # SyntaxError: cannot use `=` in function arguments
# hint: did you mean keyword arguments (`x: 1`)?
@@ -55,14 +57,14 @@ if True, do:
subjectがTに合致しているか判定する。合致していない場合はコンパイルエラーを送出する。
-```erg
+```python
a: Int
f x: Int, y: Int = x / y
```
また、`:`適用スタイルにも使われる。
-```erg
+```python
f x:
y
z
@@ -70,7 +72,7 @@ f x:
`:`も`=`と同じく演算の結果が未定義である。
-```erg
+```python
_ = x: Int # SyntaxError:
print!(x: Int) # SyntaxError:
```
@@ -92,7 +94,7 @@ objの属性を読み込む。
objについて、パターンにマッチしたlambdaを実行する。
-```erg
+```python
match [1, 2, 3]:
(l: Int) -> log "this is type of Int"
[[a], b] -> log a, b
@@ -104,7 +106,7 @@ match [1, 2, 3]:
変数`x`を削除する。ただし組み込みのオブジェクトは削除できない。
-```erg
+```python
a = 1
del a # OK
@@ -124,7 +126,7 @@ del True # SyntaxError: cannot delete a built-in object
Choiceオブジェクトという2つ組のタプルのような構造体を生成する。
`l, r`は遅延評価される。すなわち、`.get_then`または`.get_else`が呼ばれたとき初めて式が評価される。
-```erg
+```python
choice = 1 else 2
assert choice.get_then() == 1
assert choice.get_else() == 2
@@ -153,7 +155,7 @@ assert True.then(choice) == 1
入れ子になったコレクションを展開する。パターンマッチでも使える。
-```erg
+```python
[x, ...y] = [1, 2, 3]
assert x == 1 and y == [2, 3]
assert [x, ...y] == [1, 2, 3]
diff --git a/doc/JA/API/types.md b/doc/JA/API/types.md
index 60b7e9d0..b8208f26 100644
--- a/doc/JA/API/types.md
+++ b/doc/JA/API/types.md
@@ -1,5 +1,7 @@
# Erg組み込み型一覧
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
型自体の属性は`.__dict__`の中には格納されていないので、インスタンスからは参照できない
## 汎用型 (Fundamental types)
diff --git a/doc/JA/API/types/classes/Array!(T).md b/doc/JA/API/types/classes/Array!(T).md
index 76044b45..74b46f12 100644
--- a/doc/JA/API/types/classes/Array!(T).md
+++ b/doc/JA/API/types/classes/Array!(T).md
@@ -1,4 +1,6 @@
# Array! T
+[.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array!(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
可変長配列を表す型。コンパイル時に長さがわからない場合に使う。`[T]!`という糖衣構文がある。
`Array! T = ArrayWithMutLength! T, !_`で定義される。
diff --git a/doc/JA/API/types/classes/Array(T).md b/doc/JA/API/types/classes/Array(T).md
index 59cae131..e594de2d 100644
--- a/doc/JA/API/types/classes/Array(T).md
+++ b/doc/JA/API/types/classes/Array(T).md
@@ -1,3 +1,5 @@
# Array T: Type
+[.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
`Array T = ArrayWithLen T, _`で定義される。`[T]`という糖衣構文がある。
diff --git a/doc/JA/API/types/classes/ArrayWithLen(T,N).md b/doc/JA/API/types/classes/ArrayWithLen(T,N).md
index 77fc65bb..35be9e60 100644
--- a/doc/JA/API/types/classes/ArrayWithLen(T,N).md
+++ b/doc/JA/API/types/classes/ArrayWithLen(T,N).md
@@ -1,12 +1,14 @@
# ArrayWithLen T: Type, N: Nat
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithLen(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
`[T; N]`は糖衣構文。長さを省いた[`Array`型](./Array.md)もある。
## methods
* values_at(self, selectors: [Nat; N]) -> [T; N]
-```erg
+```python
assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"]
```
@@ -15,7 +17,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"]
要素が0のときはpredに関わらず`True`となるが、Warningを出す。
この仕様自体は多くの言語で採用されており、論理学的な整合性から要請される。
- ```erg
+ ```python
assert [].all(_ -> False)
```
@@ -28,7 +30,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"]
* freq self -> [{T: Nat}]
オブジェクトの出現頻度を返す。
-```erg
+```python
assert ["a", "b", "c", "b", "c", "b"].freq() \
== [{"a", 1}, {"b": 3}, {"c": 2}]
```
diff --git a/doc/JA/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/JA/API/types/classes/ArrayWithMutLength!(T,N).md
index 1012d84e..b0e2032b 100644
--- a/doc/JA/API/types/classes/ArrayWithMutLength!(T,N).md
+++ b/doc/JA/API/types/classes/ArrayWithMutLength!(T,N).md
@@ -1,5 +1,7 @@
# ArrayWithMutLength! T: Type, N: Nat!
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
コンパイル時に長さのわかる可変長配列。`ArrayWithMutLength(T, !N) == [T; !N]`という糖衣構文もある。
## methods
diff --git a/doc/JA/API/types/classes/Class.md b/doc/JA/API/types/classes/Class.md
index e69de29b..8cad7741 100644
--- a/doc/JA/API/types/classes/Class.md
+++ b/doc/JA/API/types/classes/Class.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Class.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/API/types/classes/Complex.md b/doc/JA/API/types/classes/Complex.md
index 10dcb3cd..f4e5f39c 100644
--- a/doc/JA/API/types/classes/Complex.md
+++ b/doc/JA/API/types/classes/Complex.md
@@ -1,5 +1,7 @@
# Complex
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Complex.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
複素数を表す型です。Ergで数字を表す型、例えばFloatやInt、Natなどは、大抵この型を上位に持ちます。
## supers
diff --git a/doc/JA/API/types/classes/Dict!.md b/doc/JA/API/types/classes/Dict!.md
index 302af630..611f1bcb 100644
--- a/doc/JA/API/types/classes/Dict!.md
+++ b/doc/JA/API/types/classes/Dict!.md
@@ -1,5 +1,7 @@
# Dict! K, V
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Dict!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
辞書(ハッシュマップ)を表す型。`{K: V}`という構文糖が存在する。
## methods
diff --git a/doc/JA/API/types/classes/Either.md b/doc/JA/API/types/classes/Either.md
index bcde0468..08118628 100644
--- a/doc/JA/API/types/classes/Either.md
+++ b/doc/JA/API/types/classes/Either.md
@@ -1,5 +1,7 @@
# Either L, R = L or R
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Either.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
「LかRかどちらか」を表す型。Or型の2つ限定形と考えて良い。
## methods
diff --git a/doc/JA/API/types/classes/Float.md b/doc/JA/API/types/classes/Float.md
index a874c3cf..2129c03a 100644
--- a/doc/JA/API/types/classes/Float.md
+++ b/doc/JA/API/types/classes/Float.md
@@ -1,5 +1,7 @@
# Float size
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Float.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
実数(小数を含む数)を表す型です。IEEE 754に準拠した浮動小数点数を表し、他の言語では一般的にfloatに相当する型です。
Float sizeのsizeは、8(1byte)~128(16byte)となります。単にFloatとした場合`Float 64`を表します。
Ergでの0.1は実はFloat型ではなく、Ratio型に属します。Float型のリテラルは存在せず、`(Ratioオブジェクト)f64`(e.g. (1/2)f64, 15f64)で生成します。f64は実数の1に対応します。
diff --git a/doc/JA/API/types/classes/Function(N).md b/doc/JA/API/types/classes/Function(N).md
index 0955f2ec..12bfbc21 100644
--- a/doc/JA/API/types/classes/Function(N).md
+++ b/doc/JA/API/types/classes/Function(N).md
@@ -1,9 +1,11 @@
# Function N: Nat
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Function(N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
## methods of Function 1
* then(self, g: Self) -> Self
-```erg
+```python
assert f(g(x)) == f.then(g) x
```
diff --git a/doc/JA/API/types/classes/Inf.md b/doc/JA/API/types/classes/Inf.md
index 45e579bc..ff37119e 100644
--- a/doc/JA/API/types/classes/Inf.md
+++ b/doc/JA/API/types/classes/Inf.md
@@ -1,5 +1,7 @@
# Inf
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Inf.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
Infはinfただひとつをインスタンスとするクラスである。
infの主な使いみちは、区間型での使用である。
例えば、2以上の整数型は`2.. Type
```
diff --git a/doc/JA/API/types/classes/Matrix.md b/doc/JA/API/types/classes/Matrix.md
index a4803e45..ec17e2f3 100644
--- a/doc/JA/API/types/classes/Matrix.md
+++ b/doc/JA/API/types/classes/Matrix.md
@@ -1,5 +1,7 @@
# Matrix T: Num, Shape: [M, N]
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Matrix.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
行列を表す型です。Tensor [M, N]を継承しています。
## def
diff --git a/doc/JA/API/types/classes/Module.md b/doc/JA/API/types/classes/Module.md
index 03b89e9f..98d15409 100644
--- a/doc/JA/API/types/classes/Module.md
+++ b/doc/JA/API/types/classes/Module.md
@@ -1,3 +1,5 @@
# Module
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Module.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
## methods
diff --git a/doc/JA/API/types/classes/Nat.md b/doc/JA/API/types/classes/Nat.md
index 5fe1d242..cba3e242 100644
--- a/doc/JA/API/types/classes/Nat.md
+++ b/doc/JA/API/types/classes/Nat.md
@@ -1,10 +1,12 @@
# Nat
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Nat.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
自然数を表す型。配列のインデックスや範囲型などで使われる。
## def
-```erg
+```python
Nat = 0.._
```
@@ -12,7 +14,7 @@ Nat = 0.._
* times!(self, p: () => NoneType) -> NoneType
-```erg
+```python
100.times! () =>
print! "hello!"
```
diff --git a/doc/JA/API/types/classes/Neg.md b/doc/JA/API/types/classes/Neg.md
index f11db34f..ed0cc039 100644
--- a/doc/JA/API/types/classes/Neg.md
+++ b/doc/JA/API/types/classes/Neg.md
@@ -1,5 +1,7 @@
# Neg
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Neg.md&commit_hash=290c43b09f7c3036112a164bed5fd07a1f6a5cda)
+
負の整数を表す型です。Pos and Neg and {0} == Intとなります。
ゼロ除算が起きない、Neg * Neg == Posとなるなど、いくつか特筆すべき性質も持っています。
diff --git a/doc/JA/API/types/classes/Never.md b/doc/JA/API/types/classes/Never.md
index 4ab9ff94..c4c2fc5c 100644
--- a/doc/JA/API/types/classes/Never.md
+++ b/doc/JA/API/types/classes/Never.md
@@ -1,9 +1,11 @@
# Never
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Never.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
全ての型の下位型である。全てのメソッドを持っており、当然`.new`も持っているため`Class`である。しかしインスタンスは持たず、生成されそうになった瞬間にErgは停止する。
`Panic`という同じくインスタンスを持たない型が存在するが、正常に終了する際や意図的な無限ループの際は`Never`、異常終了する際には`Panic`を使う。
-```erg
+```python
# Never <: Panic
f(): Panic = exit 0 # OK
g(): Never = panic() # TypeError
diff --git a/doc/JA/API/types/classes/NonZero.md b/doc/JA/API/types/classes/NonZero.md
index d6e3c41e..345271d5 100644
--- a/doc/JA/API/types/classes/NonZero.md
+++ b/doc/JA/API/types/classes/NonZero.md
@@ -1,5 +1,7 @@
# NonZero N
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/NonZero.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
ゼロではない数を表すクラスです。ゼロ除算の安全性が保証されます。
```mermaid
diff --git a/doc/JA/API/types/classes/Object.md b/doc/JA/API/types/classes/Object.md
index 26935cb4..c61d25cf 100644
--- a/doc/JA/API/types/classes/Object.md
+++ b/doc/JA/API/types/classes/Object.md
@@ -1,5 +1,7 @@
# Object
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Object.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
全ての型の上位型である。
## methods
diff --git a/doc/JA/API/types/classes/Operator.md b/doc/JA/API/types/classes/Operator.md
index 9c45b70b..21caabb0 100644
--- a/doc/JA/API/types/classes/Operator.md
+++ b/doc/JA/API/types/classes/Operator.md
@@ -1,5 +1,7 @@
# Operator [...T], O
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Operator.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
演算子の型です。
## def
diff --git a/doc/JA/API/types/classes/Option.md b/doc/JA/API/types/classes/Option.md
index 11dc2398..847225ab 100644
--- a/doc/JA/API/types/classes/Option.md
+++ b/doc/JA/API/types/classes/Option.md
@@ -1,5 +1,7 @@
# Option T = T or NoneType
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Option.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
「失敗するかもしれない」を表す型。
## methods
@@ -8,7 +10,7 @@
中身が`T`型であると期待して取り出す。`None`であった場合`msg`を出力してパニックする。
-```erg
+```python
x = "...".parse(Int).into(Option Int)
x.unwrap() # UnwrappingError: unwrapped a None value
x.unwrap("failed to convert from string to number") # UnwrappingError: failed to convert from string to number
diff --git a/doc/JA/API/types/classes/Pos.md b/doc/JA/API/types/classes/Pos.md
index dbade292..9be74c6b 100644
--- a/doc/JA/API/types/classes/Pos.md
+++ b/doc/JA/API/types/classes/Pos.md
@@ -1,5 +1,7 @@
# Pos
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Pos.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
Posは正数(1以上の整数)を表す型です。
0が入らないので、ゼロ除算の可能性を排除できるなどのメリットがあります。
diff --git a/doc/JA/API/types/classes/Ratio.md b/doc/JA/API/types/classes/Ratio.md
index 70e5f8d7..d4bd5dd1 100644
--- a/doc/JA/API/types/classes/Ratio.md
+++ b/doc/JA/API/types/classes/Ratio.md
@@ -1,5 +1,7 @@
# Ratio
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Ratio.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
有理数を表す型です。主に、分数を使いたいときに使います。
実はErgでの/演算子はRatioを返します。1/3などは0.33333...とは評価されず1/3のまま処理されます。また、0.1は1/10と等価です。なので、`0.1 + 0.2 == 0.3`となります。当たり前のように聞こえますが、PythonではなんとFalseになります。
とはいえ、Ratio型はFloat型に比べて若干効率が下がる傾向があります。そこまで正確な数値は要らず、かつ実行速度が重要となるポイントではFloat型を使用するといいでしょう。とはいえ、Rob Pikeが言うように早すぎる最適化は諸悪の根源です。Ratio型を捨ててFloat型を使用するのは実際にパフォーマンステストを行ってからにしましょう。素人ほど無条件に軽量な型を好みます。
diff --git a/doc/JA/API/types/classes/Record.md b/doc/JA/API/types/classes/Record.md
index 97be5017..f5956e5b 100644
--- a/doc/JA/API/types/classes/Record.md
+++ b/doc/JA/API/types/classes/Record.md
@@ -1,9 +1,11 @@
# Record
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Record.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
レコードの属するクラス。例えば`{i = 1}`は`Structural {i = Int}`型などの要素であり、`{i = Int}`クラスのインスタンスである。
他のクラスのインスタンスはレコード型の要素であってもレコードクラスのインスタンスではないことに注意。
-```erg
+```python
assert not Structural({i = Int}) in Class
assert {i = Int} in Class
diff --git a/doc/JA/API/types/classes/Result.md b/doc/JA/API/types/classes/Result.md
index 8364f26f..98b4ef50 100644
--- a/doc/JA/API/types/classes/Result.md
+++ b/doc/JA/API/types/classes/Result.md
@@ -1,6 +1,8 @@
# Result T, E
-```erg
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Result.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
Result T, E <: Error = Either T, E
```
diff --git a/doc/JA/API/types/classes/Str!.md b/doc/JA/API/types/classes/Str!.md
index 7e4bd67b..22a97976 100644
--- a/doc/JA/API/types/classes/Str!.md
+++ b/doc/JA/API/types/classes/Str!.md
@@ -1,3 +1,5 @@
# StrWithLen! N: Nat! = Inherit StrWithLen N
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
可変長文字列を表す型。
diff --git a/doc/JA/API/types/classes/Str.md b/doc/JA/API/types/classes/Str.md
index 7adcc18c..5735aac2 100644
--- a/doc/JA/API/types/classes/Str.md
+++ b/doc/JA/API/types/classes/Str.md
@@ -1,5 +1,7 @@
# Str
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
(不変長)文字列を表す型。単なる`Str`型は`StrWithLen N`型から文字数の情報を落とした型である(`Str = StrWithLen _`)。
## methods
diff --git a/doc/JA/API/types/classes/StrWithLen.md b/doc/JA/API/types/classes/StrWithLen.md
index e69de29b..67caca65 100644
--- a/doc/JA/API/types/classes/StrWithLen.md
+++ b/doc/JA/API/types/classes/StrWithLen.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/StrWithLen.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/API/types/classes/Subroutine.md b/doc/JA/API/types/classes/Subroutine.md
index 09317713..2ad5e354 100644
--- a/doc/JA/API/types/classes/Subroutine.md
+++ b/doc/JA/API/types/classes/Subroutine.md
@@ -1,5 +1,7 @@
# Subroutine
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Subroutine.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
FuncやProcの基底型です。
## methods
@@ -8,7 +10,7 @@ FuncやProcの基底型です。
サブルーチンを中断して、指定した値を返す。ネストから一気に脱出する際に便利。
-```erg
+```python
f x =
for 0..10, i ->
if i == 5:
diff --git a/doc/JA/API/types/classes/Tensor.md b/doc/JA/API/types/classes/Tensor.md
index 0fdb374c..764aa527 100644
--- a/doc/JA/API/types/classes/Tensor.md
+++ b/doc/JA/API/types/classes/Tensor.md
@@ -1,15 +1,17 @@
# Tensor Shape: [Nat; N]
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tensor.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
多次元配列を効率的に操作するためのクラス。多次元配列に対する積などの演算も定義する。
Matrix, Vectorなどはこの型を継承している。
-```erg
+```python
Tensor.arange(0..9) # Tensor [10]
```
* reshape(self, NewShape: [Nat; M]) -> Self NewShape
-```erg
+```python
(1..9).into(Tensor).reshape [3, 3]
```
diff --git a/doc/JA/API/types/classes/TransCell(T).md b/doc/JA/API/types/classes/TransCell(T).md
index e30d479e..14727194 100644
--- a/doc/JA/API/types/classes/TransCell(T).md
+++ b/doc/JA/API/types/classes/TransCell(T).md
@@ -1,9 +1,11 @@
# TransCell! T: Type!
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/TransCell(T).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
中身を型ごと変えられるセルです。T型のサブタイプとなるので、T型としても振る舞います。
初期化時点ではT型で、ある時点以降はずっとU型、といった場合に便利です。
-```erg
+```python
a = TransCell!.new None
a: TransCell! !NoneType
a.set! 1
diff --git a/doc/JA/API/types/classes/Tuple.md b/doc/JA/API/types/classes/Tuple.md
index 8ea4182c..542aae1e 100644
--- a/doc/JA/API/types/classes/Tuple.md
+++ b/doc/JA/API/types/classes/Tuple.md
@@ -1,5 +1,7 @@
# Tuple T: ...Type
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tuple.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
複数の型のオブジェクトを保持するコレクション。
## methods
@@ -8,7 +10,7 @@
2つの順番付けられたコレクション(配列かタプル)を合成する。
- ```erg
+ ```python
assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4)
```
@@ -17,7 +19,7 @@
zipを一般化したメソッド。合成するための二項演算を指定できる。
演算子には`()`, `[]`, `{}`, `{:}`も指定可能で、それぞれタプル, 配列, セット, ディクトを生成する。
- ```erg
+ ```python
assert ([1, 2, 3].zip([4, 5, 6]))[0] == (1, 4)
assert ([1, 2, 3].zip_by((), [4, 5, 6]))[0] == (1, 4)
assert ([1, 2, 3].zip_by([], [4, 5, 6]))[0] == [1, 4]
diff --git a/doc/JA/API/types/classes/Type.md b/doc/JA/API/types/classes/Type.md
index e69de29b..dae4a5c2 100644
--- a/doc/JA/API/types/classes/Type.md
+++ b/doc/JA/API/types/classes/Type.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/API/types/classes/Vector.md b/doc/JA/API/types/classes/Vector.md
index cfe0337e..3214edd2 100644
--- a/doc/JA/API/types/classes/Vector.md
+++ b/doc/JA/API/types/classes/Vector.md
@@ -1,3 +1,5 @@
# Vector T: Num, N: Nat
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Vector.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
ベクトルを表す型です。RustやC++などの同名の型と違い、この型が扱うのは数値専用です。
diff --git a/doc/JA/API/types/patches/BinOp.md b/doc/JA/API/types/patches/BinOp.md
index 85ee08dd..0a647266 100644
--- a/doc/JA/API/types/patches/BinOp.md
+++ b/doc/JA/API/types/patches/BinOp.md
@@ -1,5 +1,7 @@
# BinOp L, R, O
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/BinOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
二項演算子の型です。
## Patches
diff --git a/doc/JA/API/types/patches/UnaryOp.md b/doc/JA/API/types/patches/UnaryOp.md
index 8128dab2..1abb984f 100644
--- a/doc/JA/API/types/patches/UnaryOp.md
+++ b/doc/JA/API/types/patches/UnaryOp.md
@@ -1,5 +1,7 @@
# UnaryOp T, O
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/UnaryOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
単項演算子の型です。
## def
diff --git a/doc/JA/API/types/traits/Add(R,O).md b/doc/JA/API/types/traits/Add(R,O).md
index 9b5290c1..7cbf0690 100644
--- a/doc/JA/API/types/traits/Add(R,O).md
+++ b/doc/JA/API/types/traits/Add(R,O).md
@@ -1,6 +1,8 @@
# Add R
-```erg
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Add(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
Add R = Trait {
.AddO = Type
.`_+_` = (Self, R) -> Self.AddO
@@ -10,13 +12,13 @@ Add R = Trait {
`Add`は加算を定義する型である。加算としての`+`にはメソッドと関数の2種類がある。
二項関数としての`+`、すなわち`_+_`は、以下のように定義されている。
-```erg
+```python
`_+_`(l: Add(R, O), r: R): O = l.`_+_` r
```
わざわざこの定義があるのは、`+`をメソッドではなく関数として取り扱えるようにである。
-```erg
+```python
assert [1, 2, 3].fold(0, `_+_`) == 6
call op, x, y = op(x, y)
@@ -25,7 +27,7 @@ assert call(`_+_`, 1, 2) == 3
加算はこのように型付けされる。
-```erg
+```python
f: |O: Type; A <: Add(Int, O)| A -> O
f x = x + 1
diff --git a/doc/JA/API/types/traits/Div(R,O).md b/doc/JA/API/types/traits/Div(R,O).md
index 3ba59edf..42f7c065 100644
--- a/doc/JA/API/types/traits/Div(R,O).md
+++ b/doc/JA/API/types/traits/Div(R,O).md
@@ -1,8 +1,10 @@
# Div R, O
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Div(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
ゼロ除算によるエラーがない場合は`SafeDiv`を使ってください。
-```erg
+```python
Div R, O = Trait {
.`/` = Self.(R) -> O or Panic
}
diff --git a/doc/JA/API/types/traits/Eq.md b/doc/JA/API/types/traits/Eq.md
index e69de29b..6aed2ae0 100644
--- a/doc/JA/API/types/traits/Eq.md
+++ b/doc/JA/API/types/traits/Eq.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Eq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/API/types/traits/Into.md b/doc/JA/API/types/traits/Into.md
index 9151f047..a1f7bf31 100644
--- a/doc/JA/API/types/traits/Into.md
+++ b/doc/JA/API/types/traits/Into.md
@@ -1,5 +1,7 @@
# Into T
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Into.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
T型に型変換可能であることを示す型です。
SelfとTの間に継承関係などがなくても、互いに変換可能な関係であるときに定義します。
継承と違い暗黙には変換が行われません。必ず`.into`メソッドを呼び出す必要があります。
diff --git a/doc/JA/API/types/traits/Iterable.md b/doc/JA/API/types/traits/Iterable.md
index e69de29b..ba458258 100644
--- a/doc/JA/API/types/traits/Iterable.md
+++ b/doc/JA/API/types/traits/Iterable.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Iterable.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/API/types/traits/Num.md b/doc/JA/API/types/traits/Num.md
index 5745c5ce..e6584efb 100644
--- a/doc/JA/API/types/traits/Num.md
+++ b/doc/JA/API/types/traits/Num.md
@@ -1,8 +1,10 @@
# Num
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Num.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
## definition
-```erg
+```python
Num R = Add(R) and Sub(R) and Mul(R) and Eq
Num = Num Self
```
diff --git a/doc/JA/API/types/traits/Ord.md b/doc/JA/API/types/traits/Ord.md
index e69de29b..3ef5f04a 100644
--- a/doc/JA/API/types/traits/Ord.md
+++ b/doc/JA/API/types/traits/Ord.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Ord.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/API/types/traits/SafeDiv(R,O).md b/doc/JA/API/types/traits/SafeDiv(R,O).md
index 54c3a1b1..03595643 100644
--- a/doc/JA/API/types/traits/SafeDiv(R,O).md
+++ b/doc/JA/API/types/traits/SafeDiv(R,O).md
@@ -1,6 +1,8 @@
# SafeDiv R, O
-```erg
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/SafeDiv(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
SafeDiv R, O = Subsume Div, {
@Override
.`/` = Self.(R) -> O
diff --git a/doc/JA/API/types/traits/Sample.md b/doc/JA/API/types/traits/Sample.md
index bd286d9d..450a4cee 100644
--- a/doc/JA/API/types/traits/Sample.md
+++ b/doc/JA/API/types/traits/Sample.md
@@ -1,12 +1,14 @@
# Sample
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Sample.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
インスタンスを「適当に」選出する`sample`メソッドと`sample!`メソッドを持つトレイト。`sample`メソッドは常に同じインスタンスを返し、`sample!`メソッドは呼び出しごとに変わる適当なインスタンスを返す。
これはテストなどで適当なインスタンスがほしい場合を想定したトレイトであり、必ずしも無作為ではないことに注意が必要である。無作為抽出が必要な場合は`random`モジュールを使用する。
主要な値クラスは全て`Sample`を実装する。また、`Sample`なクラスで構成されているタプル型やレコード型、Or型、篩型でも実装されている。
-```erg
+```python
assert Int.sample() == 42
assert Str.sample() == "example"
# Intの場合、標準では64bitの範囲でサンプルされる
@@ -16,7 +18,7 @@ print! {x = Int; y = Int}.sample!() # {x = -32432892, y = 78458576891}
以下は`Sample`の実装例である。
-```erg
+```python
EmailAddress = Class {header = Str; domain = Str}, Impl=Sample and Show
@Impl Show
EmailAddress.
diff --git a/doc/JA/API/types/traits/Seq.md b/doc/JA/API/types/traits/Seq.md
index e69de29b..007f7134 100644
--- a/doc/JA/API/types/traits/Seq.md
+++ b/doc/JA/API/types/traits/Seq.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Seq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/API/types/traits/Show.md b/doc/JA/API/types/traits/Show.md
index e69de29b..30763e02 100644
--- a/doc/JA/API/types/traits/Show.md
+++ b/doc/JA/API/types/traits/Show.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Show.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/API/types/traits/Unpack.md b/doc/JA/API/types/traits/Unpack.md
index b82282a8..3b705fb8 100644
--- a/doc/JA/API/types/traits/Unpack.md
+++ b/doc/JA/API/types/traits/Unpack.md
@@ -1,8 +1,10 @@
# Unpack
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Unpack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
マーカートレイト。実装すると、レコードのようにパターンマッチで要素を分解できる。
-```erg
+```python
C = Class {i = Int}, Impl=Unpack
C.new i = Self::new {i;}
{i} = C.new(1)
diff --git a/doc/JA/compiler/TODO_hint.md b/doc/JA/compiler/TODO_hint.md
index 3844f83f..76edb2cd 100644
--- a/doc/JA/compiler/TODO_hint.md
+++ b/doc/JA/compiler/TODO_hint.md
@@ -1,4 +1,6 @@
# Hint (not implemented)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_hint.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
* `x is not defined` (x was deleted by `Del`) => `hint: deleted in line X`
* patch method duplication: "hint: Specify patch (like `T.foo(1)`) or delete either `.foo` using `Del`"
diff --git a/doc/JA/compiler/TODO_recov_suggest.md b/doc/JA/compiler/TODO_recov_suggest.md
index a11955fa..92d04c7c 100644
--- a/doc/JA/compiler/TODO_recov_suggest.md
+++ b/doc/JA/compiler/TODO_recov_suggest.md
@@ -1,5 +1,7 @@
# Error recovery suggestions (not implemented yet)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_recov_suggest.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
* `1 or 2`, `1 and 2` => `{1, 2}`?
* `U = Inherit T` => Non-class type cannot be inherited, or `U = Class T`?
* `Int and Str` => Multiple inheritance is not allowed, or `Int or Str`?
diff --git a/doc/JA/compiler/TODO_warn.md b/doc/JA/compiler/TODO_warn.md
index 0ba2ebf2..e03ffd4f 100644
--- a/doc/JA/compiler/TODO_warn.md
+++ b/doc/JA/compiler/TODO_warn.md
@@ -1,5 +1,7 @@
# warnings (not implemented yet)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_warn.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
* `t = {(record type)}` => `T = {(record type)}`? (only types defined as constants can be used for type specification)
* `{I: Int | ...}!` => `{I: Int! | ...}`
* `return x`(`x != ()`) in for/while block => `f::return` (outer block)?
diff --git a/doc/JA/compiler/abandoned.md b/doc/JA/compiler/abandoned.md
index 19bfe876..623476d9 100644
--- a/doc/JA/compiler/abandoned.md
+++ b/doc/JA/compiler/abandoned.md
@@ -1,5 +1,7 @@
# 放棄・却下された言語仕様
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/abandoned.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
## オーバーロード(アドホック多相)
パラメトリック+サブタイピング多相で代替できること、Pythonの意味論との相性の悪さなどを理由に放棄された。詳しくは[overload](../syntax/type/overloading.md)の記事を参照。
diff --git a/doc/JA/compiler/architecture.md b/doc/JA/compiler/architecture.md
index 78d5e5a5..abafdcef 100644
--- a/doc/JA/compiler/architecture.md
+++ b/doc/JA/compiler/architecture.md
@@ -1,42 +1,41 @@
-# Architecture of `ergc`
+# ergc のアーキテクチャ
-## 1. Scan an Erg script (.er) and generate a `TokenStream` (parser/lex.rs)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/architecture.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1)
-* parser/lexer/Lexer generates `TokenStream` (this is an iterator of Token, TokenStream can be generated by lexer.collect())
- * `Lexer` is constructed from `Lexer::new` or `Lexer::from_str`, where `Lexer::new` reads the code from a file or command option.
- * `Lexer` can generate tokens sequentially as an iterator; if you want to get a `TokenStream` all at once, use `Lexer::lex`.
- * `Lexer` outputs `LexError`s as errors, but `LexError` does not have enough information to display itself. If you want to display the error, use the `LexerRunner` to convert the error.
- * `LexerRunner` can also be used if you want to use `Lexer` as standalone; `Lexer` is just an iterator and does not implement the `Runnable` trait.
- * `Runnable` is implemented by `LexerRunner`, `ParserRunner`, `Compiler`, and `VirtualMachine`.
+## 1. Erg スクリプト (.er) をスキャンし、`TokenStream` (parser/lex.rs) を生成する
-## 2. Convert `TokenStream` -> `AST` (parser/parse.rs)
+* parser/lexer/Lexer が `TokenStream` を生成する (これは `Token` のイテレータである。`TokenStream` は `Lexer::collect()` によって生成できる)
+ * `Lexer` は `Lexer::new` または `Lexer::from_str` から構築される。`Lexer::new` はファイルまたはコマンド オプションからコードを読み取る。
+ * `Lexer` はイテレータとしてトークンを順次生成できるので、一度に `TokenStream` を取得したい場合は `Lexer::lex` を使う。
+ * `Lexer` は `LexError` をエラーとして出力するが、`LexError` 自体には表示するだけの情報がない。エラーを表示したい場合は、`LexerRunner` を使用してエラーを変換する。
+ * `Lexer` を単体で使用する場合は、代わりに`LexerRunner` を使用します。`Lexer` は単なるイテレータであり、`Runnable` トレイトを実装していない。
+ * `Runnable` は、 `LexerRunner` 、 `ParserRunner` 、 `Compiler` 、および `DummyVM` に実装されている。
-* `Parser`, like `Lexer`, has two constructors, `Parser::new` and `Parser::from_str`, and `Parser::parse` will give the `AST`.
-* `AST` is the wrapper type of `Vec`. It is for "Abstract Syntax Tree".
+## 2. `TokenStream` -> `AST` (parser/parse.rs)
-### 2.5 Desugaring `AST`
+* `Parser` は `Lexer` と同様に `Parser::new` と `Parser::from_str` の 2 つのコンストラクタを持ち、`Parser::parse` は `AST` を返す。
+* `AST`は`Vec`のラッパー型で、「抽象構文木」を表す。
-* expand nested vars (`Desugarer::desugar_nest_vars_pattern`)
-* desugar multiple pattern definition syntax (`Desugarer::desugar_multiple_pattern_def`)
+### 2.5 `AST`の脱糖
-## 3. Type checking & inference, Convert `AST` -> `HIR` (compiler/lower.rs)
+* ネストされた変数を展開 (`Desugarer::desugar_nest_vars_pattern`)
+* 複数パターン定義構文をmatchへ変換 (`Desugarer::desugar_multiple_pattern_def`)
-* `HIR` has every variable's type information. It is for "High-level Intermediate Representation".
-* `HIR` only holds the type of the variable, but that's enough. In extreme cases, this is because Erg has only conversion (or operator) applications. If we know the type of the conversion, we have already know the type of the object of the argument.
-* `ASTLowerer` can be constructed in the same way as `Parser` and `Lexer`.
-* `ASTLowerer::lower` will output a tuple of `HIR` and `CompileWarnings` if no errors occur.
-* `ASTLowerer` is owned by `Compiler`. Unlike conventional structures, `ASTLowerer` handles code contexts and is not a one-time disposable.
-* If the result of type inference is incomplete (if there is an unknown type variable), an error will occur during name resolution.
+## 3. 型チェックと推論、 `AST` -> `HIR` を変換 (compiler/lower.rs)
-## 4. Check side-effects (compiler/effectcheck.rs)
+* `HIR` は、すべての変数の型情報を持っており、「高レベルの中間表現」を表す。
+* `ASTLowerer は Parser や Lexer と同じように構築できる。
+* `ASTLowerer::lower` は、エラーが発生しなければ、`HIR` と `CompileWarnings` のタプルを出力する。
+* `ASTLowerer` は `Compiler` によって所有されている。 `ASTLowerer` は従来の構造体とは異なり、文脈を保持し、1 回限りの使い捨てではない。
+* 型推論の結果が不完全な場合(未知の型変数がある場合)、名前解決時にエラーが発生する。
-## 4. Check ownerships (compiler/memcheck.rs)
+## 4. 副作用のチェック (compiler/effectcheck.rs)
-## 5. Generate Bytecode (`CodeObj`) from `HIR` (compiler/codegen.rs)
+## 4. 所有権の確認 (compiler/memcheck.rs)
-* From the type information of the expression, name resolution of the quantified subroutines will be performed.
+## 5. `HIR` からバイトコード (`CodeObj`) を生成 (compiler/codegen.rs)
-## (6. (Future plans) Convert Bytecode -> LLVM IR)
+## (6. (今後の予定) バイトコード -> LLVM IR)
-* Bytecode is stack-based, whereas LLVM IR is register-based.
- There will be several more layers of intermediate processes for this conversion process.
+* バイトコードはスタックベースだが、LLVM IR はレジスタベースである。
+ この変換プロセスには、さらにいくつかの中間プロセスのレイヤーが必要となる。
diff --git a/doc/JA/compiler/errors.md b/doc/JA/compiler/errors.md
index 9bdbd8f2..5cfbe4c6 100644
--- a/doc/JA/compiler/errors.md
+++ b/doc/JA/compiler/errors.md
@@ -1,5 +1,7 @@
# Erg Compiler Errors
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/errors.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
## AssignError
イミュータブル変数を書き換えようとすると発生します。
@@ -24,7 +26,7 @@
明らかに停止しない循環を起こしている場合に発生します。
-```erg
+```python
i: Int = i
f(): Int = g()
@@ -91,7 +93,7 @@ SyntaxErrorの派生です。
変数を定義前に使用すると発生します。
正確には、あるスコープ内で定義された変数がそれ以前に使われていると発生します。
-```erg
+```python
i = 0
f x =
y = i + x
@@ -102,7 +104,7 @@ f x =
このコードでは`y = i + x`の`i`が未定義変数になります。
しかし、定数の場合は定義前に別の関数中で呼び出し可能です。
-```erg
+```python
f() = g()
g() = f()
```
@@ -113,7 +115,7 @@ g() = f()
文法上は問題ありませんが、冗長だったり一般的でないコードを検出した際に発生します(不要な`()`など)。
-```erg
+```python
if (True): # SyntaxWarning: unnecessary parentheses
...
```
diff --git a/doc/JA/compiler/hir.md b/doc/JA/compiler/hir.md
index 45748dce..0e8b5262 100644
--- a/doc/JA/compiler/hir.md
+++ b/doc/JA/compiler/hir.md
@@ -1,11 +1,13 @@
# 高レベル中間表現(HIR, High-level Intermediate Representation)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/hir.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
HIRはErgコンパイラがASTから生成する構造体です。
この構造体にはソースコード中のあらゆる式の完全な型情報が含まれており、また構文糖が脱糖されています。
ASTは(プレーンテキストとしての)ソースコードと一対一対応しますが、HIRは不要なコードの情報が除去されていたり、また省略された型情報が付記されたりしているため、HIRからソースコードを復元することは困難です。
以下のコードでHIRの例を見てみましょう。
-```erg
+```python
v = ![]
for! 0..10, i =>
v.push! i
@@ -14,7 +16,7 @@ log v.sum()
このコードから生成されるASTは以下のようになります。
-```erg
+```python
AST(Module[
VarDef{
sig: VarSignature{
@@ -71,7 +73,7 @@ AST(Module[
そしてASTから生成されるHIRは以下のようになります。
-```erg
+```python
HIR(Module[
VarDef{
sig: VarSignature{
diff --git a/doc/JA/compiler/index.md b/doc/JA/compiler/index.md
index e69de29b..33522b77 100644
--- a/doc/JA/compiler/index.md
+++ b/doc/JA/compiler/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/compiler/inference.md b/doc/JA/compiler/inference.md
index 74b79282..c189965c 100644
--- a/doc/JA/compiler/inference.md
+++ b/doc/JA/compiler/inference.md
@@ -1,10 +1,12 @@
# 型推論アルゴリズム
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/inference.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
> __Warning__: この項は編集中であり、一部に間違いを含む可能性があります。
以下で用いる表記方法を示します。
-```erg
+```python
自由型変数(型、未束縛): ?T, ?U, ...
自由型変数(値、未束縛): ?a, ?b, ...
型環境(Γ): { x: T, ... }
@@ -14,7 +16,7 @@
以下のコードを例にして説明します。
-```erg
+```python
v = ![]
v.push! 1
print! v
@@ -100,7 +102,7 @@ pub enum Type {
さて、得られた型スキーム(e.g. `'T -> 'T (idの型スキーム)`)を使用箇所(e.g. `id 1`, `id True`)の型推論で使う際は、一般化を解除する必要があります。この逆変換を __具体化(instantiation)__ と呼びます。操作は`inst`と呼ぶことにします。
-```erg
+```python
gen ?T = 'T
inst 'T = ?T (?T ∉ Γ)
```
@@ -114,7 +116,7 @@ inst 'T = ?T (?T ∉ Γ)
型代入規則`{?T --> X}`は、`?T`と`X`を同一の型とみなすよう書き換えるという意味です。この操作を __単一化(Unification)__ といいます。`X`は型変数もありえます。
単一化の詳しいアルゴリズムは[別の項](./unification.md)で解説します。単一化操作は`unify`と表すことにします。
-```erg
+```python
unify(?T, Int) == Ok(()) # ?T == (Int)
# Sは型代入規則、Tは適用する型
@@ -132,7 +134,7 @@ subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y
というのも、実引数の型は、仮引数の型のサブタイプでなければなりません。
引数の型が型変数の場合は、それを満たすように部分型関係を更新する必要があるのです。
-```erg
+```python
# 仮引数の型をTとすると
f(x: T): T = ...
@@ -147,7 +149,7 @@ f(a)
レベル管理の必要性をみるために、まずはレベル管理を導入しない型推論では問題が起こることを確認します。
以下の無名関数の型を推論してみます。
-```erg
+```python
x ->
y = x
y
@@ -156,7 +158,7 @@ x ->
まず、Ergは以下のように型変数を割り当てます。
yの型も未知ですが、現段階では割り当てないでおきます。
-```erg
+```python
x(: ?T) ->
y = x
y
@@ -165,7 +167,7 @@ x(: ?T) ->
まず決定すべきは右辺値xの型です。右辺値は「使用」なので、具体化します。
しかしxの型`?T`は自由変数なのですでに具体化されています。よってそのまま`?T`が右辺値の型になります。
-```erg
+```python
x(: ?T) ->
y = x (: inst ?T)
y
@@ -173,13 +175,13 @@ x(: ?T) ->
左辺値yの型として登録する際に、一般化します。が、後で判明するようにこの一般化は不完全であり、結果に誤りが生じます。
-```erg
+```python
x(: ?T) ->
y(: gen ?T) = x (: ?T)
y
```
-```erg
+```python
x(: ?T) ->
y(: 'T) = x
y
@@ -187,7 +189,7 @@ x(: ?T) ->
yの型は量化型変数`'T`となりました。次の行で、`y`が早速使用されています。具体化します。
-```erg
+```python
x: ?T ->
y(: 'T) = x
y(: inst 'T)
@@ -195,7 +197,7 @@ x: ?T ->
ここで注意してほしいのが、具体化の際にはすでに存在するどの(自由)型変数とも別の(自由)型変数を生成しなくてはならないという点です(一般化も同様です)。このような型変数をフレッシュ(新鮮)な型変数と呼びます。
-```erg
+```python
x: ?T ->
y = x
y(: ?U)
@@ -207,7 +209,7 @@ x: ?T ->
そこで、型変数のレベルを以下の表記で導入します。レベルは自然数で表します。
-```erg
+```python
# 通常のType型変数
?T<1>, ?T<2>, ...
# 部分型制約を付けられた型変数
@@ -216,7 +218,7 @@ x: ?T ->
では、リトライしてみます。
-```erg
+```python
x ->
y = x
y
@@ -225,7 +227,7 @@ x ->
まず、以下のようにレベル付き型変数を割り当てます。トップレベルのレベルは1です。スコープが深くなるたび、レベルが増えます。
関数の引数は内側のスコープに属するため、関数自身より1大きいレベルにいます。
-```erg
+```python
# level 1
x (: ?T<2>) ->
# level 2
@@ -235,7 +237,7 @@ x (: ?T<2>) ->
先に右辺値`x`を具体化します。先ほどと同じで、何も変わりません。
-```erg
+```python
x (: ?T<2>) ->
y = x (: inst ?T<2>)
y
@@ -245,11 +247,11 @@ x (: ?T<2>) ->
さきほどはここで結果がおかしくなっていましたので、一般化のアルゴリズムを変更します。
もし型変数のレベルが現在のスコープのレベル以下なら、一般化しても変化がないようにします。
-```erg
+```python
gen ?T = if n <= current_level, then= ?T, else= 'T
```
-```erg
+```python
x (: ?T<2>) ->
# current_level = 2
y (: gen ?T<2>) = x (: ?T<2>)
@@ -258,7 +260,7 @@ x (: ?T<2>) ->
つまり、左辺値`y`の型は`?T<2>`です。
-```erg
+```python
x (: ?T<2>) ->
# ↓ not generalized
y (: ?T<2>) = x
@@ -267,13 +269,13 @@ x (: ?T<2>) ->
yの型は未束縛型変数`?T<2>`となりました。次の行で具体化します。が、`y`の型は一般化されていないので、何も起こりません。
-```erg
+```python
x (: ?T<2>) ->
y (: ?T<2>) = x
y (: inst ?T<2>)
```
-```erg
+```python
x (: ?T<2>) ->
y = x
y (: ?T<2>)
@@ -283,7 +285,7 @@ x (: ?T<2>) ->
もう1つの例を見ます。こちらは更に一般的なケースで、関数・演算子適用、前方参照がある場合です。
-```erg
+```python
f x, y = id(x) + y
id x = x
@@ -296,7 +298,7 @@ f 10, 1
このような場合、`f`の前に`id`の宣言を仮想的に挿入し、自由型変数を割り当てておきます。
このときの型変数のレベルは`current_level`であることに注意してください。これは、他の関数内で一般化されないようにするためです。
-```erg
+```python
id: ?T<1> -> ?U<1>
f x (: ?V<2>), y (: ?W<2>) =
id(x) (: subst_call_ret([inst ?V<2>], inst ?T<1> -> ?U<1>)) + y
@@ -308,7 +310,7 @@ f x (: ?V<2>), y (: ?W<2>) =
型変数同士の半単一化では、少し事情が違います。
違うレベルの型変数の場合、相互に型制約をかけてはいけません。
-```erg
+```python
# BAD
f x (: ?V<2>), y (: ?W<2>) =
# ?V<2>(<: ?T<1>)
@@ -320,24 +322,24 @@ f x (: ?V<2>), y (: ?W<2>) =
Type型変数同士の場合、半単一化ではなく、通常の単一化を行います。
つまり、レベルの低い方に単一化させます。
-```erg
+```python
# OK
f x (: ?V<2>), y (: ?W<2>) =
# ?V<2> --> ?T<1>
id(x) (: ?U<1>) + y (: ?W<2>)
```
-```erg
+```python
f x (: ?T<1>), y (: ?W<2>) =
(id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], inst |'L <: Add('R)| ('L, 'R) -> 'L.AddO)
```
-```erg
+```python
f x (: ?T<1>), y (: ?W<2>) =
(id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], (?L(<: Add(?R<2>))<2>, ?R<2>) -> ?L<2>.AddO)
```
-```erg
+```python
id: ?T<1> -> ?U<1>
f x (: ?T<1>), y (: ?W<2>) =
# ?U<1>(<: Add(?W<2>)) # ?Lの制約を引き継ぐ
@@ -346,26 +348,26 @@ f x (: ?T<1>), y (: ?W<2>) =
(id(x) + x) (: ?U<1>.AddO)
```
-```erg
+```python
# current_level = 1
f(x, y) (: gen ?T<1>, gen ?W<2> -> gen ?U<1>.AddO) =
id(x) + x
```
-```erg
+```python
id: ?T<1> -> ?U<1>
f(x, y) (: |'W: Type| (?T<1>, 'W) -> gen ?U<1>(<: Add(?W<2>)).AddO) =
id(x) + x
```
-```erg
+```python
f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) =
id(x) + x
```
定義の際には一般化できるようにレベルを上げます。
-```erg
+```python
# ?T<1 -> 2>
# ?U<1 -> 2>
id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>)
@@ -373,7 +375,7 @@ id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>)
戻り値型が既に割り当てられている場合は、得られた型と単一化します(`?U<2> --> ?T<2>`)。
-```erg
+```python
# ?U<2> --> ?T<2>
f(x, y) (: |'W: Type| (?T<2>, 'W) -> ?T<2>(<: Add(?W<2>)).AddO) =
id(x) + x
@@ -385,13 +387,13 @@ id(x) (: gen ?T<2> -> gen ?T<2>) = x (: ?T<2>)
それに依存する型変数も同じくType型変数になります。
一般化された型変数は各関数で独立です。
-```erg
+```python
f(x, y) (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) =
id(x) + x
id(x) (: |'T: Type| 'T -> gen 'T) = x
```
-```erg
+```python
f x, y (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) =
id(x) + y
id(x) (: 'T -> 'T) = x
@@ -399,13 +401,13 @@ id(x) (: 'T -> 'T) = x
f(10, 1) (: subst_call_ret([inst {10}, inst {1}], inst |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO)
```
-```erg
+```python
f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<1>) -> ?T<1>.AddO))
```
型変数は、実装のある最小の型まで上限が拡大されます。
-```erg
+```python
# ?T(:> {10} <: Add(?W<1>))<1>
# ?W(:> {1})<1>
# ?W(:> {1})<1> <: ?T<1> (:> {10}, <: Add(?W(:> {1})<1>))
@@ -421,7 +423,7 @@ f(10, 1) (: ({10}, {1}) -> Nat)
結果として、プログラム全体の型はこうなります。
-```erg
+```python
f|W: Type, T <: Add(W)|(x: T, y: W): T.AddO = id(x) + y
id|T: Type|(x: T): T = x
@@ -430,7 +432,7 @@ f(10, 1): Nat
元の明示的に型付けられていないプログラムも再掲しておきます。
-```erg
+```python
f x, y = id(x) + y
id x = x
diff --git a/doc/JA/compiler/overview.md b/doc/JA/compiler/overview.md
index 0536bfce..d64ad9d5 100644
--- a/doc/JA/compiler/overview.md
+++ b/doc/JA/compiler/overview.md
@@ -1,5 +1,7 @@
# `erg`の概観
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/overview.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
各レイヤーの働きと特に重要な関数、メソッドを紹介します。
## 1. 字句解析
diff --git a/doc/JA/compiler/parsing.md b/doc/JA/compiler/parsing.md
index aa6ed05c..f9cc8989 100644
--- a/doc/JA/compiler/parsing.md
+++ b/doc/JA/compiler/parsing.md
@@ -1,11 +1,13 @@
# Erg言語の構文解析
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/parsing.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
## 空白の扱い
Ergの文法において特異なのは、space-sensitive(空白による区別がある)である点である。
これは、`()`の省略による表現力の低下を補うためである。同様の文法は同じく`()`を省略可能なNimでも見られる。
-```erg
+```python
f +1 == f(+1)
f + 1 == `+`(f, 1)
f (1,) == f((1,))
@@ -20,7 +22,7 @@ Ergにおいて左辺値とは`=`の左側といった単純なものではな
実際、(非常に紛らわしいが)`=`の左側にも右辺値は存在するし、`=`の右側にも左辺値が存在する。
右辺値の中に左辺値が存在することさえある。
-```erg
+```python
# iは左辺値、Array(Int)と[1, 2, 3]は右辺値
i: Array(Int) = [1, 2, 3]
# `[1, 2, 3].iter().map i -> i + 1`は右辺値だが、->の左側のiは左辺値
diff --git a/doc/JA/compiler/refinement_subtyping.md b/doc/JA/compiler/refinement_subtyping.md
index a66ca5da..16646bca 100644
--- a/doc/JA/compiler/refinement_subtyping.md
+++ b/doc/JA/compiler/refinement_subtyping.md
@@ -1,8 +1,10 @@
# 篩型
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/refinement_subtyping.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
篩型とは、以下のような型である。
-```erg
+```python
{I: Int | I >= 0}
{S: StrWithLen N | N >= 1}
{T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0}
diff --git a/doc/JA/compiler/trait_method_resolving.md b/doc/JA/compiler/trait_method_resolving.md
index b7f8cf25..3b4cf570 100644
--- a/doc/JA/compiler/trait_method_resolving.md
+++ b/doc/JA/compiler/trait_method_resolving.md
@@ -1,9 +1,11 @@
# パッチメソッドの解決
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/trait_method_resolving.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
`Nat`は0以上の`Int`、つまり`Int`のサブタイプである。
本来`Nat`はPythonのクラス階層には存在しない。Ergはこのパッチのメソッドをどうやって解決するのだろうか?
-```erg
+```python
1.times do:
log "hello, world"
```
@@ -27,7 +29,7 @@ Ergは`Int`のMROに`Int`, `Object`を持っている。これはPython由来で
Ergコンパイラは、全ての提供メソッドとその実装を持つパッチ・型のハッシュマップを持っている。
このテーブルは型が新たに定義されるたびに更新される。
-```erg
+```python
provided_method_table = {
...
"foo": [Foo],
@@ -58,7 +60,7 @@ provided_method_table = {
両者に包含関係がない場合は、コンパイルエラーとなる(これはプログラマーの意図に反したメソッドが実行されないための安全策である)。
エラーを解消させるためには、パッチを明示的に指定する必要がある。
-```erg
+```python
o.method(x) -> P.method(o, x)
```
@@ -66,20 +68,20 @@ o.method(x) -> P.method(o, x)
以下のようなパッチを定義する。
-```erg
+```python
FnType T: Type = Patch T -> T
FnType.type = T
```
`FnType`パッチのもとで以下のようなコードが可能である。これはどのように解決されるのだろうか。
-```erg
+```python
assert (Int -> Int).type == Int
```
まず、`provided_method_table`には`FnType(T)`が以下の形式で登録される。
-```erg
+```python
provided_method_table = {
...
"type": [FnType(T)],
@@ -90,6 +92,6 @@ provided_method_table = {
`FnType(T)`のパッチする型が適合するかチェックされる。この場合、`FnType(T)`のパッチ型は`Type -> Type`である。
これは`Int -> Int`に適合する。適合したら、単相化を行って置換する(`T -> T`と`Int -> Int`のdiffを取る。`{T => Int}`)。
-```erg
+```python
assert FnType(Int).type == Int
```
diff --git a/doc/JA/compiler/transpile.md b/doc/JA/compiler/transpile.md
index 90e41482..61cd54fe 100644
--- a/doc/JA/compiler/transpile.md
+++ b/doc/JA/compiler/transpile.md
@@ -1,5 +1,7 @@
# ErgコードはPythonコードにどのようにトランスパイルされるか?
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/transpile.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
正確には、ErgコードはPythonバイトコードにトランスパイルされます。
しかしPythonバイトコードはほぼPythonコードに復元できるので、ここでは等価なPythonコードを例として上げています。
ちなみに、ここで紹介する例は最適化レベルの低いものです。
@@ -11,7 +13,7 @@ namedtupleにトランスパイルされます。
namedtupleについては、[こちら](https://docs.python.jp/3/library/collections.html#collections.namedtuple)を参照してください。
似たような機能にdataclassがありますが、dataclassは`__eq__`や`__hash__`が自動実装されるなどの影響で少しパフォーマンスが落ちます。
-```erg
+```python
Employee = Class {.name = Str; .id = Int}
employee = Employee.new({.name = "John Smith"; .id = 100})
@@ -43,7 +45,7 @@ assert employee.name == 'John Smith'
名前空間内での衝突が起きない場合は、単にマングリングして展開されます。
`x::y`などの名前はバイトコードで使用されるものでPythonコードと対応させる事はできませんが、無理やり表現すると以下のようになります。
-```erg
+```python
x =
y = 1
y + 1
@@ -56,7 +58,7 @@ x = x::y + 1
衝突する場合は、内部的にしか参照できない関数を定義して使用します。
-```erg
+```python
x =
y = 1
y + 1
@@ -75,7 +77,7 @@ x = _()
公開変数に関してはPythonのデフォルトなので何もしません。
非公開変数はマングリングで対処しています。
-```erg
+```python
x = 1
y =
x = 2
diff --git a/doc/JA/compiler/type_var_normalization.md b/doc/JA/compiler/type_var_normalization.md
index 66bb2962..2a2e46cc 100644
--- a/doc/JA/compiler/type_var_normalization.md
+++ b/doc/JA/compiler/type_var_normalization.md
@@ -1,5 +1,7 @@
# 正規化
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/type_var_normalization.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
* Ergの型引数正規化はSymPyのsimplify関数を参考にしています。
例えば`concat: |T, M, N|([T; M], [T; N] -> [T; M+N])`を定義するとき、型変数・引数を具体化せずに一致判定を行わなくてはならない。
diff --git a/doc/JA/dev_guide/branches.md b/doc/JA/dev_guide/branches.md
index c8eeb9a1..12d422b6 100644
--- a/doc/JA/dev_guide/branches.md
+++ b/doc/JA/dev_guide/branches.md
@@ -1,5 +1,7 @@
# ブランチの命名と運用方針
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/branches.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1)
+
* 基本的に開発は`main`ブランチ一本で行う(モノレポ開発)。どうしてもブランチを切らないと作業しにくい場合のみ`feature-*`ブランチか`issue-*`ブランチを作成する。
## main
@@ -29,3 +31,9 @@
* 特定のissueを解決するブランチ
* 条件なし
+
+## fix-*
+
+* 特定のバグを解決するブランチ(issueがバグの場合に、`issue-*`の代わりに作成する)
+
+* 条件なし
diff --git a/doc/JA/dev_guide/build_features.md b/doc/JA/dev_guide/build_features.md
index f437b1c8..77d7a93a 100644
--- a/doc/JA/dev_guide/build_features.md
+++ b/doc/JA/dev_guide/build_features.md
@@ -1,5 +1,7 @@
# `erg` build features
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/build_features.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
## debug
デバッグモードにする。これにより、Erg内部での挙動が逐次ログ表示される。
@@ -12,8 +14,10 @@ Erg内部のオプション、ヘルプ(help, copyright, licenseなど)、エラ
## simplified_chinese
-システム言語を簡体字中国語にする。
+システム言語を簡体字中国語に設定します。
+Erg 内部オプション、ヘルプ (ヘルプ、著作権、ライセンスなど)、エラーは簡体字中国語で表示されます。
## traditional_chinese
-システム言語を繁体字中国語にする。
+システム言語を繁体字中国語に設定します。
+Erg 内部オプション、ヘルプ (ヘルプ、著作権、ライセンスなど)、エラーは繁体字中国語で表示されます。
\ No newline at end of file
diff --git a/doc/JA/dev_guide/directories.md b/doc/JA/dev_guide/directories.md
index 1eb0c60c..8f0e5b6d 100644
--- a/doc/JA/dev_guide/directories.md
+++ b/doc/JA/dev_guide/directories.md
@@ -1,5 +1,7 @@
# Ergリポジトリのディレクトリ構造
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/directories.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1)
+
```console
└─┬ assets: 画像など
├─ CODE_OF_CONDUCT: 行動規範
diff --git a/doc/JA/dev_guide/doc_guideline.md b/doc/JA/dev_guide/doc_guideline.md
index abcc87a2..1af3a61b 100644
--- a/doc/JA/dev_guide/doc_guideline.md
+++ b/doc/JA/dev_guide/doc_guideline.md
@@ -1,5 +1,7 @@
# 書式
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/doc_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
以下のルールに従っていないドキュメントはすべて修正の対象となる。
* コードコメント、または内部用のドキュメントは、である調で書く。
diff --git a/doc/JA/dev_guide/env.md b/doc/JA/dev_guide/env.md
index c85aa280..1d4bdb77 100644
--- a/doc/JA/dev_guide/env.md
+++ b/doc/JA/dev_guide/env.md
@@ -1,5 +1,7 @@
# 開発環境
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
## インストールが必要なもの
* Rust (installed with rustup)
diff --git a/doc/JA/dev_guide/faq_syntax.md b/doc/JA/dev_guide/faq_syntax.md
index 7972ae30..59456aeb 100644
--- a/doc/JA/dev_guide/faq_syntax.md
+++ b/doc/JA/dev_guide/faq_syntax.md
@@ -1,5 +1,7 @@
# Erg design's "Why" and Answers
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/faq_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
## なぜ所有権システムがあるのにGCも共存させているのですか?
Ergが所有権システムを導入した動機は、Rustのような「GCに頼らないメモリ管理」のためではないからです。
@@ -11,7 +13,7 @@ Ergが所有権システムを導入した狙いは「可変状態の局所化
`<>`や`[]`では文法の衝突が起きるからです。
-```erg
+```python
# []版
id[T: Type] [t]: [T] = t
y = id[Int] # これは関数?
@@ -30,7 +32,7 @@ y = id|Int| # OK
Ergは型自体も値として扱える設計になっているためです。
-```erg
+```python
A = [Int; 3]
assert A[2] == Int
T = (Int, Str)
@@ -53,7 +55,7 @@ assert S.i == Int
Ergでは`?`演算子によってエラーをあまり意識せずに書けます。
-```erg
+```python
read_file!() =
f = open!("foo.txt")? # 失敗したらエラーをすぐさま返すので、fはFile型
f.read_all!()
@@ -84,7 +86,7 @@ Pythonのライブラリには継承されることを前提に設計されて
デフォルトで構造的トレイトを指すと、型指定が複雑になり、プログラマの意図しない挙動を混入させる恐れがあるためです。
-```erg
+```python
# If T is a subtype of a structural trait...
# f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T
f|T| x, y: T = x + y - x
diff --git a/doc/JA/dev_guide/i18n_messages.md b/doc/JA/dev_guide/i18n_messages.md
index 675d3f3d..5a971cb4 100644
--- a/doc/JA/dev_guide/i18n_messages.md
+++ b/doc/JA/dev_guide/i18n_messages.md
@@ -1,4 +1,6 @@
-# Multilingualization of Messages
+# メッセージの多言語化
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/i18n_messages.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
Ergはメッセージ(スタート、オプション、ドキュメント、ヒント、警告、エラーメッセージなど)の多言語化を進めています。
このプロジェクトは、RustやErgの詳しい知識がなくても参加することができます。ぜひ協力をお願いします。
@@ -34,7 +36,7 @@ switch_lang!(
なお、英語はデフォルトであり、必ず最後に来るようにします。
`{name}` の部分は Rust のフォーマット機能で、変数の内容 (`name`) を文字列に埋め込むことができます。
-## Build
+## ビルド
では、`--features simplified_chinese` オプションを付けてビルドしてみましょう。
@@ -53,6 +55,6 @@ A: 現在、以下の言語がサポートされています。
* "english" (デフォルト)
* "japanese" (日本語)
* "simplified_chinese" (簡体字中国語)
-* "traditional_chinese"(繁体字中国語)
+* "traditional_chinese"(繁体字中国語)
これら以外の言語を追加したい場合は、リクエストしてください。
diff --git a/doc/JA/dev_guide/index.md b/doc/JA/dev_guide/index.md
index e69de29b..5406f3f8 100644
--- a/doc/JA/dev_guide/index.md
+++ b/doc/JA/dev_guide/index.md
@@ -0,0 +1,3 @@
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/index.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96)
+
diff --git a/doc/JA/dev_guide/rust_code_guideline.md b/doc/JA/dev_guide/rust_code_guideline.md
index cf090732..01f62696 100644
--- a/doc/JA/dev_guide/rust_code_guideline.md
+++ b/doc/JA/dev_guide/rust_code_guideline.md
@@ -1,5 +1,7 @@
# Rustコードに関するガイドライン
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/rust_code_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
## ローカルルール
* デバッグ用の出力には`log!`を使用する(release時にも必要な出力処理は`println!`等を使用する)。
diff --git a/doc/JA/dev_guide/terms.md b/doc/JA/dev_guide/terms.md
index fa079ffb..c47fd4e2 100644
--- a/doc/JA/dev_guide/terms.md
+++ b/doc/JA/dev_guide/terms.md
@@ -1,5 +1,7 @@
# 用語辞典
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
## 記号
### !
@@ -237,7 +239,7 @@
コード中である条件が成立しているか(典型的には実行時に)調べること。`assert`関数などを使用して行う。
-```erg
+```python
sum = !0
for! 0..10, i =>
sum.add! i
@@ -282,7 +284,7 @@ Ergにおいては、基本オブジェクトと同等。コンパイル時に
### [インスタントブロック](../syntax/00_basic.md#式セパレータ)
-```erg
+```python
x =
y = f(a)
z = g(b, c)
@@ -644,7 +646,7 @@ APIとして利用可能な属性。特に、トレイトによって自動実
### [デコレータ](../syntax/29_decorator.md)
-```erg
+```python
@deco
f x = ...
```
diff --git a/doc/JA/dev_guide/unify_terms.md b/doc/JA/dev_guide/unify_terms.md
index fde909fa..a85fe9e4 100644
--- a/doc/JA/dev_guide/unify_terms.md
+++ b/doc/JA/dev_guide/unify_terms.md
@@ -1,5 +1,7 @@
# 用語の統一
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/unify_terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
## Accessibility, Visibility (参照性、可視性)
Visibility(可視性)を使用する。
@@ -51,7 +53,7 @@ Visibility(可視性)を使用する。
* 名前(Name): 識別子とほぼ同じ意味。Ergにおいては代数と同じ意味で使われることもある。
* 代数名(Algebra name): Ergにおいては識別子と同等の意味。C言語では関数名は識別子だが代数名ではない。「代数」は`=`(変数代入演算子)または`=`(定数代入演算子)でオブジェクトを代入できるという言語機能自体を指す。
-```erg
+```python
代数名 <: (名前 == 識別子) <: シンボル
変数 + 定数 == 代数
```
diff --git a/doc/JA/faq_general.md b/doc/JA/faq_general.md
index 9d2b4fac..f950b405 100644
--- a/doc/JA/faq_general.md
+++ b/doc/JA/faq_general.md
@@ -1,5 +1,7 @@
# Erg FAQ
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_general.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
このFAQは一般のErg入門者向けです。
個別の(よくある)技術的な問題については[こちら](./faq_technical.md)を、文法の決定経緯(なぜこのような文法になったのか)などについては
[こちら](./dev_guide/why.md)を参照してください。
diff --git a/doc/JA/faq_technical.md b/doc/JA/faq_technical.md
index affbc713..70a42fde 100644
--- a/doc/JA/faq_technical.md
+++ b/doc/JA/faq_technical.md
@@ -1,5 +1,7 @@
# 技術的なFAQ
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_technical.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e)
+
本項はErg言語を使用する上での技術的な質問に答えるものです。すなわち、WhatやWhichで始まる質問、Yes/Noで答えられる質問を載せています。
根本的な文法の決定経緯については[こちら](./dev_guide/faq_syntax.md)を、なぜこの言語を作ったのか、この機能はどのように実装されているのかなど、より大きな話題は[こちら](./dev_guide/../faq_general.md)を参照してください。
diff --git a/doc/JA/improved_points.md b/doc/JA/improved_points.md
index eb3d7f51..1bf003ca 100644
--- a/doc/JA/improved_points.md
+++ b/doc/JA/improved_points.md
@@ -1,5 +1,7 @@
# Pythonから改良された点
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/improved_points.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
## 静的解析を行う(静的型チェック、変数・プロパティチェック)
静的型チェックの恩恵は今更強調するまでもないほどですが、変数・プロパティの存在チェックもかなり効いてくる部分です。
diff --git a/doc/JA/index.md b/doc/JA/index.md
index db3516f8..fa32a045 100644
--- a/doc/JA/index.md
+++ b/doc/JA/index.md
@@ -1,5 +1,7 @@
# Index
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/index.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
## [API/](./API/index.md)
Ergの組み込みまたは標準ライブラリで提供されるサブルーチン、型、定数等の仕様が記述されている。
diff --git a/doc/JA/migration_from_py.md b/doc/JA/migration_from_py.md
index 4ad1c57b..f04421f0 100644
--- a/doc/JA/migration_from_py.md
+++ b/doc/JA/migration_from_py.md
@@ -1,5 +1,7 @@
# PythonからErgへの移行に関してのTips
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/migration_from_py.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
## 文字列をint等に変換したい
`Str`クラスの`parse`メソッドを使用してください。これは`Result`型を返します。
@@ -9,7 +11,7 @@ s: str
i: int = int(s)
```
-```erg
+```python
s: Str
res: Result(Int, IntParseError) = s.parse Int
i: Int = res.unwrap()
@@ -18,7 +20,7 @@ f: Result(Float, FloatParseError) = s.parse Float
`try_from`メソッドも使えます。
-```erg
+```python
s: Str
i: Int = Int.try_from(s).unwrap()
f: Float = Float.try_from(s).unwrap()
diff --git a/doc/JA/python/bytecode_instructions.md b/doc/JA/python/bytecode_instructions.md
index 6e625360..6724701a 100644
--- a/doc/JA/python/bytecode_instructions.md
+++ b/doc/JA/python/bytecode_instructions.md
@@ -1,5 +1,7 @@
# Python Bytecode Instructions
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_instructions.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
Python bytecodeの変数操作系の命令はnamei (name index)を通してアクセスされる。これは、Pythonの動的変数アクセス(evalなどを使い、文字列でアクセスできる)を実現するためである。
1命令は2byteで、命令、引数がlittle endianで格納されている。
引数を取らない命令も2byte使っている(引数部は0)。
diff --git a/doc/JA/python/bytecode_specification.md b/doc/JA/python/bytecode_specification.md
index cf52911d..80306797 100644
--- a/doc/JA/python/bytecode_specification.md
+++ b/doc/JA/python/bytecode_specification.md
@@ -1,5 +1,7 @@
# Python bytecode specification
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_specification.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)
+
## Format
* 0~3 byte(u32): magic number (see common/bytecode.rs for details)
diff --git a/doc/JA/python/class_system.md b/doc/JA/python/class_system.md
index dfaf5620..158a5340 100644
--- a/doc/JA/python/class_system.md
+++ b/doc/JA/python/class_system.md
@@ -1,5 +1,7 @@
# Pythonのクラスシステム(Ergとの比較)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/class_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
## メソッド
メソッドは前方参照していてもかまわないが、これは特別なテクニックが使われているわけではなく、
@@ -51,7 +53,7 @@ TypeError: can only concatenate str (not "int") to str
Ergでは親クラスとの整合性が静的に検査される。
オーバーライド時には`Override`デコレータを付与する必要があり、オーバーライドする関数の型はされる関数の型の部分型とならなくてはならない。
-```erg
+```python
>>> C = Class()
... .f self = 1
... .g self = self.f() + 1
@@ -81,7 +83,7 @@ f(c)
f(1) # TypeError
```
-```erg
+```python
# f: |T, X <: {.m = Self.() -> T}| X -> T
f(x) = x.m()
diff --git a/doc/JA/python/index.md b/doc/JA/python/index.md
index e69de29b..2168ad9d 100644
--- a/doc/JA/python/index.md
+++ b/doc/JA/python/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/index.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)
+
diff --git a/doc/JA/syntax/00_basic.md b/doc/JA/syntax/00_basic.md
index 09c298a6..21aada11 100644
--- a/doc/JA/syntax/00_basic.md
+++ b/doc/JA/syntax/00_basic.md
@@ -1,5 +1,7 @@
# 基本事項
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
> __Warning__: 本ドキュメントは未完成です。校正(文体、正しいリンクが張られているか、など)がなされていません。また、Ergの文法はバージョン0.*の間に破壊的変更が加えられる可能性があり、それに伴うドキュメントの更新が追いついていない可能性があります。予めご了承ください。
> また、本ドキュメントの誤りを見つけた場合は、[こちらのフォーム](https://forms.gle/HtLYRfYzWCAaeTGb6)または[GitHubリポジトリ](https://github.com/mtshiba/TheErgBook/issues/new)から修正の提案をしていただけると幸いです。
@@ -9,7 +11,7 @@
まずは恒例の、Hello Worldを行いましょう。
-```erg
+```python
print!("Hello, World!")
```
@@ -17,7 +19,7 @@ Pythonや同系統の言語とほぼ同じです。目を引くのは`print`の
また、Ergでは解釈に紛れのない限り括弧`()`を省略することが出来ます。
括弧の省略ができるのはRubyと似ていますが、複数の解釈ができる括弧省略はできませんし、また引数が0個のときもPythonと同じく`()`の省略が出来ません。
-```erg
+```python
print! "Hello, World!" # OK
print! "Hello,", "World!" # OK
print!() # OK
@@ -40,7 +42,7 @@ Ergのコードはスクリプトと呼ばれます。スクリプトはファ
`#`以降はコメントとして無視されます。コードの意図を説明したいときや一時的にコードを無効化したいときなどに使います。
-```erg
+```python
# コメント
## `#`以降は改行されるまで無視されるので、`#`は何個あってもOK
#[
@@ -55,7 +57,7 @@ Ergのコードはスクリプトと呼ばれます。スクリプトはファ
各式はセパレータ―改行かセミコロン`;`―で区切ります。
Ergのスクリプトは基本的に左から右へ、上から下へ評価されます。
-```erg
+```python
n = 1 # 代入式
f(1, 2) # 関数適用式
1 + 1 # 演算子適用式
@@ -65,7 +67,7 @@ f(1, 2); 1 + 1
以下のように、ブロック内で最後に評価した式を変数の値とするインスタントブロックという機能があります。
これは引数なし関数とは違い、`()`をつけません。ブロックがその場で1度だけ評価されることに注意してください。
-```erg
+```python
i =
x = 1
x + 1
@@ -74,7 +76,7 @@ assert i == 2
これはセミコロン(`;`)では実現できません。
-```erg
+```python
i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses
```
@@ -82,7 +84,7 @@ i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses
ErgはPythonと同じくインデントを使ってブロックを表します。ブロックの開始を示すトリガーとなる演算子(特殊形式)は、`=`, `->`, `=>`, `do`, `do!`の5種類です(その他に、演算子ではありませんが`:`と`|`もインデントを生成します)。それぞれの意味は後述します。
-```erg
+```python
f x, y =
x + y
@@ -101,7 +103,7 @@ ans = match x:
また1行が長くなりすぎる場合、`\`を使って途中で改行させることができます。
-```erg
+```python
# this does not means `x + y + z` but means `x; +y; +z`
x
+ y
diff --git a/doc/JA/syntax/01_literal.md b/doc/JA/syntax/01_literal.md
index 456b3ff3..06161971 100644
--- a/doc/JA/syntax/01_literal.md
+++ b/doc/JA/syntax/01_literal.md
@@ -1,22 +1,24 @@
# Literal
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/01_literal.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
## 基本的なリテラル
### 整数リテラル(Int Literal)
-```erg
+```python
0, -0, 1, -1, 2, -2, 3, -3, ...
```
### 有理数リテラル(Ratio Literal)
-```erg
+```python
0.00, -0.0, 0.1, 400.104, ...
```
`Ratio`リテラルで整数部分または小数部分が`0`のときは、その`0`を省略できます。
-```erg
+```python
assert 1.0 == 1.
assert 0.5 == .5
```
@@ -29,14 +31,14 @@ assert 0.5 == .5
Unicodeで表現可能な文字列は、すべて使用できます。
Pythonとは違い、`'`ではクオーテーション(囲み)できません。文字列の中で`"`を使いたいときは`\"`としてください。
-```erg
+```python
"", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "السَّلَامُ عَلَيْكُمْ", ...
```
`{}`によって文字列の中に式を埋めこめます。これを文字列補間(string interpolation)といいます。
`{`, `}`自体を出力したい場合は`\{`, `\}`とします。
-```erg
+```python
assert "1 + 1 is 2" == "{1} + {1} is {1+1}"
s = "1+1"
assert "\{1+1}\" == "\{{s}\}"
@@ -47,11 +49,11 @@ assert "\{1+1}\" == "\{{s}\}"
これは学術計算でよく使用される指数表記を表すリテラルです。`Ratio`型のインスタンスになります。
非常に大きな/小さな数を表すときに使用します。Pythonと表記法は同じです。
-```erg
+```python
1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ...
```
-```erg
+```python
assert 1e-10 == 0.0000000001
```
@@ -61,37 +63,37 @@ assert 1e-10 == 0.0000000001
### [配列リテラル(Array Literal)](./10_array.md)
-```erg
+```python
[], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ...
```
### [辞書リテラル(Dict Literal)](./11_dict.md)
-```erg
+```python
{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
```
### [組リテラル(Tuple Literal)](./12_tuple.md)
-```erg
+```python
(), (1, 2, 3), (1, "hello", True), ...
```
### [レコードリテラル(Record Literal)](./13_record.md)
-```erg
+```python
{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
```
### [集合リテラル(Set Literal)](./14_set.md)
-```erg
+```python
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ...
```
`Array`リテラルとの違いとして、`Set`では重複する要素が取り除かれます。
-```erg
+```python
assert {1, 2, 1} == {1, 2}
```
@@ -99,19 +101,19 @@ assert {1, 2, 1} == {1, 2}
## 真偽値オブジェクト(Boolean Object)
-```erg
+```python
True, False
```
### Noneオブジェクト
-```erg
+```python
None
```
## 範囲オブジェクト(Range Object)
-```erg
+```python
assert 0..5 == {1, 2, 3, 4, 5}
assert 0..10 in 5
assert 0..<10 notin 10
@@ -120,7 +122,7 @@ assert 0..9 == 0..<10
## 浮動小数点数オブジェクト(Float Object)
-```erg
+```python
assert 0.0f64 == 0
assert 0.0f32 == 0.0f64
```
@@ -129,7 +131,7 @@ assert 0.0f32 == 0.0f64
## 複素数オブジェクト(Complex Object)
-```erg
+```python
1+2im, 0.4-1.2im, 0im, im
```
@@ -140,7 +142,7 @@ assert 0.0f32 == 0.0f64
Ergでは、解釈に紛れがない限り乗算を表す`*`を省略できます。
ただし、演算子の結合強度は`*`よりも強く設定されています。
-```erg
+```python
# same as `assert (1*m) / (1*s) == 1*(m/s)`
assert 1m / 1s == 1 (m/s)
```
diff --git a/doc/JA/syntax/02_name.md b/doc/JA/syntax/02_name.md
index bd18402f..17a5056d 100644
--- a/doc/JA/syntax/02_name.md
+++ b/doc/JA/syntax/02_name.md
@@ -1,11 +1,13 @@
# 変数
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
変数は代数の一種です。Ergにおける代数―紛れがなければ単に変数と呼ばれることもあります―とは、オブジェクトを名前付けしてコード中の別の場所から利用できるようにする機能を指します。
変数は以下のように定義します。
`n`の部分を変数名(または、識別子)、`=`を代入演算子、`1`の部分を代入値と呼びます。
-```erg
+```python
n = 1
```
@@ -15,13 +17,13 @@ n = 1
変数の「型」を指定したい場合は以下のようにします。型とは、これも後述しますが、大まかにはオブジェクトの属する集合です。
ここでは`n`は自然数(`Nat`)型であると指定しています。
-```erg
+```python
n: Nat = 1
```
他の言語とは違い、多重代入はできないので注意してください。
-```erg
+```python
# NG
l1 = l2 = [1, 2, 3] # SyntaxError: 多重代入はできません
# OK
@@ -31,7 +33,7 @@ l2 = l1.clone()
また、変数への再代入もできません。その代わりに使える機能、すなわち可変な状態を保持する機能については後述します。
-```erg
+```python
i = 1
i = i + 1 # AssignError: cannot assign twice
```
@@ -40,7 +42,7 @@ i = i + 1 # AssignError: cannot assign twice
これはPythonの「文」のスコープとは違う挙動なので注意してください。
このような機能は一般にシャドーイングと言います。ただし他言語のシャドーイングとは違い同一スコープではシャドーイングできません。
-```erg
+```python
x = 0
# x = 1 # AssignError: cannot assign twice
if x.is_zero(), do:
@@ -51,7 +53,7 @@ assert x == 0
以下は一見すると可能なように思えますが、やはりできません。これは技術的な制約ではなく、設計判断です。
-```erg
+```python
x = 0
if x.is_zero(), do:
x = x + 1 # NameError: cannot define variables refer to variables with the same name
@@ -64,7 +66,7 @@ assert x == 0
定数も代数の一種です。識別子を大文字で始めると定数として扱われます。一度定義したら変わらないので、定数と呼ばれます。
`N`の部分を定数名(または、識別子)と呼びます。その他は変数と同じです。
-```erg
+```python
N = 0
if True, do:
N = 1 # AssignError: constants cannot be shadowed
@@ -77,13 +79,13 @@ if True, do:
定数は、数学的定数、外部リソースに関する情報など不変な値に対して使用すると良いでしょう。
[型](./type/01_type_system.md)以外のオブジェクトは、オールキャップス(全ての文字を大文字にするスタイル)にするのが一般的です。
-```erg
+```python
PI = 3.141592653589793
URL = "https://example.com"
CHOICES = ["a", "b", "c"]
```
-```erg
+```python
PI = 3.141592653589793
match! x:
PI => print! "π"
@@ -95,7 +97,7 @@ match! x:
定数には代入できないものがあります。可変オブジェクトなどです。詳しくは後述しますが、可変オブジェクトは内容を変更することができるオブジェクトです。
これは定数には定数式のみを代入できるという規則があるためです。定数式についても後述することとします。
-```erg
+```python
X = 1 # OK
X = !1 # TypeError: cannot define Int! object as a constant
```
@@ -104,7 +106,7 @@ X = !1 # TypeError: cannot define Int! object as a constant
`Del`関数を使うことで、代数を削除することが出来ます。その代数に依存している(その代数の値を直接参照している)他の代数もまとめて削除されます。
-```erg
+```python
x = 1
y = 2
Z = 3
@@ -119,7 +121,7 @@ f(2) # NameError: f is not defined (deleted in line 6)
ただし、`Del`によって削除できるのはモジュール内で定義された代数のみです。`True`などの組み込み定数は削除できません。
-```erg
+```python
Del True # TypeError: cannot delete built-in constants
Del print! # TypeError: cannot delete built-in variables
```
@@ -128,7 +130,7 @@ Del print! # TypeError: cannot delete built-in variables
注意として、`x = a`であるとき、`x == a`とは限らない。例としては`Float.NaN`がある。これはIEEE 754により定められた正式な浮動小数点数の仕様である。
-```erg
+```python
x = Float.NaN
assert x != Float.NaN
assert x != x
@@ -136,7 +138,7 @@ assert x != x
その他、そもそも同値関係が定義されていないオブジェクトも存在する。
-```erg
+```python
f = x -> x**2 + 2x + 1
g = x -> (x + 1)**2
f == g # TypeError: cannot compare function objects
@@ -150,7 +152,7 @@ C == D # TypeError: cannot compare class objects
関数オブジェクトやクラスオブジェクトの場合、オブジェクトに変数名の情報を与えるなどの「修飾」を行う。
ただし構造型の場合はその限りではない。
-```erg
+```python
f x = x
print! f #
g x = x + 1
diff --git a/doc/JA/syntax/03_declaration.md b/doc/JA/syntax/03_declaration.md
index a0077a81..cf17bf5d 100644
--- a/doc/JA/syntax/03_declaration.md
+++ b/doc/JA/syntax/03_declaration.md
@@ -1,10 +1,12 @@
# Declaration(宣言)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/03_declaration.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
宣言は、使用する変数の型を指定する構文です。
宣言はコード中のどこでも可能ですが、宣言しただけでその変数を参照することはできません。必ず初期化する必要があります。
代入後の宣言では、代入されたオブジェクトと型が適合するかをチェック可能です。
-```erg
+```python
i: Int
# i: Int = 2のように代入と同時に宣言可能
i = 2
@@ -18,7 +20,7 @@ i: {2}
実行時の`assert`による型チェックは「〇〇型かもしれない」で検査が可能ですが、コンパイル時の`:`による型チェックは厳密です。
「〇〇型である」ことが確定していなくては検査を通らず、エラーとなります。
-```erg
+```python
i = (-1..10).sample!()
assert i in Nat # これは通るかもしれない
i: Int # これは通る
@@ -27,14 +29,14 @@ i: Nat # これは通らない(-1はNatの要素ではないから)
関数は以下の2種類の方法で宣言が可能です。
-```erg
+```python
f: (x: Int, y: Int) -> Int
f: (Int, Int) -> Int
```
引数名を明示して宣言した場合、定義時に名前が違うと型エラーとなります。引数名の任意性を与えたい場合は2番目の方法で宣言すると良いでしょう。その場合、型検査で見られるのはメソッド名とその型のみです。
-```erg
+```python
T = Trait {
.f = (x: Int, y: Int): Int
}
diff --git a/doc/JA/syntax/04_function.md b/doc/JA/syntax/04_function.md
index abad4e52..0f756cba 100644
--- a/doc/JA/syntax/04_function.md
+++ b/doc/JA/syntax/04_function.md
@@ -1,8 +1,10 @@
# 関数
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/04_function.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
関数は「引数」を受け取ってそれを加工し、「戻り値」として返すブロックです。以下のように定義します。
-```erg
+```python
add x, y = x + y
# or
add(x, y) = x + y
@@ -13,7 +15,7 @@ add(x, y) = x + y
`add`は`x`と`y`を仮引数として受け取り、それを足したもの、`x + y`を返す関数です。
定義した関数は、以下のようにして呼び出し(適用)ができます。
-```erg
+```python
add 1, 2
# or
add(1, 2)
@@ -23,16 +25,16 @@ add(1, 2)
関数は`f x, y, ...`のように呼び出しますが、実引数が多く一行では長くなりすぎる場合は`:`(コロン)を使った適用も可能です。
-```erg
+```python
f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4
```
-```erg
+```python
f some_long_name_variable_1 + some_long_name_variable_2:
some_long_name_variable_3 * some_long_name_variable_4
```
-```erg
+```python
f:
some_long_name_variable_1 + some_long_name_variable_2
some_long_name_variable_3 * some_long_name_variable_4
@@ -40,7 +42,7 @@ f:
上の3つのコードはすべて同じ意味です。このスタイルは`if`関数などを使用するときにも便利です。
-```erg
+```python
result = if Bool.sample!():
do:
log "True was chosen"
@@ -57,7 +59,7 @@ result = if Bool.sample!():
引数の数が多い関数を定義されていると、引数を渡す順番を間違える危険性があります。
そのような場合はキーワード引数を使用して呼び出すと安全です。
-```erg
+```python
f x, y, z, w, v, u: Int = ...
```
@@ -65,13 +67,13 @@ f x, y, z, w, v, u: Int = ...
このような関数は作るべきではありませんが、他人の書いたコードを使うときにこのようなコードにあたってしまうかもしれません。
そこで、キーワード引数を使います。キーワード引数は並びよりも名前が優先されるため、順番を間違えていても名前から正しい引数に値が渡されます。
-```erg
+```python
f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3
```
キーワード引数と`:`の後にすぐ改行してしまうとコロン適用スタイルとみなされるので注意してください。
-```erg
+```python
# means `f(x: y)`
f x: y
@@ -86,7 +88,7 @@ f x:
デフォルト引数は`:=`(or-assign operator)で指定します。`base`が指定されなかったら`math.E`を`base`に代入します。
-```erg
+```python
math_log x: Ratio, base := math.E = ...
assert math_log(100, 10) == 2
@@ -95,7 +97,7 @@ assert math_log(100) == math_log(100, math.E)
引数を指定しないことと`None`を代入することは区別されるので注意してください。
-```erg
+```python
p! x := 0 = print! x
p!(2) # 2
p!() # 0
@@ -104,20 +106,20 @@ p!(None) # None
型指定、パターンと併用することもできます。
-```erg
+```python
math_log x, base: Ratio := math.E = ...
f [x, y] := [1, 2] = ...
```
しかしデフォルト引数内では、後述するプロシージャを呼び出したり、可変オブジェクトを代入したりすることができません。
-```erg
+```python
f x := p! 1 = ... # NG
```
また、定義したばかりの引数はデフォルト引数に渡す値として使えません。
-```erg
+```python
f x := 1, y := x = ... # NG
```
@@ -125,13 +127,13 @@ f x := 1, y := x = ... # NG
引数をログ(記録)として出力する`log`関数は、任意の個数の引数を受け取ることができます。
-```erg
+```python
log "Hello", "World", "!" # Hello World !
```
このような関数を定義したいときは、引数に`...`を付けます。このようにすると、引数を可変長の配列として受け取ることができます。
-```erg
+```python
f x: ...Int =
for x, i ->
log i
@@ -142,7 +144,7 @@ f 1, 2, 3, 4, 5
## 複数パターンによる関数定義
-```erg
+```python
fib n: Nat =
match n:
0 -> 0
@@ -152,7 +154,7 @@ fib n: Nat =
上のような定義直下に`match`が現れる関数は、下のように書き直すことができます。
-```erg
+```python
fib 0 = 0
fib 1 = 1
fib(n: Nat): Nat = fib(n - 1) + fib(n - 2)
@@ -162,7 +164,7 @@ fib(n: Nat): Nat = fib(n - 1) + fib(n - 2)
違うクラスのインスタンスが混在する場合は、最後の定義で関数引数がOr型であることを明示しなくてはなりません。
-```erg
+```python
f "aa" = ...
f 1 = ...
# `f x = ...` is invalid
@@ -171,7 +173,7 @@ f x: Int or Str = ...
また、`match`と同じく網羅性がなくてはなりません。
-```erg
+```python
fib 0 = 0
fib 1 = 1
# PatternError: pattern of fib's parameter is not exhaustive
@@ -179,7 +181,7 @@ fib 1 = 1
しかし、上のような場合でも、後述する[篩型](./type/12_refinement.md)を使って明示的に型指定することで、網羅性を獲得できます。
-```erg
+```python
fib: 0..1 -> 0..1
fib 0 = 0
fib 1 = 1
@@ -193,7 +195,7 @@ fib 1 = 1
簡単な例として階乗の計算を行う関数`factorial`を定義してみます。階乗とは、「それ以下の正の数をすべてかける」計算です。
5の階乗は`5*4*3*2*1 == 120`となります。
-```erg
+```python
factorial 0 = 1
factorial 1 = 1
factorial(n: Nat): Nat = n * factorial(n - 1)
@@ -207,7 +209,7 @@ factorial(n: Nat): Nat = n * factorial(n - 1)
注意として、型指定を付けなかった場合はこのように推論されます。
-```erg
+```python
factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int
factorial 0 = 1
factorial 1 = 1
@@ -216,7 +218,7 @@ factorial n = n * factorial(n - 1)
しかし例え推論が出来たとしても、再帰関数には型を明示的に指定しておくべきです。上の例では、`factorial(-1)`のようなコードは有効ですが、
-```erg
+```python
factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ...
```
@@ -229,7 +231,7 @@ factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ...
コンパイル関数ができることは限られています。コンパイル時関数内で使えるのは定数式のみ、すなわち、いくつかの演算子(四則演算や比較演算、型構築演算など)とコンパイル時関数のみです。代入する引数も定数式である必要があります。
そのかわり、計算をコンパイル時に行うことができるというメリットがあります。
-```erg
+```python
Add(X, Y: Nat): Nat = X + Y
assert Add(1, 2) == 3
@@ -243,7 +245,7 @@ Sin X = math.sin X # ConstantError: this function is not computable at compile t
コンパイル時関数は多相型の定義などでもよく使われます。
-```erg
+```python
Option T: Type = T or NoneType
Option: Type -> Type
```
@@ -252,7 +254,7 @@ Option: Type -> Type
Ergでは、関数に`==`が定義されていません。それは関数の構造的な同値性判定アルゴリズムが一般には存在しないためです。
-```erg
+```python
f = x: Int -> (x + 1)**2
g = x: Int -> x**2 + 2x + 1
@@ -271,7 +273,7 @@ assert (lambda x: x) != (lambda x: x)
## Appendix2: ()の補完
-```erg
+```python
f x: Object = ...
# will be completed to
f(x: Object) = ...
diff --git a/doc/JA/syntax/05_builtin_funcs.md b/doc/JA/syntax/05_builtin_funcs.md
index 279755ed..37f3e091 100644
--- a/doc/JA/syntax/05_builtin_funcs.md
+++ b/doc/JA/syntax/05_builtin_funcs.md
@@ -1,10 +1,12 @@
# 組み込み関数
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/05_builtin_funcs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
## if
`if`は条件に応じて処理を変える関数です。
-```erg
+```python
result: Option Int = if! Bool.sample!(), do:
log "True was chosen"
1
@@ -14,7 +16,7 @@ print! result # None (or 1)
`.sample!()`は集合の値をランダムに返します。もし戻り値が真ならば、`print! "True"`が実行されます。
条件が偽であった際の処理も指定できます。2つ目のdoブロックはelseブロックと呼ばれます。
-```erg
+```python
result: Nat = if Bool.sample!():
do:
log "True was chosen"
@@ -27,7 +29,7 @@ print! result # 1 (or 0)
処理が1行ならば、インデントを省略できます。
-```erg
+```python
result = if Bool.sample!():
do 1
do 0
@@ -37,7 +39,7 @@ result = if Bool.sample!():
繰り返し行う処理を書くときは`for`が使えます。
-```erg
+```python
match_s(ss: Iterator(Str), pat: Pattern): Option Str =
for ss, s ->
if pat.match(s).is_some():
diff --git a/doc/JA/syntax/06_operator.md b/doc/JA/syntax/06_operator.md
index f2e1e1de..7a00011b 100644
--- a/doc/JA/syntax/06_operator.md
+++ b/doc/JA/syntax/06_operator.md
@@ -1,11 +1,13 @@
# 演算子
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/06_operator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
演算子(オペレーター)は、演算を表す記号です。被演算子(オペランド)は演算子の(左)右にあるもので、Ergでは専らオブジェクトです。
演算子は関数の一種であり、したがってそれ自体も第一級オブジェクトで変数に束縛できます。束縛の際は``で囲む必要があります。
`+`(と`-`)については、単項演算子と二項演算子の両方が存在するため、一意化するために`_+_`(二項演算)/`+_`(単項演算)のどちらかを指定する必要があります。
-```erg
+```python
add = `+` # SyntaxError: specify `_+_` or `+_`
add = `_+_`
assert f(1, 2) == 3
@@ -17,7 +19,7 @@ assert g(1, 2) == 2
ただし、特殊形式と呼ばれる一部の演算子は束縛できないことに注意してください。
-```erg
+```python
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/JA/syntax/07_side_effect.md b/doc/JA/syntax/07_side_effect.md
index ab542b48..a7fcfe57 100644
--- a/doc/JA/syntax/07_side_effect.md
+++ b/doc/JA/syntax/07_side_effect.md
@@ -1,15 +1,17 @@
# 副作用とプロシージャ
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/07_side_effect.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
これまで`print!`の`!`の意味を説明せずにいましたが、いよいよその意味が明かされます。この!は、ズバリこのオブジェクトが「副作用」のある「プロシージャ」であることを示しています。プロシージャは関数に「副作用」という効果を与えたものです。
-```erg
+```python
f x = print! x # EffectError: functions cannot be assigned objects with side effects
# hint: change the name to 'f!'
```
上のコードはコンパイルエラーになります。関数中でプロシージャを使用しているからです。このような場合は、プロシージャとして定義しなくてはなりません。
-```erg
+```python
p! x = print! x
```
@@ -21,7 +23,7 @@ p! x = print! x
関数とプロシージャにはそれぞれメソッドが存在します。関数メソッドは`self`の不変参照のみを取れ、プロシージャルメソッドは`self`の可変参照を取れます。
`self`は特殊な引数で、メソッドの文脈では呼び出したオブジェクト自身を指します。参照の`self`は他のいかなる変数にも代入できません。
-```erg
+```python
C.
method ref self =
x = self # OwnershipError: cannot move out 'self'
@@ -30,7 +32,7 @@ C.
メソッドは`self`の所有権を奪うこともできます。そのメソッドの定義では`ref`または`ref!`を外します。
-```erg
+```python
n = 1
s = n.into(Str) # '1'
n # ValueError: n was moved by .into (line 2)
@@ -40,7 +42,7 @@ n # ValueError: n was moved by .into (line 2)
ただし、可変参照から(不変/可変)参照の生成はできることに注意してください。これによって、プロシージャルメソッド中で再帰したり`self`を`print!`できたりします。
-```erg
+```python
T -> T # OK (move)
T -> Ref T # OK
T => Ref! T # OK (only once)
@@ -63,14 +65,14 @@ Ref! T => Ref! T # OK
前者の例は`print!`で、後者の例は以下の関数です。
-```erg
+```python
nan _ = Float.NaN
assert nan(1) != nan(1)
```
また、クラスや関数のように同値判定自体ができないオブジェクトも存在します。
-```erg
+```python
T = Structural {i = Int}
U = Structural {i = Int}
assert T == U
@@ -88,7 +90,7 @@ assert C == D # TypeError: cannot compare classes
例として`print!`プロシージャについて考えます。`print!`は一見何の変数も書き換えていないように見えます。しかし、もしこれが関数だったとすると、例えばこのようなコードで外側変数を書き換えられます。
-```erg
+```python
camera = import "some_camera_module"
ocr = import "some_ocr_module"
@@ -107,7 +109,7 @@ n = ocr.read_num(image) # n = 3.141592
とはいえ、関数中で値を一時的に確認するとき、そのためだけに関連する関数まで`!`を付けたくない場合もあるでしょう。その際は`log`関数が使えます。
`log`はコード全体の実行後に値を表示します。これにより、副作用は伝搬されません。
-```erg
+```python
log "this will be printed after execution"
print! "this will be printed immediately"
# this will be printed immediately
diff --git a/doc/JA/syntax/08_procedure.md b/doc/JA/syntax/08_procedure.md
index 1cda8f4f..03292f40 100644
--- a/doc/JA/syntax/08_procedure.md
+++ b/doc/JA/syntax/08_procedure.md
@@ -1,8 +1,10 @@
# プロシージャ
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/08_procedure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
プロシージャは可変オブジェクトを取り扱う際に必要となりますが、可変オブジェクトを引数に持てばプロシージャであるとは限りません。
-```erg
+```python
peek_str s: Str! = log s
```
diff --git a/doc/JA/syntax/09_builtin_procs.md b/doc/JA/syntax/09_builtin_procs.md
index 95dbdf96..a7d55dab 100644
--- a/doc/JA/syntax/09_builtin_procs.md
+++ b/doc/JA/syntax/09_builtin_procs.md
@@ -1,11 +1,13 @@
# 組み込みプロシージャ
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/09_builtin_procs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
## id!
オブジェクトのユニークな識別番号を返します。
純粋なErgの意味論の中では同一の構造を持つオブジェクトの間に差異を見出す事はできませんが、実際のところ、オブジェクトはメモリ上の位置が異なります。`id!`はこの位置を表す数値を返します。
-```erg
+```python
```
diff --git a/doc/JA/syntax/10_array.md b/doc/JA/syntax/10_array.md
index d8d16bb2..8181897f 100644
--- a/doc/JA/syntax/10_array.md
+++ b/doc/JA/syntax/10_array.md
@@ -1,9 +1,11 @@
# 配列
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/10_array.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
配列はもっとも基本的な __コレクション(集約)__ です。
コレクションとは、内部にオブジェクトを複数保持できるオブジェクトのことです。
-```erg
+```python
a = [1, 2, 3]
a: [Int; 3] # 型指定: セミコロンの後の数字は要素数
# 要素数がわからない場合は省略可能
@@ -16,13 +18,13 @@ assert mut_a == [2, 2, 3]
配列には、原則として違う型のオブジェクトを入れることはできません。
-```erg
+```python
[1, "a"] # TypeError: 1st element is Int, but 2nd element is Str
```
しかし、このように明示的に型指定すると制限を回避できます。
-```erg
+```python
[1, "a"]: [Int or Str]
```
@@ -30,7 +32,7 @@ assert mut_a == [2, 2, 3]
配列は、複数の値をまとめて取り出すこともできます。これをスライスと呼びます。
-```erg
+```python
l = [1, 2, 3, 4]
# Pythonのl[1:3]に相当
assert l[1..<3] == [2, 3]
@@ -43,7 +45,7 @@ assert l[..].step(2) == [2, 4]
スライスで得られるオブジェクトは配列の(不変)参照です。
-```erg
+```python
print! Typeof l[1..2] # Ref [Int; 4]
```
diff --git a/doc/JA/syntax/11_tuple.md b/doc/JA/syntax/11_tuple.md
index 3523e6a0..fef7c7b4 100644
--- a/doc/JA/syntax/11_tuple.md
+++ b/doc/JA/syntax/11_tuple.md
@@ -1,9 +1,11 @@
# タプル
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/11_tuple.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
タプルは配列と似ていますが、違う型のオブジェクトを保持できます。
このようなコレクションを非等質なコレクションと呼びます。対して等質なコレクションには配列、セットなどがあります。
-```erg
+```python
t = (1, True, "a")
(i, b, s) = t
assert(i == 1 and b == True and s == "a")
@@ -12,7 +14,7 @@ assert(i == 1 and b == True and s == "a")
タプル`t`は`t.n`の形式でn番目の要素を取り出すことができます。Pythonと違い、`t[n]`ではないことに注意してください。
これは、タプル要素のアクセスはメソッド(配列の`[]`はメソッドです)というより属性に近い(コンパイル時に要素の存在がチェックされる、nによって型が変わりうる)ためです。
-```erg
+```python
assert t.0 == 1
assert t.1 == True
assert t.2 == "a"
@@ -20,14 +22,14 @@ assert t.2 == "a"
括弧`()`はネストしないとき省略可能です。
-```erg
+```python
t = 1, True, "a"
i, b, s = t
```
タプルは違う型のオブジェクトを保持できますが、そのかわり配列のようなイテレーションができなくなります。
-```erg
+```python
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)`で表せるが、これでもイテレーションは出来ない
@@ -38,11 +40,11 @@ assert (Int; 3) == (Int, Int, Int)
ただし、非等質なコレクション(タプルなど)はアップキャスト、Intersectionなどによって等質なコレクション(配列など)に変換できます。
これを等質化といいます。
-```erg
+```python
(Int, Bool, Str) can be [T; 3] | T :> Int, T :> Bool, T :> Str
```
-```erg
+```python
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
@@ -54,21 +56,21 @@ t.try_into([Show; 3])?.iter().map(x -> log x) # OK
要素が0個のタプルはユニットと言います。ユニットは値ですが、自身の型そのものも指します。
-```erg
+```python
unit = ()
(): ()
```
ユニットはすべての要素0のタプルのスーパークラスです。
-```erg
+```python
() > (Int; 0)
() > (Str; 0)
```
このオブジェクトの使いみちは、引数、戻り値がないプロシージャなどです。Ergのサブルーチンは、必ず引数と戻り値を持つ必要があります。しかしプロシージャなどの場合、副作用を起こすだけで意味のある引数・戻り値がない場合もあります。その際に「意味のない、形式上の値」としてユニットを使うわけです。
-```erg
+```python
# ↓ 実はこの括弧はユニット
p!() =
# `print!`は意味のある値を返さない
@@ -83,7 +85,7 @@ Ergでの使い分けとしては、プロシージャなどではじめから
実は、Ergの`Callable`オブジェクトは全て1引数で1戻り値です。N個の引数を取るサブルーチンは、「N個の要素を持つタプル1つ」を引数として受け取っているだけだったのです。
-```erg
+```python
# f x = ...は暗黙にf(x) = ...とみなされる
f x = x
assert f(1) == 1
@@ -95,14 +97,14 @@ assert (2, 3) == g 1, 2, 3
関数の型もこれで説明が付きます。
-```erg
+```python
assert f in T: {(T,) -> T | T}
assert g in {(Int, ...(Int; N)) -> (Int; N) | N: Nat}
```
正確には、関数の入力はタプルではなく「デフォルト属性付きNamedタプル」です。これは関数の引数でだけ使える特殊なタプルで、レコードのように名前付けができ、デフォルト値を持つことができます。
-```erg
+```python
f(x: Int, y=0) = x + y
f: (Int, y=Int) -> Int
diff --git a/doc/JA/syntax/12_dict.md b/doc/JA/syntax/12_dict.md
index d921c6f2..f5d7701b 100644
--- a/doc/JA/syntax/12_dict.md
+++ b/doc/JA/syntax/12_dict.md
@@ -1,15 +1,17 @@
# Dict
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/12_dict.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
Dictはキーと値のペアを持つコレクションです。
-```erg
+```python
ids = {"Alice": 145, "Bob": 214, "Charlie": 301}
assert ids["Alice"] == 145
```
キーはHashであるならば文字列でなくても構いません。
-```erg
+```python
# rangeオブジェクトをキーにするのは非推奨(スライスと混同される)
r = {1..3: "1~3", 4..6: "4~6", 7..9: "7~9"}
assert r[1..3] == "1~3"
@@ -20,20 +22,20 @@ assert l[[]] == "empty"
Dictに順番は関係ありません。また、重複する要素を持つことも出来ません。この点でDictは[Set](./14_set.md)と似ています。
Dictは値付きのSetと言うこともできるでしょう。
-```erg
+```python
{"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214}
```
DictリテラルからDictを生成する場合、キーの重複がないかチェックされます。
重複がある場合コンパイルエラーとなります。
-```erg
+```python
{"Alice": 145, "Alice": 1} # KeyError: Duplicate key "Alice"
```
空のDictは`{:}`で生成します。`{}`は空の配列を表すことに注意してください。
-```erg
+```python
mut_dict = !{:}
mut_dict.insert! "Alice", 145
mut_dict.insert! "Bob", 214
@@ -44,7 +46,7 @@ assert mut_dict["Alice"] == 145
キー・値の型は単一でなくてもよく、そのような辞書を __非等質な辞書(heterogenous dict)__ といいます。
-```erg
+```python
d: {Str: Int, Int: Str} = {”a”: 1, 1: “a”}
assert d[”a”] == 1
assert d[1] == “a”
@@ -53,7 +55,7 @@ assert d[1] == “a”
しかし、違う型のキーに同じ型の値、または同じ型のキーに違う型の値をあてることはできません。
このような場合は代わりにOr型(Union)を使います。
-```erg
+```python
invalid1 = {1: “a”, “a”: “b”}
invalid2 = {1: “a”, 2: 2}
diff --git a/doc/JA/syntax/13_record.md b/doc/JA/syntax/13_record.md
index 2ab07f4a..c0db8c64 100644
--- a/doc/JA/syntax/13_record.md
+++ b/doc/JA/syntax/13_record.md
@@ -1,9 +1,11 @@
# レコード
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/13_record.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
レコードは、キーでアクセスするDictとコンパイル時にアクセスが検査されるタプルの性質を併せ持つコレクションです。
JavaScriptをやったことがある方ならば、オブジェクトリテラル記法の(より強化された)ようなものと考えてください。
-```erg
+```python
john = {.name = "John"; .age = 21}
assert john.name == "John"
@@ -20,7 +22,7 @@ JavaScriptのオブジェクトリテラルとの相違点は、文字列でア
一般的にはレコードの使用を推奨します。レコードには、コンパイル時に要素が存在するかチェックされる、 __可視性(visibility)__ を指定できるなどのメリットがあります。
可視性の指定は、Java言語などでみられるpublic/privateの指定に相当します。詳しくは[可視性](./15_visibility.md)を参照してください。
-```erg
+```python
a = {x = 1; .y = x + 1}
a.x # AttributeError: x is private
# Hint: declare as `.x`
@@ -31,7 +33,7 @@ assert a.y == 2
属性に対する明示的な型指定もできます。
-```erg
+```python
anonymous = {
.name: Option! Str = !None
.age = 20
@@ -41,7 +43,7 @@ anonymous.name.set! "John"
レコードはメソッドも持てます。
-```erg
+```python
o = {
.i = !0
.inc! ref! self = self.i.inc!()
@@ -55,7 +57,7 @@ assert o.i == 1
レコードに関して特筆すべき文法があります。レコードの属性値が全てクラス(構造型ではダメです)のとき、そのレコード自体が、自身の属性を要求属性とする型としてふるまいます。
このような型をレコード型と呼びます。詳しくは[レコード]の項を参照してください。
-```erg
+```python
# レコード
john = {.name = "John"}
# レコード型
@@ -74,7 +76,7 @@ print! Named.name # Str
レコードは以下のようにして分解できます。
-```erg
+```python
record = {x = 1; y = 2}
{x = a; y = b} = record
assert a == 1
@@ -91,7 +93,7 @@ match point:
また、レコードは属性と同名の変数があるとき、例えば`x = x`または`x = .x`を`x`に、`.x = .x`または`.x = x`を`.x`に省略できます。
ただし、属性が一つのときはセットと区別するために`;`を付ける必要があります。
-```erg
+```python
x = 1
y = 2
xy = {x; y}
@@ -108,7 +110,7 @@ assert tuple.1 == 1
この構文を利用して、レコードを分解して変数に代入できます。
-```erg
+```python
# same as `{x = x; y = y} = xy`
{x; y} = xy
assert x == 1
@@ -123,7 +125,7 @@ assert b == 2
空のレコードは`{=}`で表されます。空のレコードはUnitと同じく、自身のクラスそのものでもあります。
-```erg
+```python
empty_record = {=}
empty_record: {=}
# Object: Type = {=}
@@ -137,7 +139,7 @@ empty_record: Structural {=}
逆に、レコードクラスの`{=}`は要求インスタンス属性がないので、全てのオブジェクトがこれの要素になります。`Object`は、これのエイリアスです。
`Object`(のパッチ)は`.__sizeof__`などの極めて基本的な提供メソッドを持ちます。
-```erg
+```python
AnyPatch = Patch Structural {=}
.__sizeof__ self = ...
.clone self = ...
@@ -153,7 +155,7 @@ Never = Class {}
Ergにはもう一つインスタントブロックという構文がありますが、これは単に最後に評価した値を返すだけです。属性の保持はできません。
-```erg
+```python
x =
x = 1
y = x + 1
@@ -169,7 +171,7 @@ y =
素のレコード(レコードリテラルで生成されたレコード)は、これ単体でメソッドを実装しようとすると、直接インスタンスに定義する必要があります。
これは効率が悪く、さらに属性の数が増えていくとエラー表示などが見にくくなり使いにくいです。
-```erg
+```python
john = {
name = "John Smith"
age = !20
@@ -183,7 +185,7 @@ john + 1
そこで、このような場合はレコードクラスを継承します。このようなクラスをデータクラスと呼びます。
これについては[クラス](./type/04_class.md)の項で詳しく説明します。
-```erg
+```python
Person = Inherit {name = Str; age = Nat}
Person.
greet! ref self = print! "Hello, my name is {self::name} and I am {self::age} years old."
diff --git a/doc/JA/syntax/14_set.md b/doc/JA/syntax/14_set.md
index 3dd485cc..5537d9f3 100644
--- a/doc/JA/syntax/14_set.md
+++ b/doc/JA/syntax/14_set.md
@@ -1,8 +1,10 @@
# セット(Set)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/14_set.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
セットは集合を表し、データ構造的には重複、順序のない配列です。
-```erg
+```python
assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3}
assert {1, 2} == {1, 1, 2} # 重複は自動で削除される
assert {1, 2} == {2, 1}
@@ -10,7 +12,7 @@ assert {1, 2} == {2, 1}
セットは集合演算を行えます。
-```erg
+```python
assert 1 in {1, 2, 3}
assert not 1 in {}
assert {1} or {2} == {1, 2}
@@ -20,7 +22,7 @@ assert {1, 2} not {2} == {1}
セットは等質なコレクションです。別のクラスのオブジェクトを共存させるためには、等質化させなくてはなりません。
-```erg
+```python
s: {Int or Str} = {"a", 1, "b", -1}
```
@@ -28,7 +30,7 @@ s: {Int or Str} = {"a", 1, "b", -1}
セットは型としても扱えます。このような型は __列挙型(Enum type)__ と呼ばれます。
-```erg
+```python
i: {1, 2, 3} = 1
assert i in {1, 2, 3}
```
@@ -36,7 +38,7 @@ assert i in {1, 2, 3}
セットの要素がそのまま型の要素になります。
セット自身は違うことに注意が必要です。
-```erg
+```python
mut_set = {1, 2, 3}.into {Int; !3}
mut_set.insert!(4)
```
diff --git a/doc/JA/syntax/15_type.md b/doc/JA/syntax/15_type.md
index 840b24fc..2c4e0204 100644
--- a/doc/JA/syntax/15_type.md
+++ b/doc/JA/syntax/15_type.md
@@ -1,5 +1,7 @@
# 型
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/15_type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
型はErgにおいて非常に重要な機能ですので、[専用のセクション](./type/01_type_system.md)を用意しています。そちらをご覧ください。
diff --git a/doc/JA/syntax/16_iterator.md b/doc/JA/syntax/16_iterator.md
index 2800a5ae..29ae4a3e 100644
--- a/doc/JA/syntax/16_iterator.md
+++ b/doc/JA/syntax/16_iterator.md
@@ -1,8 +1,10 @@
# イテレータ
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/16_iterator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
イテレータは、コンテナの要素を取り出すためのオブジェクトです。
-```erg
+```python
for! 0..9, i =>
print! i
```
@@ -12,7 +14,7 @@ for! 0..9, i =>
ではここで`for!`プロシージャの型シグネチャを見てみましょう。
-```erg
+```python
for!: |T: Type, I <: Iterable T| (I, T => None) => None
```
@@ -20,7 +22,7 @@ for!: |T: Type, I <: Iterable T| (I, T => None) => None
`Iterable`は`.Iterator`属性, `.iter`メソッドを要求メソッドに持つ型です。
-```erg
+```python
Iterable T = Trait {
.Iterator = {Iterator}
.iter = Self(T).() -> Self.Iterator T
@@ -29,7 +31,7 @@ Iterable T = Trait {
`.Iterator`属性の型`{Iterator}`はいわゆるセットカインド(カインドは[こちら](./type/advanced/kind.md)で説明されています)です。
-```erg
+```python
assert [1, 2, 3] in Iterable(Int)
assert 1..3 in Iterable(Int)
assert [1, 2, 3].Iterator == ArrayIterator
diff --git a/doc/JA/syntax/17_mutability.md b/doc/JA/syntax/17_mutability.md
index 901fdd7c..df26eb7e 100644
--- a/doc/JA/syntax/17_mutability.md
+++ b/doc/JA/syntax/17_mutability.md
@@ -1,9 +1,11 @@
# Mutability
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/17_mutability.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
すでに見たように、Ergの変数は全て不変です。しかし、Ergのオブジェクトには可変性という概念があります。
以下のコードを例にします。
-```erg
+```python
a = [1, 2, 3]
a = a + [4, 5, 6]
print! a # [1, 2, 3, 4, 5, 6]
@@ -12,7 +14,7 @@ print! a # [1, 2, 3, 4, 5, 6]
上のコードは実際にはErgでは実現できません。再代入不可だからです。
このコードは実行できます。
-```erg
+```python
b = ![1, 2, 3]
b.concat! [4, 5, 6]
print! b # [1, 2, 3, 4, 5, 6]
@@ -21,7 +23,7 @@ print! b # [1, 2, 3, 4, 5, 6]
`a, b`は、最終的な結果は同じように見えますが、その意味は大きく異なります。
`a`は`Nat`の配列を示す変数ですが、1行目と2行目では指しているオブジェクトが異なります。`a`という名前が同じだけで、中身はさし変わっているのです。
-```erg
+```python
a = [1, 2, 3]
print! id! a # 0x000002A798DFE940
_a = a + [4, 5, 6]
@@ -32,14 +34,14 @@ print! id! _a # 0x000002A798DFE980
`b`は`Nat`の「動的」配列です。オブジェクトの中身は変わりますが、変数の指すものは同じです。
-```erg
+```python
b = [1,2,3].into [Int; !3]
print! id! b # 0x000002A798DFE220
b.concat! [4, 5, 6]
print! id! b # 0x000002A798DFE220
```
-```erg
+```python
i = !0
if! True:
do! i.inc!() # or i.add!(1)
@@ -50,7 +52,7 @@ print! i # 1
`!`は __可変化演算子(mutation operator)__ とよばれる特殊な演算子です。引数の不変オブジェクトを可変化して返します。
`!`がついたオブジェクトの振る舞いはカスタム可能です。
-```erg
+```python
Point = Class {.x = Int; .y = Int}
# この場合.xは可変化し、yは不変のまま
@@ -67,7 +69,7 @@ print! p.x # 1
変数と違い、すべてのスコープで同じものを指すのが定数です。
定数は`=`演算子で宣言します。
-```erg
+```python
PI = 3.141592653589
match! x:
PI => print! "this is pi"
diff --git a/doc/JA/syntax/18_ownership.md b/doc/JA/syntax/18_ownership.md
index 34e7be1c..c140705b 100644
--- a/doc/JA/syntax/18_ownership.md
+++ b/doc/JA/syntax/18_ownership.md
@@ -1,5 +1,7 @@
# 所有権システム
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/18_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
ErgはPythonをホスト言語にした言語であるため、メモリ管理の方法はPythonの処理系に依存しています。
しかし、意味論的にはErgのメモリ管理はPythonのそれとは別物です。顕著な違いは、所有権システムと循環参照の禁止に現れています。
@@ -9,7 +11,7 @@ ErgはRustから影響を受けた所有権システムを持っています。
Rustの所有権システムは一般的に難解だと言われていますが、Ergのそれは直感的になるよう簡略化されています。
Ergでは __可変オブジェクト__ に所有権がついており、所有権を失った後はそのオブジェクトを参照できません。
-```erg
+```python
v = [1, 2, 3].into [Int; !3]
push! vec, x =
@@ -34,7 +36,7 @@ print! w # [1, 2, 3, 4]
複製はPythonのディープコピーに相当し、同一のオブジェクトをまるごと作り直すので、凍結・借用と比べて一般に計算コスト、メモリコストが高くなります。
オブジェクトを複製する必要があるようなサブルーチンは、「引数を消費する」サブルーチンといいます。
-```erg
+```python
capitalize s: Str! =
s.capitalize!()
s
@@ -51,7 +53,7 @@ log s2, s1 # !"HELLO hello"
可変配列からは直接イテレータを作ることができないので、不変配列に変換します。
配列を壊したくない場合は、[`.freeze_map`メソッド](./type/mut.md)等を使います。
-```erg
+```python
# イテレータが出す値の合計を計算する
sum|T <: Add + HasUnit| i: Iterator T = ...
@@ -69,7 +71,7 @@ y # この後もyは触れられる
借用は複製や凍結よりも低コストです。
以下のような単純な場合では、借用を行えます。
-```erg
+```python
peek_str ref(s: Str!) =
log s
@@ -80,7 +82,7 @@ peek_str s
借用した値は元のオブジェクトに対する __参照__ と呼ばれます。
参照をまた別のサブルーチンに渡す「又貸し」はできますが、借りているだけなので消費することはできません。
-```erg
+```python
steal_str ref(s: Str!) =
# log関数は引数を借用するだけなので、又貸しできる
log s
@@ -89,7 +91,7 @@ steal_str ref(s: Str!) =
# hint: use `clone` method
```
-```erg
+```python
steal_str ref(s: Str!) =
# これもダメ(=は右辺を消費する)
x = s # OwnershipError: cannot consume a borrowed value
diff --git a/doc/JA/syntax/19_visibility.md b/doc/JA/syntax/19_visibility.md
index e28163df..9c9c3b40 100644
--- a/doc/JA/syntax/19_visibility.md
+++ b/doc/JA/syntax/19_visibility.md
@@ -1,15 +1,17 @@
# 可視性(Visibility)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/19_visibility.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
Ergの変数には __可視性__ という概念が存在します。
今まで見てきた変数は全て __プライベート変数(非公開変数)__ と呼ばれます。これは、外部から不可視の変数です。
例えば`foo`モジュールで定義したプライベート変数は、別のモジュールから参照できないのです。
-```erg
+```python
# foo.er
x = "this is an invisible variable"
```
-```erg
+```python
# bar.er
foo = import "foo"
foo.x # AttributeError: Module 'foo' has no attribute 'x' ('x' is private)
@@ -18,12 +20,12 @@ foo.x # AttributeError: Module 'foo' has no attribute 'x' ('x' is private)
対して、 __パブリック(公開)変数__ というものもあり、こちらは外部から参照できます。
公開変数は`.`を付けて定義します。
-```erg
+```python
# foo.er
.x = "this is a visible variable"
```
-```erg
+```python
# bar.er
foo = import "foo"
assert foo.x == "this is a visible variable"
@@ -31,7 +33,7 @@ assert foo.x == "this is a visible variable"
非公開変数には何も付ける必要はないのですが、非公開であることを明示するために`::`または`self::`(型などなら`Self::`)を付けることもできます。またモジュールなら`module::`とすることもできます。
-```erg
+```python
::x = "this is a invisible variable"
assert ::x == x
assert self::x == ::x
@@ -40,7 +42,7 @@ assert module::x == ::x
単なる逐次実行の文脈では、プライベート変数はローカル変数とほぼ同義です。内側のスコープからは参照することが出来ます。
-```erg
+```python
::x = "this is a private variable"
y =
x + 1 # 正確にはmodule::x
@@ -50,7 +52,7 @@ y =
参照したい変数のスコープを左側に指定します。トップレベルの場合は`module`を指定します。
指定しなかった場合は通常の場合と同じく最も内側の変数が参照されます。
-```erg
+```python
::x = 0
assert x == 0
y =
@@ -66,7 +68,7 @@ y =
無名サブルーチンのスコープでは`self`で自身のスコープを指定します。
-```erg
+```python
x = 0
f = x ->
log module::x, self::x
@@ -75,7 +77,7 @@ f 1 # 0 1
`::`は、プライベートインスタンス属性にアクセスするという役割も持っています。
-```erg
+```python
x = 0
C = Class {x = Int}
C.
@@ -89,12 +91,12 @@ C.
あるモジュールで定義されたクラスは、実は外部モジュールからでもメソッドを定義できます。
-```erg
+```python
# foo.er
.Foo = Class()
```
-```erg
+```python
# bar.er
{Foo; ...} = import "foo"
@@ -113,7 +115,7 @@ Foo.
外部で定義された非公開メソッドは、定義モジュール内でのみ`Foo`クラスのメソッドから参照できます。
公開メソッドはクラスの外には公開されますが、モジュール外までは公開されません。
-```erg
+```python
# baz.er
{Foo; ...} = import "foo"
@@ -124,7 +126,7 @@ foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defi
また、Re-exportする型にメソッドを定義することはできません。
インポート元のモジュールによってメソッドが見つかったり見つからなかったりといった混乱を防ぐためです。
-```erg
+```python
# bar.er
{.Foo; ...} = import "foo"
@@ -136,7 +138,7 @@ foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defi
このようなことを行いたい場合は[パッチ](./type/07_patch.md)を定義します。
-```erg
+```python
# bar.er
{Foo; ...} = import "foo"
@@ -147,7 +149,7 @@ FooImpl.
public self = self::private()
```
-```erg
+```python
# baz.er
{Foo; ...} = import "foo"
{FooImpl; ...} = import "bar"
@@ -161,7 +163,7 @@ foo.public()
変数の可視性は完全な公開・非公開しかないわけではありません。
制限付きで公開することもできます。
-```erg
+```python
# foo.er
.record = {
.a = {
@@ -179,7 +181,7 @@ _ = .record.a.y # OK
_ = .record.a.z # OK
```
-```erg
+```python
foo = import "foo"
_ = foo.record.a.x # VisibilityError
_ = foo.record.a.y # VisibilityError
diff --git a/doc/JA/syntax/20_naming_rule.md b/doc/JA/syntax/20_naming_rule.md
index 82c33236..bb6913e8 100644
--- a/doc/JA/syntax/20_naming_rule.md
+++ b/doc/JA/syntax/20_naming_rule.md
@@ -1,8 +1,10 @@
# 命名規則
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/20_naming_rule.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
変数を定数式として使いたい場合は、必ず大文字で始めます。二文字以降は小文字でもよいです。
-```erg
+```python
i: Option Type = Int
match i:
t: Type -> log "type"
@@ -12,7 +14,7 @@ match i:
副作用のあるオブジェクトは、必ず`!`で終わります。プロシージャとプロシージャルメソッド、そして可変型です。
ただし、`Proc`型自体は可変型ではありません。
-```erg
+```python
# Callable == Func or Proc
c: Callable = print!
match c:
@@ -22,7 +24,7 @@ match c:
属性を外部に公開したい場合は、初めに`.`をつけて定義します。`.`を初めにつけなかった場合は非公開になります。混乱を避けるため同一のスコープ内で共存はできません。
-```erg
+```python
o = {x = 1; .x = 2} # SyntaxError: private and public variables with the same name cannot coexist
```
@@ -32,7 +34,7 @@ o = {x = 1; .x = 2} # SyntaxError: private and public variables with the same na
このようにシングルクォートで囲まれた文字列による識別子をリテラル識別子といいます。
これは、Pythonなど他言語のAPI(FFI)を呼び出す際に使います。
-```erg
+```python
bar! = pyimport("foo").'bar'
```
@@ -40,7 +42,7 @@ Ergでも有効な識別子の場合は、''で囲む必要はありません。
さらに、リテラル識別子中では記号も空白も入れることができるため、通常は識別子として使えない文字列を識別子として使うことができます。
-```erg
+```python
'∂/∂t' y
'test 1: pass x to y'()
```
diff --git a/doc/JA/syntax/21_lambda.md b/doc/JA/syntax/21_lambda.md
index f99d9c25..b8fd0543 100644
--- a/doc/JA/syntax/21_lambda.md
+++ b/doc/JA/syntax/21_lambda.md
@@ -1,8 +1,10 @@
# 無名関数(anonymous function)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/21_lambda.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
無名関数は、関数オブジェクトを名付けずその場で生成するための文法です。
-```erg
+```python
# `->`は無名関数演算子
# same as `f x, y = x + y`
f = (x, y) -> x + y
@@ -12,7 +14,7 @@ g = (x, y: Int): Int -> x + y
引数が1つの場合は`()`を省略できます。
-```erg
+```python
assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4]
assert ((i, j) -> [i, j])(1, 2) == [1, 2]
```
@@ -20,14 +22,14 @@ assert ((i, j) -> [i, j])(1, 2) == [1, 2]
下の場合`0..9, (i -> ...)`であって`(0..9, i) -> ...`ではありません。
`->`は左辺に一つだけ引数をとります。複数の引数は一つのタプルとして受け取ります。
-```erg
+```python
for 0..9, i: Int ->
...
```
無名関数では、空白による構文解釈の差異が存在します。
-```erg
+```python
# この場合は`T(() -> Int)`と解釈される
i: T () -> Int
# この場合は(U()) -> Intと解釈される
@@ -36,7 +38,7 @@ k: U() -> Int
無名関数は引数なしでも使えます。
-```erg
+```python
# `=>`は無名プロシージャ演算子
p! = () => print! "`p!` was called"
# `() ->`, `() =>`には`do`, `do!`という糖衣構文がある
@@ -46,7 +48,7 @@ p!() # `p!` was called
引数なし関数は遅延初期化に使えます。
-```erg
+```python
time = import "time"
date = import "datetime"
now = if! True:
@@ -59,7 +61,7 @@ now = if! True:
型付け、パターンマッチもできます。このため、`match`関数はほとんど無名関数の力で実現されています。
`match`関数の引数に与える無名関数は上から順番にトライされます。なので、上の方は特殊なケースを、下に行くほど一般的なケースを記述する必要があります。順番を間違えると(可能な限り)コンパイラがWarningを出します。
-```erg
+```python
n = (Complex or Ratio or Int).sample!()
i = match n:
PI -> PI # 定数PIに等しい場合
@@ -71,7 +73,7 @@ i = match n:
エラーハンドリングも`?`か`match`を使用して行うのが一般的です。
-```erg
+```python
res: ParseResult Int
match res:
i: Int -> i
@@ -85,7 +87,7 @@ match res2:
## 無名多相関数
-```erg
+```python
# same as id|T| x: T = x
id = |T| x: T -> x
```
diff --git a/doc/JA/syntax/22_subroutine.md b/doc/JA/syntax/22_subroutine.md
index b13a57d4..8890c52d 100644
--- a/doc/JA/syntax/22_subroutine.md
+++ b/doc/JA/syntax/22_subroutine.md
@@ -1,15 +1,17 @@
# Subroutine signatures
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/22_subroutine.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
## Func
-```erg
+```python
some_func(x: T, y: U) -> V
some_func: (T, U) -> V
```
## Proc
-```erg
+```python
some_proc!(x: T, y: U) => V
some_proc!: (T, U) => V
```
@@ -18,7 +20,7 @@ some_proc!: (T, U) => V
メソッド型は、外部からは`Self`で指定できません。
-```erg
+```python
.some_method(self, x: T, y: U) => ()
# Self.(T, U) => ()はselfの所有権を奪う
.some_method: Ref(Self).(T, U) => ()
@@ -28,7 +30,7 @@ some_proc!: (T, U) => V
以下で、型`T!`は`N: Nat`という型引数を取るとします。外部から指定する場合は型変数を使用します。
-```erg
+```python
T!: Nat -> Type
# ~>は適用前後の型引数の状態を示す(このときselfは可変参照でなくてはならない)
T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => ()
@@ -39,7 +41,7 @@ T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => ()
所有権が奪われる場合は以下のようになります。
-```erg
+```python
# Nを使わないなら_で省略可
# .some_method!: |N, X: Nat| T!(N).({X}) => T!(N+X)
.some_method!|N, X: Nat|(self(N), X: Nat) => T!(N+X)
@@ -50,7 +52,7 @@ T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => ()
``で囲むことで通常の関数と同じように定義できます。
`and`や`or`などの中置アルファベット演算子は囲むことで中置演算子として定義できます。
-```erg
+```python
and(x, y, z) = x and y and z
`_+_`(x: Foo, y: Foo) = x.a + y.a
`-_`(x: Foo) = Foo.new(-x.a)
diff --git a/doc/JA/syntax/23_closure.md b/doc/JA/syntax/23_closure.md
index 5d0408a6..6e2ddda6 100644
--- a/doc/JA/syntax/23_closure.md
+++ b/doc/JA/syntax/23_closure.md
@@ -1,8 +1,10 @@
# クロージャ
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/23_closure.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
Ergのサブルーチンには、外部変数を捕捉する「クロージャ」という機能があります。
-```erg
+```python
outer = 1
f x = outer + x
assert f(1) == 2
@@ -10,7 +12,7 @@ assert f(1) == 2
不変オブジェクトと同じく、可変オブジェクトも捕捉できます。
-```erg
+```python
sum = !0
for! 1..10, i =>
sum.add! i
@@ -25,7 +27,7 @@ assert sum == 46
しかし、関数は可変オブジェクトを捕捉できないので注意が必要です。
仮に可変オブジェクトが関数内で参照できると、以下のようなコードが書けてしまいます。
-```erg
+```python
# !!! このコードは実際にはエラーになる !!!
i = !0
f x = i + x
@@ -39,7 +41,7 @@ assert f 1 == 2
関数定義時点での可変オブジェクトの内容がほしい場合は`.clone`を呼び出します。
-```erg
+```python
i = !0
immut_i = i.clone().freeze()
f x = immut_i + x
@@ -50,7 +52,7 @@ assert f 1 == 1
## 可変状態の回避、関数型プログラミング
-```erg
+```python
# Erg
sum = !0
for! 1..10, i =>
@@ -71,7 +73,7 @@ assert sum == 45
しかし、Ergではもっとシンプルな書き方を推奨します。
サブルーチンと可変オブジェクトを使って状態を持ち回す代わりに、関数を使用する状態を局所化するスタイルを使います。これは関数型プログラミングと呼ばれます。
-```erg
+```python
# Functional style
sum = (1..10).sum()
assert sum == 45
@@ -83,7 +85,7 @@ assert sum == 45
`fold`はイテレータのメソッドで、各イテレーションごとに引数`f`を実行します。
結果を蓄積するカウンタの初期値は`init`で指定し、`acc`に蓄積されていきます。
-```erg
+```python
# start with 0, result will
sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i)
assert sum == 45
diff --git a/doc/JA/syntax/24_module.md b/doc/JA/syntax/24_module.md
index 9fc334f4..5d3942ce 100644
--- a/doc/JA/syntax/24_module.md
+++ b/doc/JA/syntax/24_module.md
@@ -1,18 +1,20 @@
# モジュール
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/24_module.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
Ergでは、ファイル自体を1つのレコードとみなすことができます。これをモジュールと呼びます。
-```erg: foo.er
+```python: foo.er
# foo.er
.i = 1
```
-```erg
+```python
# fooモジュールを定義するのはこのレコードを定義するのとほとんど同じ
foo = {.i = 1}
```
-```erg: bar.er
+```python: bar.er
# bar.er
foo = import "foo"
print! foo #
@@ -21,7 +23,7 @@ assert foo.i == 1
モジュール型はレコード型でもあるので、分解代入が可能です。
-```erg
+```python
{sin; cos; ...} = import "math"
```
diff --git a/doc/JA/syntax/25_object_system.md b/doc/JA/syntax/25_object_system.md
index b2a840e8..88076206 100644
--- a/doc/JA/syntax/25_object_system.md
+++ b/doc/JA/syntax/25_object_system.md
@@ -1,5 +1,7 @@
# Object(対象体)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/25_object_system.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
変数に代入できる全てのデータです。`Object`クラスの持つ属性は以下の通りです。
* `.__repr__`: オブジェクトの(リッチでない)文字列表現を返します
@@ -7,15 +9,15 @@
* `.__dir__`: オブジェクトの属性を一覧にして返します
* `.__hash__`: オブジェクトのハッシュ値を返します
* `.__getattribute__`: オブジェクトの属性を取得して返します
-* `.clone`: オブジェクトのクローン(メモリ上に独立な実体を持つ)を生成して返します
-* `.copy`: オブジェクトのコピー(メモリ上で同じものをさす)を返します
+* `.clone`: オブジェクトのクローン(メモリ上に独立な実体を持つ)を生成して返します
+* `.copy`: オブジェクトのコピー(メモリ上で同じものをさす)を返します
## Record(レコード)
レコードリテラル(`{attr = value; ...}`)で生成されるオブジェクトです。
このオブジェクトは`.clone`や`.__sizeof__`などの基本的なメソッドを持ちます。
-```erg
+```python
obj = {.x = 1}
assert obj.x == 1
@@ -27,7 +29,7 @@ assert obj2.x == 1 and obj2.y == 2
オブジェクトと関連付けられたオブジェクトです。特に自身(`self`)を暗黙の第一引数にとるサブルーチン属性はメソッド(method)と呼ばれます。
-```erg
+```python
# private_attrには`.`がないことに注意
record = {.public_attr = j; private_attr = 2; .method = self -> self.i + 1}
record.public_attr == 2
diff --git a/doc/JA/syntax/26_pattern_matching.md b/doc/JA/syntax/26_pattern_matching.md
index c86cc43f..83737503 100644
--- a/doc/JA/syntax/26_pattern_matching.md
+++ b/doc/JA/syntax/26_pattern_matching.md
@@ -1,10 +1,12 @@
# パターンマッチ、論駁可能性
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/26_pattern_matching.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
## Ergで使用可能なパターン
### 変数パターン
-```erg
+```python
# basic assignment
i = 1
# with type
@@ -28,7 +30,7 @@ a: Array Int, 4 = [0, 1, 2, 3]
### リテラルパターン
-```erg
+```python
# もし`i`がコンパイル時に1と判断できない場合は、TypeErrorが発生する。
# `_: {1} = i`を省略したもの
1 = i
@@ -47,7 +49,7 @@ fib n: Nat = fib n-1 + fib n-2
### 定数パターン
-```erg
+```python
cond = False
match! cond:
True => print! "cond is True"
@@ -64,7 +66,7 @@ name = match num:
### 篩パターン
-```erg
+```python
# この2つは同じ
Array(T, N: {N | N >= 3})
Array(T, N | N >= 3)
@@ -75,7 +77,7 @@ f(1, 0) # TypeError: N (2nd parameter) must be 1 or more
### 破棄(ワイルドカード)パターン
-```erg
+```python
_ = 1
_: Int = 1
zero _ = 0
@@ -86,7 +88,7 @@ right(_, r) = r
後述するタプル/配列/レコードパターンと組み合わせて使います。
-```erg
+```python
[i, ...j] = [1, 2, 3, 4]
assert j == [2, 3, 4]
first|T|(fst: T, ...rest: T) = fst
@@ -95,7 +97,7 @@ assert first(1, 2, 3) == 1
### タプルパターン
-```erg
+```python
(i, j) = (1, 2)
((k, l), _) = ((1, 2), (3, 4))
# ネストしていないなら()を省略可能(1, 2は(1, 2)として扱われる)
@@ -106,7 +108,7 @@ f(x, y) = ...
### 配列パターン
-```erg
+```python
[i, j] = [1, 2]
[[k, l], _] = [[1, 2], [3, 4]]
@@ -116,7 +118,7 @@ length [_, ...rest] = 1 + length rest
#### レコードパターン
-```erg
+```python
record = {i = 1; j = 2; k = 3}
{j; ...} = record # i, k will be freed
@@ -133,7 +135,7 @@ f {x: Int; y: Int} = ...
### データクラスパターン
-```erg
+```python
Point = Inherit {x = Int; y = Int}
p = Point::{x = 1; y = 2}
Point::{x; y} = p
@@ -156,7 +158,7 @@ List T.
※実際には単なる列挙型
-```erg
+```python
match x:
i: {1, 2} -> "one or two: {i}"
_ -> "other"
@@ -166,7 +168,7 @@ match x:
※実際には単なる区間型
-```erg
+```python
# 0 < i < 1
i: 0<..<1 = 0.5
# 1 < j <= 2
diff --git a/doc/JA/syntax/27_comprehension.md b/doc/JA/syntax/27_comprehension.md
index 4448dfed..2e201462 100644
--- a/doc/JA/syntax/27_comprehension.md
+++ b/doc/JA/syntax/27_comprehension.md
@@ -1,5 +1,7 @@
# Comprehension(内包表記)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/27_comprehension.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
`[expr | (name <- iterable)+ (predicate)*]`で配列、
`{expr | (name <- iterable)+ (predicate)*}`でセット、
`{key: value | (name <- iterable)+ (predicate)*}`でDictが作れます。
@@ -9,7 +11,7 @@
内包表記の例
-```erg
+```python
# レイアウト節はi
# バインド節はi <- [0, 1, 2]
assert [i | i <- [0, 1, 2]] == [0, 1, 2]
@@ -36,7 +38,7 @@ Haskellのリスト内包表記の場合、変数の順番は結果に違いを
[(i, j) | j <- [3..5], i <- [1..3]] == [(1,3),(2,3),(3,3),(1,4),(2,4),(3,4),(1,5),(2,5),(3,5)]
```
-```erg
+```python
# Erg
assert [(i, j) | i <- 1..<3; j <- 3..<5] == [(i, j) | j <- 3..<5; i <- 1..<3]
```
@@ -53,7 +55,7 @@ assert [(i, j) for i in range(1, 3) for j in range(3, 5)] == [(i, j) for j in ra
内包表記と似たものに、篩型があります。篩型は`{Name: Type | Predicate}`という形式で作られる型(列挙型)です。
篩型の場合、Nameは1つまででレイアウトは指定できず(ただしタプル型などにすれば複数の値は扱えます)、Predicateはコンパイル時計算できるもの、つまり定数式のみが指定できます。
-```erg
+```python
Nat = {I: Int | I >= 0}
# 述語式がandだけの場合、;で代替できる
# Nat2D = {(I, J): (Int, Int) | I >= 0; J >= 0}
diff --git a/doc/JA/syntax/28_spread_syntax.md b/doc/JA/syntax/28_spread_syntax.md
index 52c2c658..f201cb2d 100644
--- a/doc/JA/syntax/28_spread_syntax.md
+++ b/doc/JA/syntax/28_spread_syntax.md
@@ -1,8 +1,10 @@
# Spread assignment (展開代入)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/28_spread_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
分解代入において、変数の前に`...`を置くと残りの要素を全てその変数に展開できます。これを展開代入と呼びます。
-```erg
+```python
[x, ...y] = [1, 2, 3]
assert x == 1
assert y == [2, 3]
@@ -16,7 +18,7 @@ assert y == (2, 3)
`...`のあとに何も書かない場合、残りの要素は無視して代入されます。このタイプの展開代入を特に抽出代入と呼びます。
抽出代入は、モジュールやレコード内にある特定の属性をローカルに持ってくる際に便利な構文です。
-```erg
+```python
{sin; cos; tan; ..} = import "math"
```
@@ -24,14 +26,14 @@ assert y == (2, 3)
レコードでも同じようにできます。
-```erg
+```python
record = {x = 1; y = 2}
{x; y; ...} = record
```
全て展開したい場合は`{*} = record`とします。OCamlなどでいう`open`です。
-```erg
+```python
record = {x = 1; y = 2}
{*} = record
assert x == 1 and y == 2
diff --git a/doc/JA/syntax/29_decorator.md b/doc/JA/syntax/29_decorator.md
index 90fd1587..2fcc956c 100644
--- a/doc/JA/syntax/29_decorator.md
+++ b/doc/JA/syntax/29_decorator.md
@@ -1,9 +1,11 @@
# デコレータ(修飾子)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/29_decorator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
デコレータは型や関数に特定の状態や振る舞いを追加したり明示するために使われます。
デコレータの文法は以下の通りです。
-```erg
+```python
@deco
X = ...
```
@@ -12,7 +14,7 @@ X = ...
デコレータは特別なオブジェクトではなく、その実体は単なる1引数関数です。デコレータは以下の疑似コードと等価です。
-```erg
+```python
X = ...
X = deco(X)
```
@@ -20,7 +22,7 @@ X = deco(X)
Ergでは変数の再代入が出来ないので、上のようなコードは通りません。
単なる変数の場合は`X = deco(...)`と同じなのですが、インスタントブロックやサブルーチンの場合はそうすることができないので、デコレータが必要になってきます。
-```erg
+```python
@deco
f x =
y = ...
@@ -50,7 +52,7 @@ C = Class ...
引数のトレイトを実装することを示します。
-```erg
+```python
Add = Trait {
.`_+_` = Self.(Self) -> Self
}
@@ -71,7 +73,7 @@ C.
トレイトにデフォルトで付属するアタッチメントパッチを指定します。
これによって、Rustのトレイトと同じ挙動を再現できます。
-```erg
+```python
# foo.er
Add R = Trait {
.AddO = Type
@@ -88,7 +90,7 @@ AddForOdd.AddO = Even
こうすると、他のモジュールからトレイトをインポートした際に、アタッチメントパッチが自動で適用されます。
-```erg
+```python
# 本来IntIsBinAdd, OddIsBinAddも同時にインポートする必要があるが、アタッチメントパッチなら省略可
{BinAdd; ...} = import "foo"
@@ -98,7 +100,7 @@ assert Odd.AddO == Even
内部的にはトレイトの`.attach`メソッドを使って結びつけているだけです。コンフリクトする場合はトレイトの`.detach`メソッドで外すことができます。
-```erg
+```python
@Attach X
T = Trait ...
assert X in T.attaches
diff --git a/doc/JA/syntax/30_error_handling.md b/doc/JA/syntax/30_error_handling.md
index 841296fa..57dde72d 100644
--- a/doc/JA/syntax/30_error_handling.md
+++ b/doc/JA/syntax/30_error_handling.md
@@ -1,5 +1,7 @@
# エラーハンドリングシステム
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/30_error_handling.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
主にResult型を使用します。
ErgではError型オブジェクトを捨てる(トップレベルで対応しない)とエラーが発生します。
@@ -30,7 +32,7 @@ except e:
上の例では、例外がどの関数から送出されたものなのか、このコードだけでは分かりません。関数定義まで遡っても、その関数が例外を出すかを判別するのは難しいです。
-```erg
+```python
# Erg
try!:
do!:
@@ -50,7 +52,7 @@ try!:
`Error`/`Result`型単体では副作用が発生しないので、例外と違い送出場所などの情報(Context、文脈)を持てませんが、`.context`メソッドを使えば`Error`オブジェクトに情報を付加できます。`.context`メソッドは`Error`オブジェクト自身を消費して新しい`Error`オブジェクトを作るタイプのメソッドです。チェイン可能であり、複数のコンテクストを保持できます。
-```erg
+```python
f() =
todo() \
.context "to be implemented in ver 1.2" \
@@ -71,7 +73,7 @@ f()
`.stack`は呼び出し元オブジェクトの配列です。Errorオブジェクトは`return`(`?`によるものも含む)されるたびにその呼出元サブルーチンを`.stack`に積んでいきます。
そして`return`ができないコンテクストで`?`されるなり`.unwrap`されるなりすると、トレースバックを表示しながらパニックします。
-```erg
+```python
f x =
...
y = foo.try_some(x)?
@@ -100,7 +102,7 @@ Ergには回復不能なエラーへの対処として __パニッキング__
パニックは`panic`関数で行います。
-```erg
+```python
panic "something went wrong!"
```
diff --git a/doc/JA/syntax/31_pipeline.md b/doc/JA/syntax/31_pipeline.md
index f4b708cd..4ee29ae6 100644
--- a/doc/JA/syntax/31_pipeline.md
+++ b/doc/JA/syntax/31_pipeline.md
@@ -1,8 +1,10 @@
# パイプライン演算子
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/31_pipeline.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
パイプライン演算子は、次のように使います。
-```erg
+```python
assert f(g(x)) == (x |> g |> f)
assert f(g(x, y)) == ((x, y) |> g |> f)
```
@@ -11,7 +13,7 @@ assert f(g(x, y)) == ((x, y) |> g |> f)
パイプライン演算子はメソッドに対しても使えます。メソッドの場合、`object.method(args)`が`object |>.method(args)`と変わります。
単に`|>`が増えただけにも見えるが、結合強度が低めなので`()`の量を減らせる場合があります。
-```erg
+```python
rand = -1.0..1.0 |>.sample!()
log rand # 0.2597...
diff --git a/doc/JA/syntax/32_integration_with_Python.md b/doc/JA/syntax/32_integration_with_Python.md
index 3d3b388a..997f5504 100644
--- a/doc/JA/syntax/32_integration_with_Python.md
+++ b/doc/JA/syntax/32_integration_with_Python.md
@@ -1,11 +1,13 @@
# Pythonとの連携
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/32_integration_with_Python.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
## Pythonへのexport
Ergスクリプトをコンパイルすると.pycファイルが生成されますが、これは単純にPythonのモジュールとして読み込むことができます。
ただし、Erg側で非公開に設定した変数はPythonからアクセスできません。
-```erg
+```python
# foo.er
.public = "this is a public variable"
private = "this is a private variable"
@@ -30,7 +32,7 @@ Pythonから取り込んだオブジェクトはデフォルトですべて`Obje
Python標準ライブラリにあるAPIはすべてErg開発チームにより型が指定されています。
-```erg
+```python
time = pyimport "time"
time.sleep! 1
```
@@ -49,7 +51,7 @@ def baz():
...
```
-```erg
+```python
# foo.d.er
foo = pyimport "foo"
.X = declare foo.'X', Int
@@ -57,14 +59,14 @@ foo = pyimport "foo"
.baz! = declare foo.'baz', () => Int
```
-```erg
+```python
foo = pyimport "foo"
assert foo.bar(1) in Int
```
これは、実行時に型チェックを行うことで型安全性を担保しています。`declare`関数は概ね以下のように動作します。
-```erg
+```python
declare|S: Subroutine| sub!: S, T =
# 実は、=>はブロックの副作用がなければ関数にキャストできる
x =>
diff --git a/doc/JA/syntax/33_package_system.md b/doc/JA/syntax/33_package_system.md
index 8ae76114..b54956d5 100644
--- a/doc/JA/syntax/33_package_system.md
+++ b/doc/JA/syntax/33_package_system.md
@@ -1,5 +1,7 @@
# パッケージシステム
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/33_package_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
Ergのパッケージはアプリケーションであるappパッケージとライブラリであるlibパッケージに大別できます。
appパッケージのエントリポイントは`src/app.er`です。`app.er`内に定義された`main`関数が実行されます。
libパッケージのエントリポイントは`src/lib.er`です。パッケージをインポートすることは`lib.er`をインポートすることと等価になります。
@@ -25,7 +27,7 @@ libパッケージのエントリポイントは`src/lib.er`です。パッケ
`foo`モジュールはファイルからなるモジュールで、`bar`モジュールはディレクトリからなるモジュールです。`bar`モジュールはさらに`baz`, `qux`モジュールを内部に持ちます。
このモジュールは単に`bar`モジュールの属性であり、`app.er`からは以下のようにアクセスできます。
-```erg
+```python
# app.er
foo = import "foo"
bar = import "bar"
@@ -47,7 +49,7 @@ main args =
└─ foo.test.er
```
-```erg
+```python
# app.er
foo = import "foo"
@@ -66,14 +68,14 @@ main args =
└─ qux.er
```
-```erg
+```python
# foo.er
bar = import "bar"
bar.qux
bar.baz # AttributeError: module 'baz' is private
```
-```erg
+```python
# qux.er
baz = import "baz"
```
diff --git a/doc/JA/syntax/34_generator.md b/doc/JA/syntax/34_generator.md
index eee9b31c..0cfdc690 100644
--- a/doc/JA/syntax/34_generator.md
+++ b/doc/JA/syntax/34_generator.md
@@ -1,8 +1,10 @@
# ジェネレータ
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/34_generator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
ジェネレータは、ブロック中で`yield!`プロシージャを使う特殊なプロシージャです。
-```erg
+```python
g!() =
yield! 1
yield! 2
@@ -13,7 +15,7 @@ g!() =
これは`return`と同じく渡された値を戻り値として返すものですが、その時点でのブロックの実行状態を保存し、もう一度呼び出された際に続きから実行するという特徴があります。
ジェネレータはプロシージャでありながらイテレータでもあります。Pythonのジェネレータはイテレータを生成する関数ですが、Ergは直接イテレートします。プロシージャ自体は一般に可変オブジェクトではありません(`!`が付かない)が、ジェネレータは実行ごとに自身の内容が変わる得るので可変オブジェクトです。
-```erg
+```python
# Generator! < Proc
g!: Generator!((), Int)
assert g!() == 1
@@ -23,7 +25,7 @@ assert g!() == 3
Pythonスタイルのジェネレータは以下のようにして定義できます。
-```erg
+```python
make_g() = () =>
yield! 1
yield! 2
diff --git a/doc/JA/syntax/SUMMARY.md b/doc/JA/syntax/SUMMARY.md
index 774c354b..de5dfd3d 100644
--- a/doc/JA/syntax/SUMMARY.md
+++ b/doc/JA/syntax/SUMMARY.md
@@ -1,5 +1,7 @@
# Summary
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/SUMMARY.md&commit_hash=2ce482b1c8407332b3b74f4c3e5596f373f9a657)
+
- [Basics](./00_basic.md)
- [Literal](./01_literal.md)
- [Name](02_name.md)
diff --git a/doc/JA/syntax/container_ownership.md b/doc/JA/syntax/container_ownership.md
index f48b4aa3..65c514be 100644
--- a/doc/JA/syntax/container_ownership.md
+++ b/doc/JA/syntax/container_ownership.md
@@ -1,8 +1,10 @@
# Subscript(添字アクセス)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/container_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
`[]`は通常のメソッドとは異なっています。
-```erg
+```python
a = [!1, !2]
a[0].inc!()
assert a == [2, 2]
@@ -13,7 +15,7 @@ assert a == [2, 2]
よって、`[]`は実際には`.`と同じく特別な構文の一部です。Pythonとは違い、オーバーロードできません。
メソッドで`[]`の挙動を再現することもできません。
-```erg
+```python
C = Class {i = Int!}
C.get(ref self) =
self::i # TypeError: `self::i` is `Int!` (require ownership) but `get` doesn't own `self`
@@ -33,7 +35,7 @@ own_do! C.new({i = 1}).steal(), i => i.inc!()
また、`[]`は所有権を奪うこともできますが、その際に要素がシフトするわけではありません。
-```erg
+```python
a = [!1, !2]
i = a[0]
i.inc!()
diff --git a/doc/EN/syntax/grammar.txt b/doc/JA/syntax/grammar.md
similarity index 98%
rename from doc/EN/syntax/grammar.txt
rename to doc/JA/syntax/grammar.md
index deaff920..06a6d6d2 100644
--- a/doc/EN/syntax/grammar.txt
+++ b/doc/JA/syntax/grammar.md
@@ -1,4 +1,5 @@
# The Grammar of Erg (ver 0.1.0, provisional)
+```
special_op ::= '=' | '->' | '=>' | '.' | ',' | ':' | '::' | '|>' | '&'
separator ::= ';' | '\n'
escape ::= '\'
@@ -76,7 +77,7 @@ record ::= '{' '=' '}'
set ::= '{' '}'
| '{' expr (',' expr)* ','? '}'
dict ::= '{' ':' '}'
- | '{' symbol ':' expr (',' symbol ':' expr)* ','? '}'
+ | '{' expr ':' expr (',' expr ':' expr)* ','? '}'
tuple ::= '(' ')'
| '(' expr (',' expr)* ','? ')'
indent ::= /* ... */
@@ -86,3 +87,4 @@ expr ::= accessor | literal
| call | def | lambda
line ::= expr separator+
program ::= expr? | (line | comment)*
+```
\ No newline at end of file
diff --git a/doc/JA/syntax/indexes.md b/doc/JA/syntax/indexes.md
index 0db44b64..07066223 100644
--- a/doc/JA/syntax/indexes.md
+++ b/doc/JA/syntax/indexes.md
@@ -1,5 +1,7 @@
# 索引
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/indexes.md&commit_hash=438bcb89ea692f219b30f3a3ba107888b23eae98)
+
この索引にないAPIについては[こちら](../API/index.md)を参照してください。
用語の意味については[こちら](../dev_guide/terms.md)を参照。
diff --git a/doc/JA/syntax/quick_tour.md b/doc/JA/syntax/quick_tour.md
index 66ddbdd3..b93bc059 100644
--- a/doc/JA/syntax/quick_tour.md
+++ b/doc/JA/syntax/quick_tour.md
@@ -1,5 +1,7 @@
# Quick Tour
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/quick_tour.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
`syntax`以下のドキュメントは、概ねプログラミング初心者でも理解できることを目指して書かれています。
すでにPythonやRust, Haskellなどの言語を習得されている方にとっては、少し冗長であるかもしれません。
@@ -10,7 +12,7 @@
変数は`=`で定義します。Haskellと同じように、一度定義した変数は書き換えられません。ただし別のスコープではシャドーイングできます。
-```erg
+```python
i = 0
if True:
i = 1
@@ -20,7 +22,7 @@ assert i == 0
大文字で始まるものは定数です。コンパイル時計算できるものだけが定数にできます。
また、定数は定義以降すべてのスコープで同一です。
-```erg
+```python
PI = 3.141592653589793
match random.random!(0..10):
PI:
@@ -32,7 +34,7 @@ match random.random!(0..10):
Pythonと違い、変数の型のみを先に宣言することが可能です。
当然、宣言の型と実際に代入されるオブジェクトの型は互換していなくてはなりません。
-```erg
+```python
i: Int
i = 10
```
@@ -41,7 +43,7 @@ i = 10
Haskellと同じように定義できます。
-```erg
+```python
fib 0 = 0
fib 1 = 1
fib n = fib(n - 1) + fib(n - 2)
@@ -49,7 +51,7 @@ fib n = fib(n - 1) + fib(n - 2)
無名関数は以下のように定義できます。
-```erg
+```python
i -> i + 1
assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4]
```
@@ -62,7 +64,7 @@ Erg独自の演算子は以下の通りです。
Ocamlの`ref`のようなものです。
-```erg
+```python
i = !0
i.update! x -> x + 1
assert i == 1
@@ -72,13 +74,13 @@ assert i == 1
副作用のあるサブルーチンはプロシージャと呼ばれ、`!`がついています。
-```erg
+```python
print! 1 # 1
```
## ジェネリック関数(多相関数)
-```erg
+```python
id|T|(x: T): T = x
id(1): Int
id("a"): Str
@@ -88,7 +90,7 @@ id("a"): Str
ML系言語にあるレコード(あるいはJSのオブジェクトリテラル)に相当するものを利用できます。
-```erg
+```python
p = {x = 1; y = 2}
```
@@ -96,7 +98,7 @@ p = {x = 1; y = 2}
Ergは可変オブジェクト(`!`演算子で可変化したオブジェクト)に所有権がついており、複数の場所から書き換えられません。
-```erg
+```python
i = !0
j = i
assert j == 0
@@ -109,13 +111,13 @@ i # MoveError
変数の頭に`.`をつけると、その変数は公開変数となり、外部モジュールから参照できるようになります。
-```erg
+```python
# foo.er
.x = 1
y = 1
```
-```erg
+```python
foo = import "foo"
assert foo.x == 1
foo.y # VisibilityError
@@ -125,7 +127,7 @@ foo.y # VisibilityError
### 変数パターン
-```erg
+```python
# basic assignment
i = 1
# with type
@@ -137,7 +139,7 @@ fn: Int -> Int = x -> x + 1
### リテラルパターン
-```erg
+```python
# if `i` cannot be determined to be 1 at compile time, TypeError occurs.
# short hand of `_: {1} = i`
1 = i
@@ -154,7 +156,7 @@ fib n: Nat = fib n-1 + fib n-2
### 定数パターン
-```erg
+```python
PI = 3.141592653589793
E = 2.718281828459045
num = PI
@@ -166,7 +168,7 @@ name = match num:
### 破棄(ワイルドカード)パターン
-```erg
+```python
_ = 1
_: Int = 1
right(_, r) = r
@@ -176,7 +178,7 @@ right(_, r) = r
後述するタプル/配列/レコードパターンと組み合わせて使う。
-```erg
+```python
[i, ...j] = [1, 2, 3, 4]
assert j == [2, 3, 4]
first|T|(fst: T, ...rest: T) = fst
@@ -185,7 +187,7 @@ assert first(1, 2, 3) == 1
### タプルパターン
-```erg
+```python
(i, j) = (1, 2)
((k, l), _) = ((1, 2), (3, 4))
# ネストしていないなら()を省略可能(1, 2は(1, 2)として扱われる)
@@ -194,14 +196,14 @@ m, n = 1, 2
### 配列パターン
-```erg
+```python
length [] = 0
length [_, ...rest] = 1 + length rest
```
#### レコードパターン
-```erg
+```python
{sin; cos; tan; ...} = import "math"
{*} = import "math" # import all
@@ -213,7 +215,7 @@ age = match person:
### データクラスパターン
-```erg
+```python
Point = Inherit {x = Int; y = Int}
p = Point::{x = 1; y = 2}
Point::{x; y} = p
@@ -221,7 +223,7 @@ Point::{x; y} = p
## 内包表記
-```erg
+```python
odds = [i | i <- 1..100; i % 2 == 0]
```
@@ -234,7 +236,7 @@ Ergでは多重・多段継承をサポートしていません。
Rustのトレイトと似ていますが、より本来の意味に近いもので、合成や分離ができ、属性とメソッドは対等に扱われます。
また、実装を伴いません。
-```erg
+```python
XY = Trait {x = Int; y = Int}
Z = Trait {z = Int}
XYZ = XY and Z
@@ -254,13 +256,13 @@ Point.
述語式で型に制限をかけられます。
-```erg
+```python
Nat = {I: Int | I >= 0}
```
## 値を含むパラメトリック型(依存型)
-```erg
+```python
a: [Int; 3]
b: [Int; 4]
a + b: [Int; 7]
diff --git a/doc/JA/syntax/type/01_type_system.md b/doc/JA/syntax/type/01_type_system.md
index f8c07359..c6d5d35d 100644
--- a/doc/JA/syntax/type/01_type_system.md
+++ b/doc/JA/syntax/type/01_type_system.md
@@ -1,12 +1,14 @@
# Ergの型システム
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/01_type_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
以下では、Ergの型システムを概略的に説明します。詳細については他の項で解説します。
## 定義方法
Ergの特徴的な点として、(通常の)変数、関数(サブルーチン)、型(カインド)の定義にあまり大きな構文上の違いがないというところがあります。すべて、通常の変数・関数定義の文法に従って定義されます。
-```erg
+```python
f i: Int = i + 1
f #
f(1) # 2
@@ -64,7 +66,7 @@ Ergの配列(Array)はPythonでいうところのリストとなります。`[In
> __Note__: `(Type; N)`は型であり値でもあるので、このような使い方もできます。
>
-> ```erg
+> ```python
> Types = (Int, Str, Bool)
>
> for! Types, T =>
@@ -73,7 +75,7 @@ Ergの配列(Array)はPythonでいうところのリストとなります。`[In
> a: Types = (1, "aaa", True)
> ```
-```erg
+```python
pop|T, N|(l: [T; N]): ([T; N-1], T) =
[...l, last] = l
(l, last)
@@ -86,7 +88,7 @@ lpop|T, N|(l: [T; N]): (T, [T; N-1]) =
`!`の付く型はオブジェクトの内部構造書き換えを許可する型です。例えば`[T; !N]`クラスは動的配列となります。
`T`型オブジェクトから`T!`型オブジェクトを生成するには、単項演算子の`!`を使います。
-```erg
+```python
i: Int! = !1
i.update! i -> i + 1
assert i == 2
@@ -101,7 +103,7 @@ assert mut_arr == [1, 2, 3, 4]
型は以下のように定義します。
-```erg
+```python
Point2D = {.x = Int; .y = Int}
```
@@ -114,7 +116,7 @@ Point2D = {.x = Int; .y = Int}
以下は`+`(中置演算子)を要求する `Add`型の定義です。`R, O`はいわゆる型引数で、`Int`や`Str`など実装のある型(クラス)が入れられます。他の言語で型引数には特別な記法(ジェネリクス、テンプレートなど)が与えられていますが、Ergでは通常の引数と同じように定義できます。
なお型引数は型オブジェクト以外も使用できます。例えば配列型`[Int; 3]`は`Array Int, 3`の糖衣文法です。型の実装がかぶる場合、ユーザは明示的に選択しなくてはなりません。
-```erg
+```python
Add R = Trait {
.AddO = Type
.`_+_` = Self.(R) -> Self.AddO
@@ -123,7 +125,7 @@ Add R = Trait {
.`_+_`は Add.`_+_`の省略形です。前置演算子の.`+_`は`Num`型のメソッドです。
-```erg
+```python
Num = Add and Sub and Mul and Eq
NumImpl = Patch Num
NumImpl.
@@ -133,7 +135,7 @@ NumImpl.
多相型は関数のように扱えます。`Mul Int, Str`などのように指定して単相化します(多くの場合は指定しなくても実引数で推論されます)。
-```erg
+```python
1 + 1
`_+_` 1, 1
Nat.`_+_` 1, 1
@@ -145,7 +147,7 @@ Int.`_+_` 1, 1
これは、`Int <: Ratio`であるために`1`が`Ratio`にダウンキャストされるからです。
しかしこれはキャストされません。
-```erg
+```python
i = 1
if i: # TypeError: i: Int cannot cast to Bool, use Int.is_zero() instead.
log "a"
@@ -158,7 +160,7 @@ if i: # TypeError: i: Int cannot cast to Bool, use Int.is_zero() instead.
Ergは静的ダックタイピングを採用しており、明示的に型を指定する必要は殆どありません。
-```erg
+```python
f x, y = x + y
```
@@ -167,7 +169,7 @@ f x, y = x + y
`{0}`と`{1}`は`Int`や`Nat`などの部分型となる列挙型です。
列挙型などには名前を付けて要求/実装メソッドを付けられます。その型にアクセスできる名前空間では、要求を満たすオブジェクトは実装メソッドを使用できます。
-```erg
+```python
Binary = Patch {0, 1}
Binary.
# selfにはインスタンスが格納される。この例では0か1のどちらか。
@@ -184,7 +186,7 @@ Binary.
以降は`0.to_bool()`というコードが可能となります(もっとも`0 as Bool == False`がビルトインで定義されていますが)。
コード中に示されたように、実際に`self`を書き換える事のできる型の例を示します。
-```erg
+```python
Binary! = Patch {0, 1}!
Binary!.
switch! ref! self = match! self:
@@ -198,7 +200,7 @@ print! b # => 0
## 構造型(無名型)
-```erg
+```python
Binary = {0, 1}
```
@@ -211,14 +213,14 @@ Binary = {0, 1}
下のような指定はできません。`Add`はそれぞれ別のものを指すと解釈されるからです。
例えば、`Int`と`Str`はともに`Add`だが、`Int`と`Str`の加算はできません。
-```erg
+```python
add l: Add, r: Add =
l + r # TypeError: there is no implementation of `_+_`: |T, U <: Add| (T, U) ->
```
また、下の`A`, `B`は同じ型とはみなされません。しかし、型`O`は一致するとみなされます。
-```erg
+```python
... |R1; R2; O; A <: Add(R1, O); B <: Add(R2, O)|
```
diff --git a/doc/JA/syntax/type/02_basic.md b/doc/JA/syntax/type/02_basic.md
index 922b5a35..f720880c 100644
--- a/doc/JA/syntax/type/02_basic.md
+++ b/doc/JA/syntax/type/02_basic.md
@@ -1,10 +1,12 @@
# 型に関する基本的な文法
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/02_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
## 型指定
Ergでは以下のように`:`の後に変数の型を指定します。代入と同時に行うこともできます。
-```erg
+```python
i: Int # これから使う変数iはInt型であると宣言する
i: Int = 1
j = 1 # type specification can be omitted
@@ -12,7 +14,7 @@ j = 1 # type specification can be omitted
通常の式に対しても型指定することができます。
-```erg
+```python
i = 1: Int
f([1, "a"]: [Int or Str])
```
@@ -20,7 +22,7 @@ f([1, "a"]: [Int or Str])
単純な変数代入の場合、ほとんどの型指定は省略可能です。
型指定は単純な変数よりもサブルーチンや型の定義時に役立ちます。
-```erg
+```python
# 引数の型指定
f x, y: Array Int = ...
T X, Y: Array Int = ...
@@ -28,20 +30,20 @@ T X, Y: Array Int = ...
上の場合、`x, y`は共に`Array Int`であることに注意して下さい。
-```erg
+```python
# 大文字変数の値は定数式でなくてはならない
f X: Int = X
```
あるいは、型引数の情報が完全にいらない場合は`_`で省略することもできます。
-```erg
+```python
g v: [T; _] = ...
```
ただし、型指定の箇所で`_`を指定するとそれは`Object`を意味することに注意して下さい。
-```erg
+```python
f x: _, y: Int = x + y # TypeError: + is not implemented between Object and Int
```
@@ -52,7 +54,7 @@ Ergでは`:`(型宣言演算子)による型と式の関係指定の他に、`<:
これも単純な変数の指定より、サブルーチンや型の定義時に使うことが多いです。
-```erg
+```python
# 引数の部分型指定
f X <: T = ...
@@ -66,7 +68,7 @@ Iterable T = Trait {
また、クラス定義時に部分型指定を行うと、クラスが指定した型のサブタイプか静的に検査できます。
-```erg
+```python
# クラスCはShowのサブタイプ
C = Class Object, Impl=Show
C.show self = ... # Showの要求属性
@@ -74,7 +76,7 @@ C.show self = ... # Showの要求属性
特定の場合だけ部分型指定することもできます。
-```erg
+```python
K T: Eq
K Int <: Show and Eq
K T = Class Object
@@ -87,7 +89,7 @@ K(Int).
構造型を実装する際は、部分型指定を行うことを推奨します。
構造的部分型付けの特性から、要求属性の実装をする際にタイポや型指定の間違いがあってもエラーが出ないためです。
-```erg
+```python
C = Class Object
C.shoe self = ... # TypoのせいでShowが実装できていない(単なる固有のメソッドとみなされる)
```
@@ -96,7 +98,7 @@ C.shoe self = ... # TypoのせいでShowが実装できていない(単なる固
トレイトやクラスには、モジュール内でのみ属性を定義できます。
-```erg
+```python
C = Class()
C.pub_attr = "this is public"
C::private_attr = "this is private"
@@ -107,7 +109,7 @@ assert c.pub_attr == "this is public"
`C.`か`C::`のあとに改行してインデント以下にまとめて定義する文法を一括定義(batch definition)といいます。
-```erg
+```python
C = Class()
C.pub1 = ...
C.pub2 = ...
@@ -127,7 +129,7 @@ C::
型には別名(エイリアス)を付けることができます。これにより、レコード型など長い型を短く表現できます。
-```erg
+```python
Id = Int
Point3D = {x = Int; y = Int; z = Int}
IorS = Int or Str
@@ -140,7 +142,7 @@ Vector = Array Int
これは、違う目的の型は別々の型として新しく定義するべき、ということです。
また、すでにエイリアスのある型に重ねてエイリアスを付けることを防ぐ目的もあります。
-```erg
+```python
Id = Int
UserId = Int # TypeWarning: duplicate aliases: Id and UserId
diff --git a/doc/JA/syntax/type/03_trait.md b/doc/JA/syntax/type/03_trait.md
index 5b234c07..ca426ac3 100644
--- a/doc/JA/syntax/type/03_trait.md
+++ b/doc/JA/syntax/type/03_trait.md
@@ -1,9 +1,11 @@
# トレイト
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/03_trait.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
トレイトは、レコード型に型属性の要求を追加した記名型です。
Pythonでいう抽象基底クラス(Abstract Base Class, ABC)に類似しますが、代数的演算を行えるという特徴があります。
-```erg
+```python
Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int}
```
@@ -12,7 +14,7 @@ Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int}
トレイトは宣言ができるのみで実装を持てないことに注意してください(実装は後に述べるパッチという機能で実現します)。
トレイトは部分型指定でクラスに実装されているかチェックできます。
-```erg
+```python
Point2D <: Norm
Point2D = Class {.x = Int; .y = Int}
Point2D.norm self = self.x**2 + self.y**2
@@ -20,14 +22,14 @@ Point2D.norm self = self.x**2 + self.y**2
要求属性を実装していないとエラーになります。
-```erg
+```python
Point2D <: Norm # TypeError: Point2D is not a subtype of Norm
Point2D = Class {.x = Int; .y = Int}
```
トレイトは構造型と同じく合成、置換、排除などの演算を適用できます(e.g. `T and U`)。このようにしてできたトレイトをインスタントトレイトと呼びます。
-```erg
+```python
T = Trait {.x = Int}
U = Trait {.y = Int}
V = Trait {.x = Int; y: Int}
@@ -40,7 +42,7 @@ assert Structural(W) == Structural(T.replace {.x = Ratio})
トレイトは型でもあるので、通常の型指定にも使えます。
-```erg
+```python
points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)]
assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25]
```
@@ -51,7 +53,7 @@ assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25]
下の例でいうと、`BinAddSub`は`BinAdd`と`BinSub`を包摂しています。
これはクラスにおける継承(Inheritance)に対応しますが、継承と違い複数の基底型を`and`で合成して指定できます。`not`によって一部を除外したトレイトでもOKです。
-```erg
+```python
Add R = Trait {
.AddO = Type
.`_+_` = Self.(R) -> Self.AddO
@@ -69,7 +71,7 @@ ClosedAddSub = Subsume ClosedAdd and ClosedSub
トレイトは構造化できます。
-```erg
+```python
SAdd = Structural Trait {
.`_+_` = Self.(Self) -> Self
}
@@ -87,7 +89,7 @@ assert add(C.new(1), C.new(2)) == C.new(3)
記名的トレイトは単に要求メソッドを実装しただけでは使えず、実装したことを明示的に宣言する必要があります。
以下の例では明示的な実装の宣言がないため、`add`が`C`型の引数で使えません。`C = Class {i = Int}, Impl := Add`としなくてはならないのです。
-```erg
+```python
Add = Trait {
.`_+_` = Self.(Self) -> Self
}
@@ -109,7 +111,7 @@ add C.new(1), C.new(2) # TypeError: C is not subclass of Add
トレイトは引数を取ることができます。これは依存型と同じです。
-```erg
+```python
Mapper T: Type = Trait {
.MapIter = {Iterator}
.map = Self(T).(T -> U) -> Self.MapIter U
@@ -127,7 +129,7 @@ assert [1, 2, 3].iter().map(x -> "{x}").collect(Array) == ["1", "2", "3"]
派生トレイトでは基底トレイトの型定義をオーバーライドできます。
この場合、オーバーライドするメソッドの型は、基底メソッドの型の部分型でなければなりません。
-```erg
+```python
# `Self.(R) -> O`は`Self.(R) -> O or Panic`の部分型
Div R, O: Type = Trait {
.`/` = Self.(R) -> O or Panic
@@ -142,7 +144,7 @@ SafeDiv R, O = Subsume Div, {
実際の`Add`, `Sub`, `Mul`の定義はこのようになっています。
-```erg
+```python
Add R = Trait {
.Output = Type
.`_+_` = Self.(R) -> .Output
@@ -159,7 +161,7 @@ Mul R = Trait {
`.Output`という変数の名前が重複しています。これら複数のトレイトを同時に実装したい場合、以下のように指定します。
-```erg
+```python
P = Class {.x = Int; .y = Int}
# P|Self <: Add(P)|はP|<: Add(P)|に省略可能
P|Self <: Add(P)|.
@@ -172,7 +174,7 @@ P|Self <: Mul(Int)|.
このようにして実装した重複のあるAPIは、使用時は殆どの場合型推論されますが、`||`で明示的に型指定することで解決もできます。
-```erg
+```python
print! P.Output # TypeError: ambiguous type resolution
print! P|<: Mul(Int)|.Output #
```
diff --git a/doc/JA/syntax/type/04_class.md b/doc/JA/syntax/type/04_class.md
index b0f2ea05..9b9e0434 100644
--- a/doc/JA/syntax/type/04_class.md
+++ b/doc/JA/syntax/type/04_class.md
@@ -1,9 +1,11 @@
# Class
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/04_class.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
Ergにおけるクラスは、大まかには自身の要素(インスタンス)を生成できる型と言えます。
以下は単純なクラスの例です。
-```erg
+```python
Person = Class {.name = Str; .age = Nat}
# .newが定義されなかった場合、自動で`Person.new = Person::__new__`となります
Person.
@@ -22,7 +24,7 @@ print! classof(john) # Person
以下のように改行せず定義すると文法エラーになるので注意してください。
-```erg
+```python
Person.new name, age = ... # SyntaxError: cannot define attributes directly on an object
```
@@ -39,7 +41,7 @@ class Person:
age: int
```
-```erg
+```python
# Ergでこの書き方はクラス属性の宣言を意味する(インスタンス属性ではない)
Person = Class()
Person.
@@ -47,7 +49,7 @@ Person.
age: Int
```
-```erg
+```python
# 上のPythonコードに対応するErgコード
Person = Class {
.name = Str
@@ -61,7 +63,7 @@ Person = Class {
下の例で説明する。`species`という属性は全てのインスタンスで共通なので、クラス属性とした方が自然である。だが`name`という属性は各インスタンスが個々に持っておくべきなのでインスタンス属性とすべきなのである。
-```erg
+```python
Person = Class {name = Str}
Person::
species = "human"
@@ -85,7 +87,7 @@ alice.greet() # Hello, My name is Alice.
因みに、インスタンス属性と型属性で同名、同型のものが存在する場合、コンパイルエラーとなる。これは混乱を避けるためである。
-```erg
+```python
C = Class {.i = Int}
C.
i = 1 # AttributeError: `.i` is already defined in instance fields
@@ -104,7 +106,7 @@ Ergではクラスメソッドを追加したりはできませんが、[パッ
既存のクラスを継承することも出来ます([Inheritable](./../27_decorator.md/#inheritable)クラスの場合)。
`Inherit`は継承を意味します。左辺の型を派生クラス、右辺の`Inherit`の引数型を基底クラスと言います。
-```erg
+```python
MyStr = Inherit Str
# other: StrとしておけばMyStrでもOK
MyStr.
@@ -119,7 +121,7 @@ Pythonと違い、定義されたErgのクラスはデフォルトで`final`(継
継承可能にするためには`Inheritable`デコレータをクラスに付ける必要があります。
`Str`は継承可能クラスのひとつです。
-```erg
+```python
MyStr = Inherit Str # OK
MyStr2 = Inherit MyStr # NG
@@ -133,7 +135,7 @@ MyStr3 = Inherit InheritableMyStr # OK
クラスは型とは同値判定の仕組みが異なります。
型は構造に基づいて同値性が判定されます。
-```erg
+```python
Person = {.name = Str; .age = Nat}
Human = {.name = Str; .age = Nat}
@@ -142,7 +144,7 @@ assert Person == Human
クラスは同値関係が定義されていません。
-```erg
+```python
Person = Class {.name = Str; .age = Nat}
Human = Class {.name = Str; .age = Nat}
@@ -153,7 +155,7 @@ Person == Human # TypeError: cannot compare classes
クラスは自身の要素を生成することができる型といいましたが、それだけは厳密な説明ではありません。実際はレコード型+パッチでも同じことができるからです。
-```erg
+```python
Person = {.name = Str; .age = Nat}
PersonImpl = Patch Person
PersonImpl.
@@ -176,7 +178,7 @@ john = Person.new("John Smith", 25)
ErgではクラスでNSTを実現します。NSTの利点として、堅牢性などが挙げられます。
大規模なプログラムを書いていると、オブジェクトの構造が偶然一致することはままあります。
-```erg
+```python
Dog = {.name = Str; .age = Nat}
DogImpl = Patch Dog
DogImpl.
@@ -194,7 +196,7 @@ john.bark() # "Yelp!"
`Dog`と`Person`の構造は全く同一ですが、動物が挨拶したり人間が吠えたりできるようにするのは明らかにナンセンスです。
後者はともかく、前者は不可能なので適用できないようにする方が安全です。このような場合はクラスを使用すると良いでしょう。
-```erg
+```python
Dog = Class {.name = Str; .age = Nat}
Dog.
bark = log "Yelp!"
@@ -211,7 +213,7 @@ john.bark() # TypeError: `Person` object has no method `.bark`
つまり、`T.x`, `T.bar`は`{i = Int}`と互換性のある型がアクセスできる(コンパイル時に結びつける)オブジェクトであり、`{i = Int}`や`C`に定義されているわけではありません。
対してクラス属性はクラス自身が保持しています。なので、構造が同じであっても継承関係にないクラスからはアクセスできません。
-```erg
+```python
C = Class {i = Int}
C.
foo self = ...
@@ -233,11 +235,11 @@ print! C.new({i = 1}).bar #
## データクラスとの違い
-クラスには、レコードクラスに`Class`を通した通常のクラスと、レコードクラスを継承(`Inherit`)したデータクラスがあります。
+クラスには、レコードを要求型とする`Class`を通した通常のクラスと、レコードを継承(`Inherit`)したデータクラスがあります。
データクラスはレコードの機能を受け継いでおり、分解代入ができる、`==`や`hash`がデフォルトで実装されているなどの特徴があります。
逆に独自の同値関係やフォーマット表示を定義したい場合は通常のクラスを使用するとよいでしょう。
-```erg
+```python
C = Class {i = Int}
c = C.new {i = 1}
d = C.new {i = 2}
@@ -245,9 +247,9 @@ print! c #
c == d # TypeError: `==` is not implemented for `C`
D = Inherit {i = Int}
-e = D.new {i = 1}
-f = D.new {i = 2}
-print! e # D{i = 1}
+e = D::{i = 1} # e = D.new {i = 1}と同じ
+f = D::{i = 2}
+print! e # D(i = 1)
assert e != f
```
@@ -255,7 +257,7 @@ assert e != f
Or型のクラスを定義しやすくするために、`Enum`が用意されています。
-```erg
+```python
X = Class()
Y = Class()
XorY = Enum X, Y
@@ -264,7 +266,7 @@ XorY = Enum X, Y
それぞれの型には`XorY.X`, `XorY.Y`のようにしてアクセスでき、コンストラクタは`XorY.cons(X)`のようにして取得できます。
`.cons`はクラスを受け取ってそのコンストラクタを返すメソッドです。
-```erg
+```python
x1 = XorY.new X.new()
x2 = XorY.cons(X)()
assert x1 == x2
@@ -274,7 +276,7 @@ assert x1 == x2
クラスは、要件型のサブタイプです。要件型のメソッド(パッチメソッド含む)を使用できます。
-```erg
+```python
T = Trait {.foo = Foo}
C = Class(..., Impl: T)
C.
@@ -288,4 +290,4 @@ assert T.foo == Foo
Previous | Next
-
+
\ No newline at end of file
diff --git a/doc/JA/syntax/type/05_inheritance.md b/doc/JA/syntax/type/05_inheritance.md
index 82c2c6b8..598513e9 100644
--- a/doc/JA/syntax/type/05_inheritance.md
+++ b/doc/JA/syntax/type/05_inheritance.md
@@ -1,9 +1,11 @@
# 継承(Inheritance)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/05_inheritance.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
継承を使うと、既存のクラスに機能を加えたり特化したりした新しいクラスを定義できます。
継承はトレイトにおける包摂に似ています。継承してできたクラスは、もとのクラスのサブタイプになります。
-```erg
+```python
NewInt = Inherit Int
NewInt.
plus1 self = self + 1
@@ -16,7 +18,7 @@ assert NewInt.new(1) + NewInt.new(1) == 2
オプション引数`additional`を指定すると追加のインスタンス属性を持つことができます。ただし値クラスの場合はインスタンス属性を追加できません。
-```erg
+```python
@Inheritable
Person = Class {name = Str}
Student = Inherit Person, additional: {id = Int}
@@ -34,7 +36,7 @@ Ergでは例外的に`Never`型の継承はできない設計となっている
[Or型](./13_algebraic.md)をクラス化した列挙クラスも継承ができます。この際、オプション引数`Excluding`を指定することで選択肢のどれか(`or`で複数選択可)を外せます。
なお追加はできません。選択肢を追加したクラスは、元のクラスのサブタイプとはならないからです。
-```erg
+```python
Number = Class Int or Float or Complex
Number.
abs(self): Float =
@@ -49,7 +51,7 @@ RealNumber = Inherit Number, Excluding: Complex
同様に、[篩型](./12_refinement.md)も指定できます。
-```erg
+```python
Months = Class 0..12
MonthsNot31Days = Inherit Months, Excluding: {1, 3, 5, 7, 8, 10, 12}
@@ -74,7 +76,7 @@ StrMoreThan4 = Inherit StrMoreThan3, Excluding: StrWithLen N | N == 3
最後に、3つ目の条件について考えます。この条件はErg特有で、他のオブジェクト指向言語ではあまり見られないものですが、これも安全のためです。これがなかったとき、どんなまずいことが起こりうるか見てみましょう。
-```erg
+```python
# Bad example
@Inheritable
Base! = Class {x = Int!}
@@ -95,7 +97,7 @@ Inherited!.
なので、オーバーライドの影響を受ける可能性のあるメソッドは一般に全て書き直す必要があるわけです。Ergはこのルールを仕様に組み込んでいます。
-```erg
+```python
# OK
@Inheritable
Base! = Class {x = Int!}
@@ -124,7 +126,7 @@ Inherited!.
例えば`Real`(`Add()`を実装する)のサブタイプである`Int`では`Add()`を再実装しているようにみえます。
-```erg
+```python
Int = Class ..., Impl := Add() and ...
```
@@ -135,13 +137,13 @@ Int = Class ..., Impl := Add() and ...
Ergでは通常のクラス同士でIntersection(交差), Diff(除外), Complement(否定)が行えません。
-```erg
+```python
Int and Str # TypeError: cannot unite classes
```
このルールにより、複数のクラスを継承すること、すなわち多重継承が行えません。
-```erg
+```python
IntAndStr = Inherit Int and Str # SyntaxError: multiple inheritance of classes is not allowed
```
@@ -161,7 +163,7 @@ Ergでは継承元の属性を書き換えることができません。これ
オーバーライドはより特化したメソッドで上書きする操作であるため書き換えとは異なります。オーバーライドの際も互換性のある型で置き換えなくてはなりません。
-```erg
+```python
@Inheritable
Base! = Class {.pub = !Int; pri = !Int}
Base!.
@@ -180,7 +182,7 @@ Inherited!.
2つ目は、継承元の(可変)インスタンス属性に対する更新操作です。これも禁止されています。基底クラスのインスタンス属性は、基底クラスの用意したメソッドからのみ更新できます。
属性の可視性にかかわらず、直接更新はできません。ただし読み取りはできます。
-```erg
+```python
@Inheritable
Base! = Class {.pub = !Int; pri = !Int}
Base!.
@@ -209,7 +211,7 @@ Ergが多重継承、多層継承を禁止したのはこの危険性を低減
Ergはサブタイプ判定の一部を型システムが自動で判定してくれます(e.g. 0以上のIntであるところのNat)。
しかし例えば、「有効なメールアドレスを表す文字列型」をErgの型システムのみに頼って作成することは困難です。通常の文字列にバリデーションを行うべきでしょう。そして、バリデーションが通った文字列オブジェクトには何らかの「保証書」を付加したいところです。それが継承クラスへのダウンキャストに相当するわけです。`Strオブジェクト`を`ValidMailAddressStr`にダウンキャストすることは、文字列が正しいメールアドレスの形式であるか検証することと一対一対応します。
-```erg
+```python
ValidMailAddressStr = Inherit Str
ValidMailAddressStr.
init s: Str =
@@ -229,7 +231,7 @@ valid: ValidMailAddressStr # assurance that it is in the correct email address f
こうすれば、引数として受け付けるのは`Person`オブジェクトとそれを継承したクラス、`Student`オブジェクトのみです。
この方が保守的で、不必要に多くの責任を負う必要がなくなります。
-```erg
+```python
Named = {name = Str; ...}
Dog = Class {name = Str; breed = Str}
Person = Class {name = Str}
diff --git a/doc/JA/syntax/type/06_nst_vs_sst.md b/doc/JA/syntax/type/06_nst_vs_sst.md
index 4884f630..c2798a43 100644
--- a/doc/JA/syntax/type/06_nst_vs_sst.md
+++ b/doc/JA/syntax/type/06_nst_vs_sst.md
@@ -1,6 +1,8 @@
# 記名的部分型 vs. 構造的部分型
-```erg
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/06_nst_vs_sst.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+```python
Months = 0..12
# NST
diff --git a/doc/JA/syntax/type/07_patch.md b/doc/JA/syntax/type/07_patch.md
index f79c7f53..6173b9ed 100644
--- a/doc/JA/syntax/type/07_patch.md
+++ b/doc/JA/syntax/type/07_patch.md
@@ -1,10 +1,12 @@
# Patch
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/07_patch.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
Ergでは、既存の型・クラスに手を加えることはできません。
クラスにメソッドを追加で定義することはできず、特殊化(specialization, 多相に宣言された型を単相化し専用のメソッドを定義する機能。C++などが持つ)も行えません。
しかし、既存の型・クラスに機能を追加したいという状況は多々あり、これを実現するためにパッチという機能があります。
-```erg
+```python
StrReverse = Patch Str
StrReverse.
reverse self = self.iter().rev().collect(Str)
@@ -18,7 +20,7 @@ assert "abc".reverse() == "cba"
ただし、パッチのメソッドは記名型(クラス)のメソッドより優先度が低く、既存のクラスのメソッドをオーバーライド(上書き)できません。
-```erg
+```python
StrangeInt = Patch Int
StrangeInt.
`_+_` = Int.`_-_` # AssignError: .`_+_` is already defined in Int
@@ -28,7 +30,7 @@ StrangeInt.
ただし、基本的にはオーバーライドを行わず、別の名前のメソッドを定義することを推奨します。
オーバーライドは安全のためいくつかの制約が課されており、それほど気軽に行えるものではないからです。
-```erg
+```python
StrangeInt = Inherit Int
StrangeInt.
# オーバーライドするメソッドにはOverrideデコレータを付与する必要がある
@@ -41,7 +43,7 @@ StrangeInt.
パッチは一つの型に対して複数定義し、まとめることもできます。
-```erg
+```python
# foo.er
StrReverse = Patch(Str)
@@ -60,7 +62,7 @@ StrToKebabCase.
StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase
```
-```erg
+```python
{StrBoosterPack; ...} = import "foo"
assert "abc".reverse() == "cba"
@@ -71,7 +73,7 @@ assert "to kebab case".to_kebab_case() == "to-kebab-case"
複数のパッチが定義できると、中には実装の重複が発生する可能性があります。
-```erg
+```python
# foo.er
StrReverse = Patch(Str)
@@ -87,13 +89,13 @@ StrReverseMk2.
そのような場合は、メソッド形式ではなく関連関数形式とすることで一意化できます。
-```erg
+```python
assert StrReverseMk2.reverse("hello") == "olleh"
```
また、選択的にインポートすることでも一意化できます。
-```erg
+```python
{StrReverseMk2; ...} = import "foo"
assert StrReverseMk2.reverse("hello") == "olleh"
@@ -105,7 +107,7 @@ assert StrReverseMk2.reverse("hello") == "olleh"
このようなパッチは接着パッチ(Glue Patch)と呼ばれます。
`Str`は組み込みの型であるため、ユーザーがトレイトを後付けするためには接着パッチが必要なわけです。
-```erg
+```python
Reverse = Trait {
.reverse = Self.() -> Self
}
@@ -120,7 +122,7 @@ StrReverse.
これは、仮に複数の接着パッチが同時に「見える」場合、どの実装を選択するか一意に決められなくなるからです。
ただし、別のスコープ(モジュール)に移る際にパッチを入れ替えることはできます。
-```erg
+```python
NumericStr = Inherit Str
NumericStr.
...
@@ -151,7 +153,7 @@ impl Reverse for String {
RustのトレイトはErgのトレイトとパッチの機能を併せ持つ機能だと言えるでしょう。こう言うとRustのトレイトの方が便利に聞こえますが、実はそうとも限りません。
-```erg
+```python
# Erg
Reverse = Trait {
.reverse = Self.() -> Self
@@ -166,7 +168,7 @@ StrReverse.
Ergではimplブロックがパッチとしてオブジェクト化されているため、他のモジュールから取り込む際に選択的な取り込みが可能になります。さらに副次的な効果として、外部構造体への外部トレイトの実装も可能となっています。
また、dyn traitやimpl traitといった文法も構造型によって必要なくなります。
-```erg
+```python
# Erg
reversible: [Reverse; 2] = [[1, 2, 3], "hello"]
@@ -188,7 +190,7 @@ fn iter(i: I) -> impl Iterator- where I: IntoIterator {
この場合、自由度を与えたい項を引数にします(下の場合は`T: Type`)。このようにして定義したパッチを全称パッチといいます。
見れば分かる通り、全称パッチは正確にはパッチを返す関数ですが、それ自体もパッチとみなすことが可能です。
-```erg
+```python
FnType T: Type = Patch(T -> T)
FnType(T).
type = T
@@ -203,7 +205,7 @@ assert (Int -> Int).type == Int
以下のように拡張によって成り立たなくなる性質もあるので、構造的パッチを定義する際は慎重に設計してください。
-```erg
+```python
# これはStructuralにするべきではない
Norm = Structural Patch {x = Int; y = Int}
Norm.
diff --git a/doc/JA/syntax/type/08_value.md b/doc/JA/syntax/type/08_value.md
index 2e2fb77c..2563900b 100644
--- a/doc/JA/syntax/type/08_value.md
+++ b/doc/JA/syntax/type/08_value.md
@@ -1,8 +1,10 @@
# 値型(Value types)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/08_value.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
値型はErg組み込み型のうちコンパイル時評価が可能な型で、具体的には以下のものです。
-```erg
+```python
Value = (
Int
or Nat
@@ -23,7 +25,7 @@ Value = (
値型のオブジェクト・定数、およびそれにコンパイル時サブルーチンを適用したものを定数式と呼びます。
-```erg
+```python
1, 1.0, 1+2im, True, None, "aaa", [1, 2, 3], Fib(12)
```
diff --git a/doc/JA/syntax/type/09_attributive.md b/doc/JA/syntax/type/09_attributive.md
index 96dce87e..b57a8f09 100644
--- a/doc/JA/syntax/type/09_attributive.md
+++ b/doc/JA/syntax/type/09_attributive.md
@@ -1,5 +1,7 @@
# 属性型(Attributive Type)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/09_attributive.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
属性型は、レコードおよびデータクラス、パッチ、モジュールなどが含まれる型です。
属性型に属する型は値型ではありません。
diff --git a/doc/JA/syntax/type/10_interval.md b/doc/JA/syntax/type/10_interval.md
index 38d308ba..9ff3a712 100644
--- a/doc/JA/syntax/type/10_interval.md
+++ b/doc/JA/syntax/type/10_interval.md
@@ -1,8 +1,10 @@
# Interval Type
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/10_interval.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
`Range`オブジェクトの最も基本的な使い方は、イテレータとしての使用です。
-```erg
+```python
for! 0..9, i =>
print! i
```
@@ -11,7 +13,7 @@ Pythonと違い、末尾の数字は含まれることに注意してくださ
しかし、`Range`オブジェクトの使い道はこれだけではありません。型としても使うことが出来ます。このような型を区間型(Interval type)と呼びます。
-```erg
+```python
i: 0..10 = 2
```
@@ -21,7 +23,7 @@ i: 0..10 = 2
イテレータとしても使えるため、`10..0`などのように逆順で指定することも出来ますが、
`<..`, `..<`, `<..<`の向きは逆転できません。
-```erg
+```python
a = 0..10 # OK
b = 0..<10 # OK
c = 10..0 # OK
@@ -32,6 +34,6 @@ f = 10<..<0 # Syntax error
範囲演算子(range operator)は、`Ord`な不変型であるならば数値以外の型にも使用できます。
-```erg
+```python
Alphabet = "A".."z"
```
diff --git a/doc/JA/syntax/type/11_enum.md b/doc/JA/syntax/type/11_enum.md
index bb040c5d..51dd9524 100644
--- a/doc/JA/syntax/type/11_enum.md
+++ b/doc/JA/syntax/type/11_enum.md
@@ -1,17 +1,19 @@
# Enumerative Type(列挙型)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/11_enum.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
列挙型(Enum type)はSetによって生成されます。
列挙型はそのままでも型指定で使えますが、クラス化したりパッチを定義することで更にメソッドを定義できます。
列挙型による部分型システムを列挙的部分型付けといいます。
-```erg
+```python
Bool = {True, False}
Status = {"ok", "error"}
```
`1..7`は`{1, 2, 3, 4, 5, 6, 7}`と書き換えられるので、要素が有限の場合は本質的に列挙型と区間型は等価です。
-```erg
+```python
Binary! = Class {0, 1}!.
invert! ref! self =
if! self == 0:
@@ -31,7 +33,7 @@ b.invert!()
enum Status { Ok, Error }
```
-```erg
+```python
# Erg
Status = {"Ok", "Error"}
```
@@ -52,7 +54,7 @@ impl ExtraStatus {
}
```
-```erg
+```python
# Status > ExtraStatusであり、Statusの要素はExtraStatusのメソッドを使える
Status = Trait {"Ok", "Error"}
# ...
@@ -64,7 +66,7 @@ patchingによってメソッドの追加もできます。
明示的に包含関係を示したい場合、または既存のEnum型に選択肢を追加したい場合は`or`演算子を使います。
-```erg
+```python
ExtraStatus = Status or {"Unknown"}
```
@@ -72,7 +74,7 @@ ExtraStatus = Status or {"Unknown"}
デフォルトでは、等質な列挙型を要件型とするクラスは、要素が属しているクラスのサブクラスとして扱えます。
あえてそうしたくない場合は、ラッパークラスとするとよいでしょう。
-```erg
+```python
Abc = Class {"A", "B", "C"}
Abc.new("A").is_uppercase()
diff --git a/doc/JA/syntax/type/12_refinement.md b/doc/JA/syntax/type/12_refinement.md
index f87decec..337cec6c 100644
--- a/doc/JA/syntax/type/12_refinement.md
+++ b/doc/JA/syntax/type/12_refinement.md
@@ -1,11 +1,13 @@
# 篩型(Refinement Type)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/12_refinement.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
Refinement type(篩型、ふるいがた)は、述語式によって制約付けられた型です。列挙型や区間型は篩型の一種です。
篩型の標準形は`{Elem: Type | (Pred)*}`です。これは、`Pred`を満たす`Elem`を要素とする型である、という意味です。
篩型に使えるのは[Const型](./advanced/const.md)のみです。
-```erg
+```python
Nat = 0.._
Odd = {N: Int | N % 2 == 1}
Char = StrWithLen 1
@@ -22,7 +24,7 @@ Array3OrMore == {A: Array _, N | N >= 3}
`Pred`は(左辺)述語式と呼ばれます。これは代入式と同じく意味のある値を返すものではなく、左辺にはパターンしか置けません。
すなわち、`X**2 - 5X + 6 == 0`のような式は篩型の述語式としては使えません。この点において、右辺式の述語式とは異なります。
-```erg
+```python
{X: Int | X**2 - 5X + 6 == 0} # SyntaxError: the predicate form is invalid. Only names can be on the left-hand side
```
@@ -34,14 +36,14 @@ Array3OrMore == {A: Array _, N | N >= 3}
`Odd`を定義したのはいいですが、このままではリテラル以外ではあまり使えないようにみえます。通常の`Int`オブジェクトの中の奇数を`Odd`に昇格させる、つまり`Int`を`Odd`にダウンキャストするためには、`Odd`のコンストラクタを通す必要があります。
篩型の場合、通常のコンストラクタ`.new`はパニックする可能性があり、`.try_new`という`Result`型を返す補助的なコンストラクタもあります。
-```erg
+```python
i = Odd.new (0..10).sample!()
i: Odd # or Panic
```
また、`match`中で型指定として使用することもできます。
-```erg
+```python
# i: 0..10
i = (0..10).sample!()
match i:
@@ -58,7 +60,7 @@ match i:
今まで紹介した列挙型と区間型は、篩型の糖衣構文です。
`{a, b, ...}`は`{I: Typeof(a) | I == a or I == b or ... }`に、`a..b`は`{I: Typeof(a) | I >= a and I <= b}`に脱糖されます。
-```erg
+```python
{1, 2} == {I: Int | I == 1 or I == 2}
1..10 == {I: Int | I >= 1 and I <= 10}
1..<10 == {I: Int | I >= 1 and I < 10} == {I: Int | I >= 1 and I <= 9}
@@ -68,7 +70,7 @@ match i:
`_: {X}`を`X`と書き換えられるように(定数パターン)、`_: {X: T | Pred}`は`X: T | Pred`と書き換えることができます。
-```erg
+```python
# メソッド.mは長さ3以上の配列に定義される
Array(T, N | N >= 3)
.m(&self) = ...
diff --git a/doc/JA/syntax/type/13_algebraic.md b/doc/JA/syntax/type/13_algebraic.md
index 99246287..14c353f6 100644
--- a/doc/JA/syntax/type/13_algebraic.md
+++ b/doc/JA/syntax/type/13_algebraic.md
@@ -1,5 +1,7 @@
# Algebraic type (代数演算型)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/13_algebraic.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e)
+
代数演算型は、型を代数のようにみなして演算することで生成される型のことです。
代数演算型が扱う演算は、Union, Intersection, Diff, Complementなどがあります。
通常のクラスはUnionのみが行えて、他の演算は型エラーになります。
@@ -9,7 +11,7 @@
Union型では型について複数の可能性を与える事ができる。名前の通り、`or`演算子で生成されます。
代表的なUnionは`Option`型です。`Option`型は`T or NoneType`のpatch typeで、主に失敗するかもしれない値を表現します。
-```erg
+```python
IntOrStr = Int or Str
assert dict.get("some key") in (Int or NoneType)
@@ -21,7 +23,7 @@ Option T = T or NoneType
Intersection型は型同士を`and`演算で結合して得られます。
-```erg
+```python
Num = Add and Sub and Mul and Eq
```
@@ -32,7 +34,7 @@ Num = Add and Sub and Mul and Eq
Diff型は`not`演算で得られます。
英文に近い表記としては`and not`とした方が良いですが、`and`, `or`と並べて収まりが良いので`not`だけで使うのが推奨されます。
-```erg
+```python
CompleteNum = Add and Sub and Mul and Div and Eq and Ord
Num = CompleteNum not Div not Ord
@@ -46,7 +48,7 @@ Complementは`not`演算で得られますが、これは単項演算です。`n
`not T`型によるIntersectionはDiffと同等で、`not T`型によるDiffはIntersectionと同等です。
しかしこのような書き方は推奨されません。
-```erg
+```python
# the simplest definition of the non-zero number type
NonZero = Not {0}
# deprecated styles
@@ -60,7 +62,7 @@ Bool == {True} not not {False} # 2 == 1 - -1
そうではない「見かけの代数型」には、Enum型やInterval型、レコード型の`or`や`and`があります。
これらは簡約が可能なので真の代数演算型ではなく、型指定に使うとWarningが出ます。Warningを消すためには簡約化するか型定義を行うかする必要があります。
-```erg
+```python
assert {1, 2, 3} or {2, 3} == {1, 2, 3}
assert {1, 2, 3} and {2, 3} == {2, 3}
assert -2..-1 or 1..2 == {-2, -1, 1, 2}
@@ -76,7 +78,7 @@ q: Point2D = {x = 1; y = 2; z = 3}
真の代数演算型には、`Or`型、`And`型があります。クラス同士の`or`などは`Or`型です。
-```erg
+```python
assert Int or Str == Or(Int, Str)
assert Int and Marker == And(Int, Marker)
```
diff --git a/doc/JA/syntax/type/14_dependent.md b/doc/JA/syntax/type/14_dependent.md
index 754ae782..dbe95180 100644
--- a/doc/JA/syntax/type/14_dependent.md
+++ b/doc/JA/syntax/type/14_dependent.md
@@ -1,12 +1,14 @@
# 依存型
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/14_dependent.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
依存型はErgの最大の特徴とも言っても良い機能です。
依存型とは、値を引数に取る型です。通常の多相型は型のみを引数に取れますが、その制限を緩めたのが依存型といえます。
依存型は、`[T; N]`(`Array(T, N)`)などがそれに相当します。
この型は、中身の型`T`だけでなく、中身の個数`N`にも依存して決まる型です。`N`には`Nat`型のオブジェクトが入ります。
-```erg
+```python
a1 = [1, 2, 3]
assert a1 in [Nat; 3]
a2 = [4, 5, 6, 7]
@@ -16,7 +18,7 @@ assert a1 + a2 in [Nat; 7]
関数引数で渡した型オブジェクトが戻り値型に関連する場合は、以下のように記述します。
-```erg
+```python
narray: |N: Nat| {N} -> [{N}; N]
narray(N: Nat): [N; N] = [N; N]
assert narray(3) == [3, 3, 3]
@@ -26,7 +28,7 @@ assert narray(3) == [3, 3, 3]
依存型そのものは既存の言語にも存在するものですが、Ergでは依存型にプロシージャルメソッドを定義できるという特徴があります。
-```erg
+```python
x = 1
f x =
print! f::x, module::x
@@ -42,7 +44,7 @@ T(1).x() # 1
可変依存型の型引数はメソッドの適用によって遷移させることができます。
遷移指定は`~>`で行います。
-```erg
+```python
# `Id`は不変型なので遷移させることはできないことに注意
VM!(State: {"stopped", "running"}! := _, Id: Nat := _) = Class(..., Impl := Phantom! State)
VM!().
@@ -66,7 +68,7 @@ vm.stop!() # TypeError: VM!(!"stopped", 1) doesn't have .stop!()
既存の型を組み込んだり継承して依存型を作ることもできます。
-```erg
+```python
MyArray(T, N) = Inherit [T; N]
# .arrayと連動してself: Self(T, N)の型が変わる
diff --git a/doc/JA/syntax/type/15_quantified.md b/doc/JA/syntax/type/15_quantified.md
index 86bb9c6f..7fa2bd07 100644
--- a/doc/JA/syntax/type/15_quantified.md
+++ b/doc/JA/syntax/type/15_quantified.md
@@ -1,16 +1,18 @@
# 型変数(Type Variable)、量化型
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/15_quantified.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
型変数はサブルーチン引数の型指定などに使用する変数で、その型が任意である(単相化しない)ことを示します。
まず、型変数を導入するモチベーションとして、入力をそのまま返す`id`関数について考えましょう。
-```erg
+```python
id x: Int = x
```
入力をそのまま返す`id`関数が`Int`型に対して定義されていますが、この関数は明らかに任意の型に対して定義できます。
最大のクラスを表す`Object`を使用してみましょう。
-```erg
+```python
id x: Object = x
i = id 1
@@ -21,7 +23,7 @@ b = id True
確かに任意の型を受け付けるようになりましたが、1つ問題があります。戻り値の型が`Object`に拡大されてしまうのです。
入力が`Int`型なら`Int`型、`Str`型なら`Str`型が返るようになっていてほしいですね。
-```erg
+```python
print! id 1 #
id(1) + 1 # TypeError: cannot add `Object` and `Int`
```
@@ -29,7 +31,7 @@ id(1) + 1 # TypeError: cannot add `Object` and `Int`
入力の型と戻り値の型が同じであるようにするには、 __型変数__ を使います。
型変数は`||`(型変数リスト)中で宣言します。
-```erg
+```python
id|T: Type| x: T = x
assert id(1) == 1
assert id("foo") == "foo"
@@ -39,7 +41,7 @@ assert id(True) == True
これを関数の __全称量化(全称化)__ と呼びます。細かい違いはありますが、他言語でジェネリクスと呼ばれる機能に相当します。そして全称量化された関数を __多相関数__ と呼びます。
多相関数の定義は、全ての型に対して同じ形の関数を定義するようなものです(Ergはオーバーロードを禁止しているので、下のコードは実際には書けません)。
-```erg
+```python
id|T: Type| x: T = x
# pseudo code
# ==
@@ -57,7 +59,7 @@ id x: NoneType = x
また、任意の型では大きすぎる場合、制約を与えることも出来ます。
制約を与えることにはメリットもあり、例えばサブタイプ指定をすると、特定のメソッドを使えるようになります。
-```erg
+```python
# T <: Add
# => TはAddのサブクラス
# => 加算ができる
@@ -69,7 +71,7 @@ add|T <: Add| l: T, r: T = l + r
このような型付けもできます。
-```erg
+```python
f|
Y, Z: Type
X <: Add Y, O1
@@ -81,7 +83,7 @@ f|
注釈リストが長くなる場合は、事前宣言するとよいでしょう。
-```erg
+```python
f: |Y, Z: Type, X <: Add(Y, O1), O1 <: Add(Z, O2), O2 <: Add(X, O3)| (X, Y, Z) -> O3
f|X, Y, Z| x: X, y: Y, z: Z =
x + y + z + x
@@ -91,7 +93,7 @@ f|X, Y, Z| x: X, y: Y, z: Z =
これは、型変数はすべて実引数から推論可能であるというErgの言語設計からの要求です。
なので、戻り値の型など推論ができない情報は、実引数から渡します。Ergは型を実引数から渡すことができるのです。
-```erg
+```python
Iterator T = Trait {
# 戻り値の型を引数から渡している
# .collect: |K: Type -> Type| Self(T).({K}) -> K(T)
@@ -105,7 +107,7 @@ it.collect(Array) # [2, 3, 4]
型変数が宣言できるのは`||`の間のみである。ただし、宣言した後はスコープを抜けるまで任意の場所で使用できる。
-```erg
+```python
f|X|(x: X): () =
y: X = x.clone()
log X.__name__
@@ -118,14 +120,14 @@ f 1
以下のようにして、使用時に明示的に単相化もできます。
-```erg
+```python
f: Int -> Int = id|Int|
```
その場合、実引数の型よりも指定された型の方が優先されます(合致していないと実引数の型が間違っているという型エラーになる)。
すなわち、実際に渡されたオブジェクトが指定された型に変換可能ならば変換され、そうでなければコンパイルエラーとなります。
-```erg
+```python
assert id(1) == 1
assert id|Int|(1) in Int
assert id|Ratio|(1) in Ratio
@@ -136,14 +138,14 @@ id|Int|("str") # TypeError: id|Int| is type `Int -> Int` but got Str
この文法が内包表記とバッティングする際は`()`で囲む必要があります。
-```erg
+```python
# {id|Int| x | x <- 1..10}だと{id | ...}だと解釈される
{(id|Int| x) | x <- 1..10}
```
既に存在する型と同名の型変数は宣言出来ません。これは、型変数がすべて定数であるためです。
-```erg
+```python
I: Type
# ↓ invalid type variable, already exists
f|I: Type| ... = ...
@@ -153,7 +155,7 @@ f|I: Type| ... = ...
左辺における型引数はデフォルトで束縛型変数として扱われます。
-```erg
+```python
K(T: Type, N: Nat) = ...
K(T, N).
foo(x) = ...
@@ -161,7 +163,7 @@ K(T, N).
別の型変数名を使用すると警告が出ます。
-```erg
+```python
K(T: Type, N: Nat) = ...
K(U, M). # Warning: K's type variable names are 'T' and 'N'
foo(x) = ...
@@ -169,7 +171,7 @@ K(U, M). # Warning: K's type variable names are 'T' and 'N'
定数は定義以降すべての名前空間で同一なので、当然型変数名にも使用できません。
-```erg
+```python
N = 1
K(N: Nat) = ... # NameError: N is already defined
@@ -184,7 +186,7 @@ L(M).
型引数ごとに多重定義することはできませんが、型引数を代入していない依存型(非原始カインド)と代入した依存型(原始カインド)は関係がないので同名のメソッドを定義できます。
-```erg
+```python
K(I: Int) = ...
K.
# Kは真の型(原子カインド)ではないので、メソッドを定義できない
@@ -198,7 +200,7 @@ K(0).
前章で定義した`id`関数は任意の型になれる関数です。では、「`id`関数自体の型」は何なのでしょうか?
-```erg
+```python
print! classof(id) # |T: Type| T -> T
```
@@ -208,7 +210,7 @@ print! classof(id) # |T: Type| T -> T
無名関数と同じく、多相関数型には型変数名の任意性がありますが、これらはすべて同値となります。
-```erg
+```python
assert (|T: Type| T -> T) == (|U: Type| U -> U)
```
@@ -223,14 +225,14 @@ assert (|T: Type| T -> T) == (|U: Type| U -> U)
開いた全称型は、同形な全ての「真の型」のスーパータイプになります。対して、閉じた全称型は、同形な全ての「真の型」のサブタイプになります。
-```erg
+```python
(|T: Type| T -> T) < (Int -> Int) < (T -> T)
```
閉じている方が小さい/開いている方が大きい、と覚えるとよいでしょう。
しかし、どうしてそうなるのでしょうか。理解を深めるため、それぞれのインスタンスを考えてみます。
-```erg
+```python
# id: |T: Type| T -> T
id|T|(x: T): T = x
@@ -266,7 +268,7 @@ id_int_fn(f3: Int -> Int): (Int -> Int) = f
Ergでは型自体も値であるため、引数を取る型、例えば関数型なども須らく依存型になります。つまり、多相関数型は全称型でかつ依存型でもあるといえます。
-```erg
+```python
PolyFn = Patch(|T| T -> T)
PolyFn.
type self = T # NameError: cannot find 'T'
diff --git a/doc/JA/syntax/type/16_subtyping.md b/doc/JA/syntax/type/16_subtyping.md
index d7f33f84..d8d34278 100644
--- a/doc/JA/syntax/type/16_subtyping.md
+++ b/doc/JA/syntax/type/16_subtyping.md
@@ -1,8 +1,10 @@
# 部分型付け
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/16_subtyping.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
Ergでは、クラス同士の包含関係は比較演算子`<`, `>`で判定可能です。
-```erg
+```python
Nat < Int
Int < Object
1.._ < Nat
@@ -13,7 +15,7 @@ Int < Object
`<:`演算子とは別の意味を持つことに注意してください。左辺のクラスが右辺の型のサブタイプであると宣言するもので、コンパイル時にのみ意味を持ちます。
-```erg
+```python
C <: T # T: StructuralType
f|D <: E| ...
@@ -26,7 +28,7 @@ assert F < G
構造型は構造的型付けを実現するための型であり、構造が同じならば同じオブジェクトとみなされます。
-```erg
+```python
T = Structural {i = Int}
U = Structural {i = Int}
@@ -38,7 +40,7 @@ assert t in U
対してクラスは記名的型付けを実現するための型であり、型およびインスタンスを構造的に比較することができません。
-```erg
+```python
C = Class {i = Int}
D = Class {i = Int}
@@ -54,7 +56,7 @@ assert not c in D
すなわち、構造型やトレイトを関数の型として直接指定することはできない。
部分型指定を使って「その型のサブタイプである単一のクラス」として指定する必要がある。
-```erg
+```python
# OK
f1 x, y: Int = x + y
# NG
@@ -68,7 +70,7 @@ f3 x, y: A = x + y
## クラスのアップキャスト
-```erg
+```python
i: Int
i as (Int or Str)
i as (1..10)
diff --git a/doc/JA/syntax/type/17_type_casting.md b/doc/JA/syntax/type/17_type_casting.md
index 44cd1363..6571f91f 100644
--- a/doc/JA/syntax/type/17_type_casting.md
+++ b/doc/JA/syntax/type/17_type_casting.md
@@ -1,5 +1,7 @@
# キャスト
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/17_type_casting.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
## アップキャスト
Pythonはダックタイピングを採用する言語のため、キャストという概念はありません。アップキャストはする必要がなく、ダウンキャストも基本的にはありません。
@@ -8,7 +10,7 @@ Pythonはダックタイピングを採用する言語のため、キャスト
~~Erg拡張バイトコードはBINARY_ADDに型情報を加えますが、この際の型情報はRatio-Ratioとなります。この場合はBINARY_ADD命令がIntのキャストを行うため、キャストを指定する特別な命令は挿入されません。なので、例えば子クラスでメソッドをオーバーライドしても、親を型に指定すれば型強制(type coercion)が行われ、親のメソッドで実行されます(コンパイル時に親のメソッドを参照するように名前修飾が行われます)。コンパイラが行うのは型強制の妥当性検証と名前修飾のみです。ランタイムがオブジェクトをキャストすることはありません(現在のところ。実行最適化のためにキャスト命令が実装される可能性はあります)。~~
-```erg
+```python
@Inheritable
Parent = Class()
Parent.
@@ -31,7 +33,7 @@ greet! child # "Hello from Parent"
この挙動はPythonとの非互換性を生むことはありません。そもそもPythonでは変数に型が指定されないので、いわば全ての変数が型変数で型付けされている状態となります。型変数は適合する最小の型を選ぶので、Ergで型を指定しなければPythonと同じ挙動が達成されます。
-```erg
+```python
@Inheritable
Parent = Class()
Parent.
@@ -52,7 +54,7 @@ greet! child # "Hello from Child"
継承関係にある型同士では`.from`, `.into`が自動実装されるので、それを使うこともできます。
-```erg
+```python
assert 1 == 1.0
assert Ratio.from(1) == 1.0
assert 1.into() == 1.0
@@ -62,7 +64,7 @@ assert 1.into() == 1.0
ダウンキャストは一般に安全ではなく、変換方法も自明ではないため、代わりに`TryFrom.try_from`の実装で実現します。
-```erg
+```python
IntTryFromFloat = Patch Int
IntTryFromFloat.
try_from r: Float =
diff --git a/doc/JA/syntax/type/18_mut.md b/doc/JA/syntax/type/18_mut.md
index ec232cab..50b24643 100644
--- a/doc/JA/syntax/type/18_mut.md
+++ b/doc/JA/syntax/type/18_mut.md
@@ -1,11 +1,13 @@
# 可変型(Mutable Type)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/18_mut.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
> __Warning__: この項の情報は古く、一部に間違いを含みます。
Ergではデフォルトですべての型が不変型、すなわち内部状態を更新できないようになっています。
しかし可変な型ももちろん定義できます。可変型は`!`を付けて宣言します。
-```erg
+```python
Person! = Class({name = Str; age = Nat!})
Person!.
greet! ref! self = print! "Hello, my name is {self::name}. I am {self::age}."
@@ -19,7 +21,7 @@ Person!.
可変型オブジェクトの破壊的操作は、主に`.update!`メソッドを介して行います。`.update!`メソッドは高階プロシージャで、`self`に関数`f`を適用して更新します。
-```erg
+```python
i = !1
i.update! old -> old + 1
assert i == 2
@@ -27,7 +29,7 @@ assert i == 2
`.set!`メソッドは単に古い内容を捨てて新しい値に差し替えます。`.set! x = .update! _ -> x`です。
-```erg
+```python
i = !1
i.set! 2
assert i == 2
@@ -35,14 +37,14 @@ assert i == 2
`.freeze_map`メソッドは値を不変化して操作を行います。
-```erg
+```python
a = [1, 2, 3].into [Nat; !3]
x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(Array)
```
多相不変型において型の型引数`T`は暗黙に不変型であると仮定されます。
-```erg
+```python
# ImmutType < Type
K T: ImmutType = Class ...
K! T: Type = Class ...
@@ -53,7 +55,7 @@ K! T: Type = Class ...
注意として、オブジェクトの可変性にはいくつかの種類があります。
以下では組み込みのコレクション型について、その不変/可変型の意味を確認します。
-```erg
+```python
# 配列型
## 不変型(immutable types)
[T; N] # 可変操作は実行できない
@@ -72,7 +74,7 @@ K! T: Type = Class ...
これらの配列型は糖衣構文であり、実際の型は以下の通りです。
-```erg
+```python
# 実際は4種類の型
[T; N] = Array(T, N)
[T; !N] = Array!(T, !N)
@@ -85,7 +87,7 @@ K! T: Type = Class ...
なお、型を変更可能とはこのような意味です。
-```erg
+```python
a = [1, 2, 3].into [!Nat; 3]
a.map!(_ -> "a")
a: [!Str; 3]
@@ -93,7 +95,7 @@ a: [!Str; 3]
他のコレクション型についても同様です。
-```erg
+```python
# タプル型
## 不変型(immutable types)
(T, U) # 要素数不変、中身を変更できない
@@ -103,7 +105,7 @@ a: [!Str; 3]
...
```
-```erg
+```python
# セット型
## 不変型(immutable types)
{T; N} # 不変要素数、中身を変更できない
@@ -114,7 +116,7 @@ a: [!Str; 3]
...
```
-```erg
+```python
# 辞書型
## 不変型(immutable types)
{K: V} # 不変長、中身を変更できない
@@ -124,7 +126,7 @@ a: [!Str; 3]
...
```
-```erg
+```python
# レコード型
## 不変型(immutable types)
{x = Int; y = Str} # 中身を変更できない
@@ -137,7 +139,7 @@ a: [!Str; 3]
`T = (...)`のとき単に`T! = (...)!`となる型`(...)`を単純構造型と呼びます。単純構造型は(意味論上)内部構造を持たない型ともいえます。
配列、タプル、セット、辞書、レコード型は全て単純構造型ではありませんが、Int型や篩型は単純構造型です。
-```erg
+```python
# 篩型
## 列挙型
{1, 2, 3} # 1, 2, 3のうちどれか、変更できない
diff --git a/doc/JA/syntax/type/19_bound.md b/doc/JA/syntax/type/19_bound.md
index 3024ebc8..f027dae0 100644
--- a/doc/JA/syntax/type/19_bound.md
+++ b/doc/JA/syntax/type/19_bound.md
@@ -1,5 +1,7 @@
# 型境界 (Type Bound)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/19_bound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
型境界は型指定に条件を加えるものである。これを実現する機能がガード(ガード節)である。
関数シグニチャ、無名関数シグニチャのほか、篩型でもこの機能を利用できる。
ガードは戻り値型の後に記述する。
@@ -9,7 +11,7 @@
変数の満たす条件を、`Bool`を返す式(述語式)で指定できる。
使用できるのは[値オブジェクト](./08_value.md)と演算子だけである。コンパイル時関数は今後のバージョンで対応される可能性がある。
-```erg
+```python
f a: [T; N] | T, N, N > 5 = ...
g a: [T; N | N > 5] | T, N = ...
Odd = {I: Int | I % 2 == 1}
diff --git a/doc/JA/syntax/type/advanced.md b/doc/JA/syntax/type/advanced.md
index 57fa0935..9f810e4e 100644
--- a/doc/JA/syntax/type/advanced.md
+++ b/doc/JA/syntax/type/advanced.md
@@ -1 +1,4 @@
以降は更に高度な型システムを解説します。入門者の方はすべての項を読まなくても問題ありません。
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/syntax/type/advanced/GADTs.md b/doc/JA/syntax/type/advanced/GADTs.md
index 2b8a8a7d..3e5a4f91 100644
--- a/doc/JA/syntax/type/advanced/GADTs.md
+++ b/doc/JA/syntax/type/advanced/GADTs.md
@@ -1,8 +1,10 @@
# 一般化代数的データ型(Generalized Algebraic Data Types, GADTs)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/GADTs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
ErgはOr型をクラス化することで一般化代数的データ型(GADTs)を作成出来ます。
-```erg
+```python
Nil T = Class(Impl := Phantom T)
Cons T = Class {head = T; rest = List T}, Impl := Unpack
List T: Type = Class(Nil T or Cons T)
@@ -20,7 +22,7 @@ print! nil.head() # RuntimeError: "empty list"
`List(T).nil() = ...`ではなく`List.nil|T|() = ...`としているのは、使用時に型指定が不要になるからです。
-```erg
+```python
i = List.nil()
_: List Int = cons 1, i
```
@@ -28,7 +30,7 @@ _: List Int = cons 1, i
ここで定義した`List T`はGADTsですが、素朴な実装であり、GADTsの真価を発揮していません。
例えば、上の`.head`メソッドはもし中身が空なら実行時エラーを出しますが、この検査はコンパイル時に行うことができます。
-```erg
+```python
List: (Type, {"Empty", "Nonempty"}) -> Type
List T, "Empty" = Class(Impl := Phantom T)
List T, "Nonempty" = Class {head = T; rest = List(T, _)}, Impl := Unpack
@@ -46,7 +48,7 @@ print! nil().head() # TypeError
巷でよく説明されるGADTsの例は、以上のように中身が空か否か型で判定できるリストです。
Ergではさらに精密化して、長さを持つリストを定義できます。
-```erg
+```python
List: (Type, Nat) -> Type
List T, 0 = Class(Impl := Phantom T)
List T, N = Class {head = T; rest = List(T, N-1)}, Impl := Unpack
diff --git a/doc/JA/syntax/type/advanced/_rank2type.md b/doc/JA/syntax/type/advanced/_rank2type.md
index 79fdd3ae..77ef9348 100644
--- a/doc/JA/syntax/type/advanced/_rank2type.md
+++ b/doc/JA/syntax/type/advanced/_rank2type.md
@@ -1,12 +1,14 @@
# rank-2多相
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/_rank2type.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
> __Warning__: このドキュメントは情報が古く、全般に間違いを含みます。
Ergでは`id|T|(x: T): T = x`などのように色々な型を受け取れる関数、すなわち多相関数を定義できる。
では、多相関数を受け取れる関数は定義できるだろうか?
例えば、このような関数である(この定義は誤りを含むことに注意してほしい)。
-```erg
+```python
# tuple_map(i -> i * 2, (1, "a")) == (2, "aa")になってほしい
tuple_map|T|(f: T -> T, tup: (Int, Str)): (Int, Str) = (f(tup.0), f(tup.1))
```
@@ -15,7 +17,7 @@ tuple_map|T|(f: T -> T, tup: (Int, Str)): (Int, Str) = (f(tup.0), f(tup.1))
今まで説明してきた型の範疇では、このような関数の定義はできない。型変数にスコープの概念がないからである。
ここで一旦型を離れて、値レベルでのスコープの概念を確認する。
-```erg
+```python
arr = [1, 2, 3]
arr.map i -> i + 1
```
@@ -25,7 +27,7 @@ arr.map i -> i + 1
今までの型は、全ての型変数で生存期間が同一なのである。すなわち、`T`, `X`, `Y`は同時に決定されていて、以降は不変でなければならない。
逆に言えば、`T`を「内側のスコープ」にある型変数とみなすことができるならば`tuple_map`関数を構成できる。そのために用意されたのが、 __ランク2型__ である。
-```erg
+```python
# tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str)
tuple_map f: (|T: Type| T -> T), tup: (Int, Str) = (f(tup.0), f(tup.1))
assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa")
@@ -34,7 +36,7 @@ assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa")
`{(型) | (型変数のリスト)}`という形式の型を全称型といった(詳しくは[全称型](./../quantified.md)を参照)。
いままで見てきた`id`関数は、典型的な全称関数=多相関数である。
-```erg
+```python
id x = x
id: |T: Type| T -> T
```
@@ -43,7 +45,7 @@ id: |T: Type| T -> T
これについて、単純な1引数関数を使って考える。
-```erg
+```python
f1: (T -> T) -> Int | T # 任意の関数を受け取り、Intを返す関数
f2: (|T: Type| T -> T) -> Int # 多相関数を受け取り、Intを返す関数
f3: Int -> (|T: Type| T -> T) # Intを受け取り、閉じた全称型関数を返す関数
@@ -52,7 +54,7 @@ f4: |T: Type|(Int -> (T -> T)) # 上と同じ意味(こちらが推奨)
`f3`と`f4`が同じなのに対して、`f1`と`f2`は異なるというのは奇妙に思える。実際にそのような型の関数を構成してみる。
-```erg
+```python
# id: |T: Type| T -> T
id x = x
# same type as `f1`
@@ -67,7 +69,7 @@ take_i_and_return_arbit_f|T: Type|(_: Int): (T -> T) = id
適用してみると、その違いがわかってくる。
-```erg
+```python
_ = take_univq_f_and_return_i(x -> x, 1) # OK
_ = take_univq_f_and_return_i(x: Int -> x, 1) # NG
_ = take_univq_f_and_return_i(x: Str -> x, 1) # NG
@@ -90,7 +92,7 @@ assert f2 == g2
ランクの定義だが、まず量化されていない型、すなわち`Int`, `Str`, `Bool`, `T`, `Int -> Int`, `Option Int`などは「ランク0」とされる。
-```erg
+```python
# KはOptionなどの多項カインド
R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0)
```
@@ -99,7 +101,7 @@ R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0)
さらに二階の全称量化が行われている型(`(|T| T -> T) -> Int`などランク1型を引数に持つ型)、またはそれらを戻り値型に含む型を「ランク2」とする。
以上を繰り返して「ランクN」型が定義される。また、ランクN型はN以下のランクの型をすべて含む。ゆえに、複数のランクが混在する型のランクは、その中で最も高いランクと同じになる。
-```erg
+```python
R1 = (|...| R0) or (R0 -> R1) or K(R1) or R0
R2 = (|...| R1) or (R1 -> R2) or K(R2) or R1
...
@@ -108,7 +110,7 @@ Rn = (|...| Rn-1) or (Rn-1 -> Rn) or K(Rn) or Rn-1
いくつか例をみてみよう。
-```erg
+```python
(|T: Type| T -> T) -> (|U: Type| U -> U)
=> R1 -> R1
=> R1 -> R2
@@ -122,7 +124,7 @@ Option(|T: Type| T -> T)
定義より、`tuple_map`はランク2型である。
-```erg
+```python
tuple_map:
((|T: Type| T -> T), (Int, Str)) -> (Int, Str)
=> (R1, R0) -> R0
@@ -133,7 +135,7 @@ tuple_map:
Ergでは、ランク2までの型を扱うことができる(ランクN型はN以下のランクの型をすべて含むため、正確にいうとErgの型はすべてランク2型である)。それ以上の型の関数を構成しようとするとエラーになる。
例えば、多相関数を多相関数のまま扱う関数はすべて他の引数の型指定が必要である。また、このような関数は構成できない。
-```erg
+```python
# this is a rank-3 type function
# |X, Y: Type|((|T: Type| T -> T), (X, Y)) -> (X, Y)
generic_tuple_map|X, Y: Type| f: (|T: Type| T -> T), tup: (X, Y) = (f(tup.0), f(tup.1))
diff --git a/doc/JA/syntax/type/advanced/default_param.md b/doc/JA/syntax/type/advanced/default_param.md
index e183cd97..33309674 100644
--- a/doc/JA/syntax/type/advanced/default_param.md
+++ b/doc/JA/syntax/type/advanced/default_param.md
@@ -1,8 +1,10 @@
# デフォルト引数付きの関数型
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/default_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
まず、デフォルト引数の使用例を見る。
-```erg
+```python
f: (Int, Int, z := Int) -> Int
f(x, y, z := 0) = x + y + z
@@ -19,7 +21,7 @@ assert fold(g, [1, 2, 3]) == 8
`:=`以降の引数はデフォルト引数である。
部分型付け規則は以下の通り。
-```erg
+```python
((X, y := Y) -> Z) <: (X -> Z)
((X, y := Y, ...) -> Z) <: ((X, ...) -> Z)
```
diff --git a/doc/JA/syntax/type/advanced/erasure.md b/doc/JA/syntax/type/advanced/erasure.md
index 08c0c66c..fe58b35d 100644
--- a/doc/JA/syntax/type/advanced/erasure.md
+++ b/doc/JA/syntax/type/advanced/erasure.md
@@ -1,12 +1,14 @@
# 型消去(Type erasure)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/erasure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
型消去とは、型引数に`_`を指定し、その情報をあえて捨てることです。型消去は多相型を持つ言語の多くが併せて持つ機能ですが、Ergの文法に即して言えば型引数消去といった方が正確でしょう。
もっともよく見られる型消去された型の例は`[T, _]`でしょう。配列はコンパイル時にその長さが分からない場合もあります。例えば、コマンドライン引数を指す`sys.argv`は`[Str, _]`型です。コマンドライン引数の長さをErgのコンパイラは知りようがないため、長さに関する情報は諦めなくてはならないのです。
しかし、型消去された型は、されていない型のスーパータイプになる(e.g. `[T; N] < [T; _]`)ため、より多くのオブジェクトを受け取れるようになります。
`[T; N]`型のオブジェクトはもちろん`[T; _]`型のメソッドを使用できますが、使用後`n`の情報は消去されます。長さが変わってしまっているかもしれないからです。長さが変わらないならばシグネチャで示さなくてはなりません。
-```erg
+```python
# 配列の長さが変わらないことが保証される関数(sortなど)
f: [T; N] -> [T; N]
# されない関数(filterなど)
@@ -16,14 +18,14 @@ g: [T; n] -> [T; _]
型指定自体で`_`を使うとその型は`Object`までアップキャストされます。
型でない型引数(Int, Bool型など)の場合、`_`としたパラメータは未定義になります。
-```erg
+```python
i: _ # i: Object
[_; _] == [Object; _] == Array
```
型消去は型指定の省略とは違います。一度型引数情報を消去してしまうと、再びアサーションしなければ情報は戻りません。
-```erg
+```python
implicit = (1..5).iter().map(i -> i * 2).to_arr()
explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat))
```
@@ -36,7 +38,7 @@ let partial = (1..6).iter().map(|i| i * 2).collect::>();
Ergでは型の部分省略はできず、代わりに高階カインド多相を使用します。
-```erg
+```python
# collectはカインドを受け取る高階カインドのメソッド
hk = (1..5).iter().map(i -> i * 2).collect(Array)
hk: Array(Int)
diff --git a/doc/JA/syntax/type/advanced/existential.md b/doc/JA/syntax/type/advanced/existential.md
index 4e433516..d47c5fc8 100644
--- a/doc/JA/syntax/type/advanced/existential.md
+++ b/doc/JA/syntax/type/advanced/existential.md
@@ -1,9 +1,11 @@
# 存在型
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/existential.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
∀に対応する全称型があるならば、∃に対応する存在型があると考えるのが自然です。
存在型は難しいものではありません。そうと意識していないだけで、既にあなたは存在型を知っています。
-```erg
+```python
T: Trait
f x: T = ...
```
@@ -11,7 +13,7 @@ f x: T = ...
上のトレイト`T`は存在型として使われています。
対して下の場合の`T`はトレイトでしかなく、`X`は全称型です。
-```erg
+```python
f|X <: T| x: X = ...
```
@@ -19,7 +21,7 @@ f|X <: T| x: X = ...
まず、上で見たように存在型は型変数を伴わないので、型指定をシンプルにできます。
また、型変数を除去できるので全称型ならランク2を超えてしまうような型も構成できます。
-```erg
+```python
show_map f: (|T| T -> T), arr: [Show; _] =
arr.map x ->
y = f x
@@ -30,7 +32,7 @@ show_map f: (|T| T -> T), arr: [Show; _] =
しかし、見ればわかるように存在型は元の型を忘却・拡大してしまうので、戻り値の型を広げたくない場合などは全称型を使う必要があります。
逆に、引数として受け取るだけで戻り値に関係のない型は存在型で記述して構いません。
-```erg
+```python
# id(1): Intになって欲しい
id|T|(x: T): T = x
# |S <: Show|(s: S) -> ()は冗長
diff --git a/doc/JA/syntax/type/advanced/keyword_param.md b/doc/JA/syntax/type/advanced/keyword_param.md
index bc2ea537..e77f06f9 100644
--- a/doc/JA/syntax/type/advanced/keyword_param.md
+++ b/doc/JA/syntax/type/advanced/keyword_param.md
@@ -1,13 +1,15 @@
# キーワード引数付き関数型
-```erg
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/keyword_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
h(f) = f(y: 1, x: 2)
h: |T: Type|((y: Int, x: Int) -> T) -> T
```
キーワード引数付き関数の部分型付け規則は以下の通り。
-```erg
+```python
((x: T, y: U) -> V) <: ((T, U) -> V) # x, y are arbitrary keyword parameters
((y: U, x: T) -> V) <: ((x: T, y: U) -> V)
((x: T, y: U) -> V) <: ((y: U, x: T) -> V)
@@ -18,7 +20,7 @@ h: |T: Type|((y: Int, x: Int) -> T) -> T
すなわち、`(x: T, y: U) -> V`を`(U, T) -> V`にキャストすることはできない。
なお、キーワード引数がつくのはトップレベルのタプル内のみで、配列やネストしたタプルでキーワード引数は付かない。
-```erg
+```python
Valid: [T, U] -> V
Invalid: [x: T, y: U] -> V
Valid: (x: T, ys: (U,)) -> V
diff --git a/doc/JA/syntax/type/advanced/kind.md b/doc/JA/syntax/type/advanced/kind.md
index 38399fca..d95aa668 100644
--- a/doc/JA/syntax/type/advanced/kind.md
+++ b/doc/JA/syntax/type/advanced/kind.md
@@ -1,5 +1,7 @@
# カインド(Kind)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/kind.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
Ergでは全てが型付けられている。型自体も例外ではない。「型の型」を表すのが __カインド(種)__ である。例えば`1`が`Int`に属しているように、`Int`は`Type`に属している。`Type`は最もシンプルなカインドである __原子カインド(Atomic kind)__ である。型理論的の記法では、`Type`は`*`に対応する。
カインドという概念で実用上重要なのは1項以上のカインド(多項カインド)である。1項のカインドは、例えば`Option`などがそれに属する。1項カインドは`Type -> Type`と表される[1 ](#1)。`Array`や`Option`などの __コンテナ__ は特に型を引数に取る多項カインドのことなのである。
@@ -9,7 +11,7 @@ Ergでは全てが型付けられている。型自体も例外ではない。
また、原子カインドでないカインドは型ではないことに注意してほしい。`-1`は数値だが`-`は数値ではないのと同じように、`Option Int`は型だが`Option`は型ではない。`Option`などは型構築子と呼ばれることもある。
-```erg
+```python
assert not Option in Type
assert Option in Type -> Type
```
@@ -17,7 +19,7 @@ assert Option in Type -> Type
なので、以下のようなコードはエラーになる。
Ergではメソッドを定義できるのは原子カインドのみで、メソッドの第一引数以外の場所で`self`という名前を使えない。
-```erg
+```python
# K is an unary kind
K: Type -> Type
K T = Class ...
@@ -32,7 +34,7 @@ K(T).
0項のカインド`() -> Type`も存在する。これは型理論的には原子カインドと同一視されることもあるが、Ergでは区別される。例としては`Class`などがある。
-```erg
+```python
Nil = Class()
```
@@ -40,7 +42,7 @@ Nil = Class()
多項カインド間にも部分型関係、もとい部分カインド関係があります。
-```erg
+```python
K T = ...
L = Inherit K
L <: K
@@ -48,7 +50,7 @@ L <: K
すなわち、任意の`T`に対し`L T <: K T`ならば`L <: K`であり、その逆も成り立ちます。
-```erg
+```python
∀T. L T <: K T <=> L <: K
```
@@ -56,7 +58,7 @@ L <: K
高階カインド(higher-order kind)というものもある。これは高階関数と同じコンセプトのカインドで、カインド自体を受け取るカインドである。`(Type -> Type) -> Type`などが高階カインドである。高階カインドに属するオブジェクトを定義してみよう。
-```erg
+```python
IntContainerOf K: Type -> Type = K Int
assert IntContainerOf Option == Option Int
assert IntContainerOf Result == Result Int
@@ -69,26 +71,26 @@ assert IntContainerOf in (Type -> Type) -> Type
型理論において、レコードという概念がある。これはErgのレコードとほぼ同じものである[2 ](#2)。
-```erg
+```python
# This is a record, and it corresponds to what is called a record in type theory
{x = 1; y = 2}
```
レコードの値が全て型であるとき、それはレコード型といって型の一種であった。
-```erg
+```python
assert {x = 1; y = 2} in {x = Int; y = Int}
```
レコード型はレコードを型付けする。察しの良い方は、レコード型を型付けする「レコードカインド」があるはずだと考えたかもしれない。実際に、それは存在する。
-```erg
+```python
log Typeof {x = Int; y = Int} # {{x = Int; y = Int}}
```
`{{x = Int; y = Int}}`のような型がレコードカインドである。これは特別な記法ではない。単に、`{x = Int; y = Int}`のみを要素に持つ列挙型である。
-```erg
+```python
Point = {x = Int; y = Int}
Pointy = {Point}
```
@@ -96,7 +98,7 @@ Pointy = {Point}
レコードカインドの重要な特性は、`T: |T|`であり、`U <: T`であるとき、`U: |T|`であるという点にある。
これは列挙型が実際には篩型の糖衣構文であることからもわかる。
-```erg
+```python
# 通常のオブジェクトでは{c} == {X: T | X == c}だが、
# 型の場合等号が定義されない場合があるので|T| == {X | X <: T}となる
{Point} == {P | P <: Point}
@@ -105,7 +107,7 @@ Pointy = {Point}
型制約中の`U <: T`は、実は`U: |T|`の糖衣構文である。
このような型のセットであるカインドは一般にセットカインドと呼ばれる。セットカインドはIteratorパターンでも現れる。
-```erg
+```python
Iterable T = Trait {
.Iterator = {Iterator}
.iter = Self(T).() -> Self.Iterator T
@@ -114,7 +116,7 @@ Iterable T = Trait {
## 多項カインドの型推論
-```erg
+```python
Container K: Type -> Type, T: Type = Patch K(T, T)
Container(K).
f self = ...
diff --git a/doc/JA/syntax/type/advanced/marker_trait.md b/doc/JA/syntax/type/advanced/marker_trait.md
index be11716b..93f55f28 100644
--- a/doc/JA/syntax/type/advanced/marker_trait.md
+++ b/doc/JA/syntax/type/advanced/marker_trait.md
@@ -1,20 +1,22 @@
# Marker Trait
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/marker_trait.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
マーカートレイトは、要求属性のないトレイトである。すなわち、メソッドを実装せずにImplすることができる。
要求属性がないと意味がないように思えるが、そのトレイトに属しているという情報が登録されるので、パッチメソッドを使ったり、コンパイラが特別扱いしたりできる。
すべてのマーカートレイトは`Marker`トレイトに包摂される。
標準で提供されている`Light`はマーカートレイトの一種である。
-```erg
+```python
Light = Subsume Marker
```
-```erg
+```python
Person = Class {.name = Str; .age = Nat} and Light
```
-```erg
+```python
M = Subsume Marker
MarkedInt = Inherit Int, Impl := M
@@ -26,6 +28,6 @@ assert i in M
マーカークラスは`Excluding`引数で外すことも可能である。
-```erg
+```python
NInt = Inherit MarkedInt, Impl := N, Excluding: M
```
diff --git a/doc/JA/syntax/type/advanced/mut_struct.md b/doc/JA/syntax/type/advanced/mut_struct.md
index d1efe69b..b963b704 100644
--- a/doc/JA/syntax/type/advanced/mut_struct.md
+++ b/doc/JA/syntax/type/advanced/mut_struct.md
@@ -1,8 +1,10 @@
# 可変構造型
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/mut_struct.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
`T!`型は任意の`T`型オブジェクトを入れられて差し替え可能なボックス型であると説明した。
-```erg
+```python
Particle! State: {"base", "excited"}! = Class(..., Impl := Phantom State)
Particle!.
# このメソッドはStateを"base"から"excited"に遷移させる
@@ -19,7 +21,7 @@ Particle!.
それを実現するのが可変構造(可変)型である。
-```erg
+```python
v = [Str; !0].new()
v.push! "Hello"
v: [Str; !1]
@@ -30,7 +32,7 @@ v: [Str; !1]
可変構造型はもちろんユーザー定義も可能である。ただし、不変構造型とは構成法に関していくつか違いがあるので注意が必要である。
-```erg
+```python
Nil T = Class(Impl := Phantom T)
List T, !0 = Inherit Nil T
List T, N: Nat! = Class {head = T; rest = List(T, !N-1)}
diff --git a/doc/JA/syntax/type/advanced/newtype.md b/doc/JA/syntax/type/advanced/newtype.md
index 6859b904..943c9478 100644
--- a/doc/JA/syntax/type/advanced/newtype.md
+++ b/doc/JA/syntax/type/advanced/newtype.md
@@ -1,10 +1,12 @@
# Newtype pattern
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/newtype.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
ここでは、Rustでよく使われるnewtypeパターンのErg版を紹介します。
Ergはでは以下のように型のエイリアスを定義できますが、これはあくまで同じ型を指します。
-```erg
+```python
UserId = Int
```
@@ -14,7 +16,7 @@ UserId = Int
newtypeパターンはこのような場合に適したデザインパターンです。
-```erg
+```python
UserId = Class {id = Nat}
UserId.
new id: Nat =
diff --git a/doc/JA/syntax/type/advanced/overloading.md b/doc/JA/syntax/type/advanced/overloading.md
index af0633ac..8aed76d2 100644
--- a/doc/JA/syntax/type/advanced/overloading.md
+++ b/doc/JA/syntax/type/advanced/overloading.md
@@ -1,9 +1,11 @@
# オーバーロード
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/overloading.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
Ergでは __アドホック多相__ をサポートしない。すなわち、関数・カインドの多重定義(オーバーロード)ができない。が、トレイトクラスとパッチを組み合わせることでオーバーロードの挙動を再現できる。
トレイトクラスのかわりにトレイトを使用しても良いが、その場合`.add1`を実装している型全てが対象になってしまう。
-```erg
+```python
Add1 = Trait {
.add1: Self.() -> Self
}
@@ -24,7 +26,7 @@ assert add1(1.0) == 2.0
各型での処理が完全に同じなら下のように書くこともできる。上の書き方は、クラスによって挙動を変える(が、戻り値型は同じ)場合に使う。
型引数を使う多相を __パラメトリック多相__ という。パラメトリック多相は下のように部分型指定と併用する場合が多く、その場合はパラメトリック多相とサブタイピング多相の合わせ技ということになる。
-```erg
+```python
add1|T <: Int or Str| x: T = x + 1
assert add1(1) == 2
assert add1(1.0) == 2.0
@@ -32,7 +34,7 @@ assert add1(1.0) == 2.0
また、引数の数が違うタイプのオーバーロードはデフォルト引数で再現できる。
-```erg
+```python
C = Class {.x = Int; .y = Int}
C.
new(x, y := 0) = Self::__new__ {.x; .y}
@@ -47,7 +49,7 @@ assert C.new(0, 0) == C.new(0)
まず、オーバーロードされた関数は定義が分散する。このため、エラーが発生した際に原因となる箇所を報告するのが難しい。
また、サブルーチンをインポートすることによって、すでに定義されたサブルーチンの挙動が変わる恐れもある。
-```erg
+```python
{id; ...} = import "foo"
...
id x: Int = x
@@ -60,7 +62,7 @@ id "str" # TypeError: id is not implemented for Str
次に、デフォルト引数との相性が悪い。デフォルト引数のある関数がオーバーロードされているとき、どれが優先されるかという問題がある。
-```erg
+```python
f x: Int = ...
f(x: Int, y := 0) = ...
@@ -70,7 +72,7 @@ f(1) # which is chosen?
さらに、宣言との相性が悪い。
宣言`f: Num -> Num`は、どちらの定義のことを指しているのか特定できない。`Int -> Ratio`と`Ratio -> Int`は包含関係がないためである。
-```erg
+```python
f: Num -> Num
f(x: Int): Ratio = ...
f(x: Ratio): Int = ...
@@ -79,7 +81,7 @@ f(x: Ratio): Int = ...
そして、文法の一貫性を損なう。Ergは変数の再代入を禁止するが、オーバーロードの文法は再代入のように見えてしまう。
無名関数に置換することもできない。
-```erg
+```python
# same as `f = x -> body`
f x = body
diff --git a/doc/JA/syntax/type/advanced/phantom.md b/doc/JA/syntax/type/advanced/phantom.md
index 6933bdf9..d7441589 100644
--- a/doc/JA/syntax/type/advanced/phantom.md
+++ b/doc/JA/syntax/type/advanced/phantom.md
@@ -1,9 +1,11 @@
# 幽霊型(Phantom class)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/phantom.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
幽霊型は、コンパイラに注釈を与えるためだけに存在するマーカートレイトである。
幽霊型の使い方として、リストの構成をみる。
-```erg
+```python
Nil = Class()
List T, 0 = Inherit Nil
List T, N: Nat = Class {head = T; rest = List(T, N-1)}
@@ -11,7 +13,7 @@ List T, N: Nat = Class {head = T; rest = List(T, N-1)}
このコードはエラーとなる。
-```erg
+```python
3 | List T, 0 = Inherit Nil
^^^
TypeConstructionError: since Nil does not have a parameter T, it is not possible to construct List(T, 0) with Nil
@@ -21,7 +23,7 @@ hint: use 'Phantom' trait to consume T
このエラーはつまり、`List(_, 0).new Nil.new()`とされたときに`T`の型推論ができないという文句である。Ergでは型引数を未使用のままにすることができないのである。
このような場合は何でもよいので`T`型を右辺で消費する必要がある。サイズが0の型、例えば長さ0のタプルならば実行時のオーバーヘッドもなく都合がよい。
-```erg
+```python
Nil T = Class((T; 0))
List T, 0 = Inherit Nil T
List T, N: Nat = Class {head = T; rest = List(T, N-1)}
@@ -31,7 +33,7 @@ List T, N: Nat = Class {head = T; rest = List(T, N-1)}
このようなときにちょうどよいのが幽霊型である。幽霊型はサイズ0の型を一般化した型である。
-```erg
+```python
Nil T = Class(Impl := Phantom T)
List T, 0 = Inherit Nil T
List T, N: Nat = Class {head = T; rest = List(T, N-1)}
@@ -45,7 +47,7 @@ assert nil.__size__ == 0
また、`Phantom`は型以外にも任意の型引数を消費することができる。以下の例では`State`という`Str`のサブタイプオブジェクトである型引数を`Phantom`が保持している。
この場合も、`state`はオブジェクトの実体に現れないハリボテの型変数である。
-```erg
+```python
VM! State: {"stopped", "running"}! = Class(..., Impl := Phantom! State)
VM!("stopped").
start ref! self("stopped" ~> "running") =
diff --git a/doc/JA/syntax/type/advanced/projection.md b/doc/JA/syntax/type/advanced/projection.md
index 404edff6..20f47c9d 100644
--- a/doc/JA/syntax/type/advanced/projection.md
+++ b/doc/JA/syntax/type/advanced/projection.md
@@ -1,8 +1,10 @@
# Projection Type(射影型)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/projection.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
射影型は、次のコードにおける`Self.AddO`のような型を表します。
-```erg
+```python
Add R = Trait {
.`_+_` = Self, R -> Self.AddO
.AddO = Type
@@ -16,7 +18,7 @@ AddForInt.
`Add(R)`型は何らかのオブジェクトとの加算が定義されている型といえます。メソッドは型属性であるべきなので、`+`の型宣言はインデント以下に記述します。
`Add`型のミソとなるのが`.AddO = Type`という宣言で、射影型である`.AddO`型の実体は、`Add`のサブタイプである型が持ちます。例えば、`Int.AddO = Int`, `Odd.AddO = Even`です。
-```erg
+```python
assert Int < Add
assert Int.AddO == Int
assert Odd < Add
diff --git a/doc/JA/syntax/type/advanced/quantified_dependent.md b/doc/JA/syntax/type/advanced/quantified_dependent.md
index b778acf3..ddbe1943 100644
--- a/doc/JA/syntax/type/advanced/quantified_dependent.md
+++ b/doc/JA/syntax/type/advanced/quantified_dependent.md
@@ -1,8 +1,10 @@
# 量化依存型
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/quantified_dependent.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
Ergには量化型、依存型が存在します。すると当然、その二つを組み合わせた型を作ることができます。それが量化依存型です。
-```erg
+```python
NonNullStr = |N: Nat| StrWithLen N | N != 0 # same as {S | N: Nat; S: StrWithLen N; N != 0}
NonEmptyArray = |N: Nat| [_; N | N > 0] # same as {A | N: Nat; A: Array(_, N); N > 0}
```
@@ -11,7 +13,7 @@ NonEmptyArray = |N: Nat| [_; N | N > 0] # same as {A | N: Nat; A: Array(_, N); N
左辺値としての量化依存型は、元の型と同じモジュール内でのみメソッドを定義出来ます。
-```erg
+```python
K A: Nat = Class ...
K(A).
...
@@ -21,7 +23,7 @@ K(A | A >= 1).
右辺値としての量化依存型は、使用する型変数を型変数リスト(`||`)で宣言する必要がある。
-```erg
+```python
# Tは具体的な型
a: |N: Nat| [T; N | N > 1]
```
diff --git a/doc/JA/syntax/type/advanced/shared.md b/doc/JA/syntax/type/advanced/shared.md
index ea2a8700..f2805470 100644
--- a/doc/JA/syntax/type/advanced/shared.md
+++ b/doc/JA/syntax/type/advanced/shared.md
@@ -1,5 +1,7 @@
# 共有参照(Shared Reference)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/shared.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
共有参照は気をつけて扱わねばならない言語機能の一つです。
例えばTypeScriptでは以下のようなコードが型検査を通ってしまいます。
@@ -21,7 +23,7 @@ console.log(vip_area) # [NormalMember]
Ergでは、所有権システムのおかげでこのようなコードは弾かれます。
-```erg
+```python
NormalMember = Class()
VIPMember = Class()
@@ -35,7 +37,7 @@ log vip_area # OwnershipError: `vip_room` was moved to `normal_room`
しかし、オブジェクトの所有権が一箇所にしかない状態は不便である場合もあります。
そのためにErgは`SharedCell! T!`という型があり、これが共有状態を表します。
-```erg
+```python
$p1 = SharedCell!.new(!1)
$p2 = $p1.mirror!()
$p3 = SharedCell!.new(!1)
@@ -57,7 +59,7 @@ assert $p3 == 1
重要な事実として、`SharedCell! T!`は非変(non-variant)です。すなわち、型引数の違いによる包含関係が定義されません。
-```erg
+```python
$vip_area = SharedCell!.new([].into [VIPMember; !_])
$normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError: expected SharedCell!([NormalMember; !_]), but got SharedCell!([VIPMember; !_])
# hint: SharedCell!(T) is non-variant, which means it cannot have a supertype or a subtype.
@@ -65,7 +67,7 @@ $normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError:
しかし、以下のコードは問題ありません。最後の行では、型変換されたのは引数の`VIPMember`の方です。
-```erg
+```python
$normal_area = SharedCell!.new([].into [NormalMember; !_])
$normal_area.push!(NormalMember.new()) # OK
$normal_area.push!(VIPMember.new()) # OK
diff --git a/doc/JA/syntax/type/advanced/special.md b/doc/JA/syntax/type/advanced/special.md
index 482ad174..a63d1502 100644
--- a/doc/JA/syntax/type/advanced/special.md
+++ b/doc/JA/syntax/type/advanced/special.md
@@ -1,8 +1,10 @@
# 特殊型(Self, Super)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
`Self`は自身の型を表します。単にエイリアスとして使うことも出来ますが、派生型中では意味が変わる(自身の型を指す)ので注意してください。
-```erg
+```python
@Inheritable
C = Class()
C.
@@ -16,7 +18,7 @@ classof D.new_c() # C
`Super`は基底クラスの型を表します。メソッド自体は基底クラスのものを参照しますが、インスタンスは自身の型を使います。
-```erg
+```python
@Inheritable
C = Class()
@@ -33,7 +35,7 @@ classof D.new_c() # C
`Self`, `Super`は、構造型・トレイト中では型変数として使用できます。これは、その型のサブタイプであるところのクラスを指します。すなわち、型`T`中で`Self`は`Self <: T`を意味します。
-```erg
+```python
Add R = Trait {
.AddO = Type
.`_+_`: Self, R -> Self.AddO
diff --git a/doc/JA/syntax/type/advanced/typeof.md b/doc/JA/syntax/type/advanced/typeof.md
index f9fa02aa..df6b1117 100644
--- a/doc/JA/syntax/type/advanced/typeof.md
+++ b/doc/JA/syntax/type/advanced/typeof.md
@@ -1,8 +1,10 @@
# Typeof, classof
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/typeof.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
`Typeof`はErgの型推論システムを覗くことができる関数であり、その挙動は複雑である。
-```erg
+```python
assert Typeof(1) == {I: Int | I == 1}
i: 1..3 or 5..10 = ...
assert Typeof(i) == {I: Int | (I >= 1 and I <= 3) or (I >= 5 and I <= 10)}
@@ -21,7 +23,7 @@ assert {X: C | X == I} < C and C <= {i = Int}
値クラスに関しては本来対応するレコード型が存在しない。この問題を解消するため、値クラスは`__valueclass_tag__`属性を持っているレコード型ということになっている。
なお、この属性にアクセスすることはできず、ユーザー定義型で`__valueclass_tag__`属性を定義することもできない。
-```erg
+```python
i: Int = ...
assert Typeof(i) == {__valueclass_tag__ = Phantom Int}
s: Str = ...
@@ -38,7 +40,7 @@ Ergは可能な限りオブジェクトの型を篩型として推論し、そ
すべてのクラスは構造型に変換することができる。これを __構造化__ という。クラスの構造化された型は`Structure`関数で取得できる。
クラスが`C = Class T`で定義されているとき(すべてのクラスはこの形式で定義されている)、`Structure(C) == T`になる。
-```erg
+```python
C = Class {i = Int}
assert Structure(C) == {i = Int}
D = Inherit C
diff --git a/doc/JA/syntax/type/advanced/variance.md b/doc/JA/syntax/type/advanced/variance.md
index 7ff493af..04f16814 100644
--- a/doc/JA/syntax/type/advanced/variance.md
+++ b/doc/JA/syntax/type/advanced/variance.md
@@ -1,5 +1,7 @@
# 変性(variance)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/variance.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
Ergは多相型のサブタイピングを行えるが、一部注意しなくてはならない点がある。
まずは通常の多相型の包含関係を考える。一般に、コンテナ`K`と代入する型`A, B`があり、`A < B`のとき、`K A < K B`となる。
@@ -49,7 +51,7 @@ Ergにはもう一つ変性がある。それは非変性(non-variance)である
全称型の型変数は、その上限・下限を指定できます。
-```erg
+```python
|A <: T| K(A)
|B :> T| K(B)
```
@@ -59,14 +61,14 @@ Ergにはもう一つ変性がある。それは非変性(non-variance)である
変性指定は重ねがけすることもできます。
-```erg
+```python
# U < A < T
{... | A <: T; A :> U}
```
以下に変性指定を使ったコードの例を示します。
-```erg
+```python
show|S <: Show| s: S = log s
Nil T = Class(Impl=Phantom T)
@@ -90,7 +92,7 @@ List(T).
ここで、メソッドの変性指定を省略した場合どうなるか考えます。
-```erg
+```python
...
List T = Class {head = T; rest = Cons T}
List(T).
@@ -109,7 +111,7 @@ List(T).
では、このアップキャストを許可するようにした場合はどうなるか考えます。
変性指定を反転させてみましょう。
-```erg
+```python
...
List T = Class {head = T; rest = Cons T}
List(T).
@@ -128,7 +130,7 @@ List(T).
`Inputs(T)`と指定すると、その型は`T`に関して反変となる。
`Outputs(T)`と指定すると、その型は`T`に関して共変となる。
-```erg
+```python
K T = Class(...)
assert not K(Str) <= K(Object)
assert not K(Str) >= K(Object)
diff --git a/doc/JA/syntax/type/advanced/widening.md b/doc/JA/syntax/type/advanced/widening.md
index da0ecf24..2bb2d786 100644
--- a/doc/JA/syntax/type/advanced/widening.md
+++ b/doc/JA/syntax/type/advanced/widening.md
@@ -1,8 +1,10 @@
# 型拡大(Type Widening)
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/widening.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
例えば以下のような多相関数を定義する。
-```erg
+```python
ids|T|(x: T, y: T) = x, y
```
@@ -10,7 +12,7 @@ ids|T|(x: T, y: T) = x, y
包含関係にある別のクラスのインスタンスペアを代入すると、大きい方にアップキャストされて同じ型になる。
また、包含関係にない別のクラスを代入するとエラーになるのも容易に理解できる。
-```erg
+```python
assert ids(1, 2) == (1, 2)
assert ids(1, 2.0) == (1.0, 2.0)
ids(1, "a") # TypeError
@@ -18,7 +20,7 @@ ids(1, "a") # TypeError
さて、では別の構造型を持つ型の場合はどうなるのだろうか。
-```erg
+```python
i: Int or Str
j: Int or NoneType
ids(i, j) # ?
@@ -26,7 +28,7 @@ ids(i, j) # ?
これの説明を行う前に、Ergの型システムが実は(実行時の)クラスを見ていないという事実に注目しなくてはならない。
-```erg
+```python
1: {__valueclass_tag__ = Phantom Int}
2: {__valueclass_tag__ = Phantom Int}
2.0: {__valueclass_tag__ = Phantom Ratio}
@@ -43,7 +45,7 @@ ids(1, "a"): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phanto
さて、別の構造型の例に戻ろう。結論から言うと上のコードは型があっていないとしてTypeErrorになる。
しかし型注釈で型拡大を行えばコンパイルが通る。
-```erg
+```python
i: Int or Str
j: Int or NoneType
ids(i, j) # TypeError: types of i and j not matched
@@ -67,7 +69,7 @@ ids(i, j) # OK
Ergでは、戻り値型が一致しない場合デフォルトでエラーとなる。
-```erg
+```python
parse_to_int s: Str =
if not s.is_numeric():
do parse_to_int::return error("not numeric")
@@ -81,7 +83,7 @@ parse_to_int s: Str =
これを解決するためには、戻り値型を明示的にOr型と指定する必要がある。
-```erg
+```python
parse_to_int(s: Str): Int or Error =
if not s.is_numeric():
do parse_to_int::return error("not numeric")
diff --git a/doc/JA/tips.md b/doc/JA/tips.md
index 85c326fd..868f76b0 100644
--- a/doc/JA/tips.md
+++ b/doc/JA/tips.md
@@ -1,5 +1,7 @@
# Tips
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tips.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
## エラーの表示言語を変えたい
各国語版のergをダウンロードしてください。
@@ -7,7 +9,7 @@
## レコードの特定の属性だけ可変化したい
-```erg
+```python
record: {.name = Str; .age = Nat; .height = CentiMeter}
{height; rest; ...} = record
mut_record = {.height = !height; ...rest}
@@ -17,7 +19,7 @@ mut_record = {.height = !height; ...rest}
Ergで同一スコープ内でのシャドーイングはできません。しかし、スコープが変われば定義しなおせるので、インスタントブロックを使うといいでしょう。
-```erg
+```python
# T!型オブジェクトを取得し、最終的にT型として変数へ代入
x: T =
x: T! = foo()
@@ -29,7 +31,7 @@ x: T =
ラッパークラスを作りましょう。これはいわゆるコンポジション(合成)と言われるパターンです。
-```erg
+```python
FinalWrapper = Class {inner = FinalClass}
FinalWrapper.
method self =
@@ -43,7 +45,7 @@ FinalWrapper.
`Singleton`を実装すると、クラスとインスタンスが同一視されます。
また、`Enum`を使うと、その選択肢となる型がリダイレクト属性として自動的に定義されます。
-```erg
+```python
Ok = Class Impl := Singleton
Err = Class Impl := Singleton
ErrWithInfo = Inherit {info = Str}
@@ -55,7 +57,7 @@ match! stat:
Status.ErrWithInfo::{info;} -> ...
```
-```erg
+```python
Status = Enum Ok, Err, ErrWithInfo
# is equivalent to
Status = Class Ok or Err or ErrWithInfo
@@ -69,7 +71,7 @@ Status.
method 1:
-```erg
+```python
arr = [...]
for! arr.iter().enumerate(start: 1), i =>
...
@@ -77,7 +79,7 @@ for! arr.iter().enumerate(start: 1), i =>
method 2:
-```erg
+```python
arr = [...]
for! arr.iter().zip(1..), i =>
...
@@ -88,12 +90,12 @@ for! arr.iter().zip(1..), i =>
`foo.er`の非公開APIは`foo.test.er`というモジュールでは特別にアクセス可能となります。
`foo.test.er`モジュールはインポートできないので、隠蔽性は保たれます。
-```erg
+```python
# foo.er
private x = ...
```
-```erg
+```python
# foo.test.er
foo = import "foo"
@@ -108,7 +110,7 @@ foo = import "foo"
属性をプライベートにして、ゲッタを定義するとよいでしょう。
-```erg
+```python
C = Class {v = Int!}
C::
inc_v!(ref! self) = self::v.inc!()
@@ -122,7 +124,7 @@ C.
引数をレコードで受け取ると良いでしょう。
-```erg
+```python
Point = {x = Int; y = Int}
norm: Point -> Int
diff --git a/doc/JA/tools/build.md b/doc/JA/tools/build.md
index 193be4cc..a50a68e8 100644
--- a/doc/JA/tools/build.md
+++ b/doc/JA/tools/build.md
@@ -1,5 +1,7 @@
# buildサブコマンド
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/build.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
buildサブコマンドでは、パッケージのビルドを行います。
デフォルトのビルドで行われる工程は、以下の通りです。
diff --git a/doc/JA/tools/env.md b/doc/JA/tools/env.md
index 030c373c..d4640d78 100644
--- a/doc/JA/tools/env.md
+++ b/doc/JA/tools/env.md
@@ -1,5 +1,7 @@
# envサブコマンド
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
envサブコマンドはerg実行環境の指定を行います。
`erg env new [env name]`で新しい実行環境を作成します。対話ツールが開き、ergのバージョンを指定すると、そのバージョンのergがインストール(すでにあれば流用されます)され、新しい環境として使えるようになります。
`erg env switch [env name]`で環境の切り替えができます。
diff --git a/doc/JA/tools/fmt.md b/doc/JA/tools/fmt.md
index adc6165c..1e16f02d 100644
--- a/doc/JA/tools/fmt.md
+++ b/doc/JA/tools/fmt.md
@@ -1,5 +1,7 @@
# fmt
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/fmt.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
fmtサブコマンドででコードフォーマットが出来ます。
よく使用されるフラッグは以下の通りです。
diff --git a/doc/JA/tools/index.md b/doc/JA/tools/index.md
index e69de29b..f08300dc 100644
--- a/doc/JA/tools/index.md
+++ b/doc/JA/tools/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/JA/tools/install.md b/doc/JA/tools/install.md
index d8a1cc8f..b5532756 100644
--- a/doc/JA/tools/install.md
+++ b/doc/JA/tools/install.md
@@ -1,5 +1,7 @@
# installサブコマンド
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/install.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
installでレジストリサイトに登録されたパッケージをインストールできる。
基本的な使い方はcargoなどのパッケージマネージャと同じ。
diff --git a/doc/JA/tools/pack.md b/doc/JA/tools/pack.md
index 0363fd0e..9d8cc522 100644
--- a/doc/JA/tools/pack.md
+++ b/doc/JA/tools/pack.md
@@ -1,5 +1,7 @@
# パッケージマネージャー
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/pack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
Ergは標準でパッケージマネージャーが付属しており、`pack`サブコマンドで呼び出せる。
以下は典型的なオプションである。
@@ -34,7 +36,7 @@ Ergは標準でパッケージマネージャーが付属しており、`pack`
`erg pack init`すると以下のようなファイル、`package.er`が生成される。`package.er`にはパッケージの設定を記述する。
以下は`package.er`の記述例である。
-```erg
+```python
name = "example" # package name
author = "John Smith" # package author name
version = "0.1.0"
diff --git a/doc/JA/tools/repl.md b/doc/JA/tools/repl.md
index 87969a48..69997b88 100644
--- a/doc/JA/tools/repl.md
+++ b/doc/JA/tools/repl.md
@@ -1,5 +1,7 @@
# REPL
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/repl.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
`erg`コマンドを引数を与えず実行すると、REPLが起動されます。また、`repl`サブコマンドを指定して起動することもできます。
さらに以下のフラグを指定できます。
diff --git a/doc/JA/tools/test.md b/doc/JA/tools/test.md
index c2264c05..82e7faef 100644
--- a/doc/JA/tools/test.md
+++ b/doc/JA/tools/test.md
@@ -1,5 +1,7 @@
# testサブコマンド
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/test.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
ergコマンドにはtestというサブコマンドがあり、テスト実装、及び実行の支援を行う。
## Testデコレータ(@Test)
@@ -7,7 +9,7 @@ ergコマンドにはtestというサブコマンドがあり、テスト実装
Ergではパッケージ中の`tests`ディレクトリか`*.test.er`ファイル中の`@Test`を付けたサブルーチンを`erg test`コマンドでテストする。
`tests`のサブルーチンはブラックボックステスト(非公開関数をテストしない)、`*.test.er`のサブルーチンはホワイトボックステスト(非公開関数もテストする)を担当する。
-```erg
+```python
# tests/test1.er
{add; ...} = import "foo"
@@ -24,12 +26,12 @@ Ergでは`#`, `#[`以降がコメント行となるが、`##`, `#[[`でdoc comme
さらにdoc comment中のソースコードはergと指定されていれば、erg testコマンドで自動テストされる。
以下はテストの例である。
-```erg
+```python
VM = ...
...
#[[
execute commands.
- ```erg
+ ```python
# VM in standard configuration
{vm1; ...} = import "tests/mock"
diff --git a/doc/zh_CN/API/consts.md b/doc/zh_CN/API/consts.md
new file mode 100644
index 00000000..93936329
--- /dev/null
+++ b/doc/zh_CN/API/consts.md
@@ -0,0 +1,15 @@
+# 内置常量
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/consts.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## True
+
+## False
+
+## None
+
+## Ellipsis
+
+## NotImplemented
+
+## Inf
diff --git a/doc/zh_CN/API/funcs.md b/doc/zh_CN/API/funcs.md
new file mode 100644
index 00000000..25f57506
--- /dev/null
+++ b/doc/zh_CN/API/funcs.md
@@ -0,0 +1,123 @@
+# 功能
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/funcs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 基本功能
+
+### if|T; U|(cond: Bool, then: T, else: U) -> T or U
+
+### map|T; U|(i: Iterable T, f: T -> U) -> Map U
+
+请注意,参数的顺序与 Python 相反
+
+### log(x: Object, type: LogType = Info) -> None
+
+在调试显示中记录“x”。 执行完成后汇总并显示日志
+支持表情符号的终端根据“类型”添加前缀
+
+* type == Info: 💬
+* type == Ok: ✅
+* type == Warn: ⚠️
+* type == Hint: 💡
+
+### panic(msg: Str) -> Panic
+
+显示msg并停止。
+支持表情符号的终端有一个🚨前缀。
+
+### discard|T|(x: ...T) -> NoneType
+
+扔掉`x`。不使用返回值时使用。与 `del` 不同,它不会使变量 `x` 不可访问
+
+```python
+p! x =
+ # q!应该返回一些不是None或()的值
+ # 如果不需要,请使用`discard`
+ discard q!(x)
+ f x
+
+discard True
+assert True # OK
+```
+
+### import(path: Path) -> Module or CompilerPanic
+
+导入一个模块。如果找不到模块,则引发编译错误
+
+### eval(code: Str) -> Object
+
+将`code`作为代码进行评估并返回。
+
+### classof(object: Object) -> Class
+
+返回`object`的类。
+但是,由于无法比较类,如果要判断实例,请使用`object in Class`而不是`classof(object) == Class`
+编译时确定的结构类型是通过`Typeof`获得的
+
+## Iterator, Array生成系统
+
+### repeat|T|(x: T) -> RepeatIterator T
+
+```python
+rep = repeat 1 # Repeater(1)
+for! rep, i =>
+ print! i
+# 1 1 1 1 1 ...
+```
+
+### dup|T; N|(x: T, N: Nat) -> [T; N]
+
+```python
+[a, b, c] = dup new(), 3
+print! a #
+print! a == b # False
+```
+
+### cycle|T|(it: Iterable T) -> CycleIterator T
+
+```python
+cycle([0, 1]).take 4 # [0, 1, 0, 1]
+cycle("hello").take 3 # "hellohellohello"
+```
+
+## 定数式関数
+
+### Class
+
+创建一个新类。 与`Inherit`不同,通过`Class`传递与基类型无关,并且方法会丢失
+您将无法进行比较,但您可以进行模式匹配等操作
+
+```python
+C = Class {i = Int}
+NewInt = Class Int
+Months = Class 1..12
+jan = Months.new(1)
+jan + Months.new(2) # TypeError: `+` is not implemented for 'Months'
+match jan:
+ 1 -> log "January"
+ _ -> log "Other"
+```
+
+第二个参数 Impl 是要实现的特征
+
+### Inherit
+
+继承一个类。您可以按原样使用基类方法
+
+### Trait
+
+创造一个新的特质。目前,只能指定记录类型
+
+### Typeof
+
+返回参数类型。如果要获取运行时类,请使用`classof`。
+如果您将其用于类型规范,则会出现警告。
+
+```python
+x: Typeof i = ...
+# TypeWarning: Typeof(i) == Int, please replace it
+```
+
+### Deprecated
+
+作为解码器使用。警告不推荐使用的类型或函数
\ No newline at end of file
diff --git a/doc/zh_CN/API/index.md b/doc/zh_CN/API/index.md
new file mode 100644
index 00000000..77223195
--- /dev/null
+++ b/doc/zh_CN/API/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/API/modules/external/alstruct.md b/doc/zh_CN/API/modules/external/alstruct.md
new file mode 100644
index 00000000..bf8dd4f5
--- /dev/null
+++ b/doc/zh_CN/API/modules/external/alstruct.md
@@ -0,0 +1,59 @@
+# 结构
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/external/alstruct.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+模块为它们提供代表代数结构和补丁的特征
+
+* 成员
+
+## 二进制运算
+
+```python
+BinOp Op: Kind 2 = Subsume Op(Self, Self.ReturnTypeOf Op), Additional: {
+ .ReturnTypeof = TraitType -> Type
+}
+
+Nat <: BinOp Add
+assert Nat. ReturnTypeof(Add) == Nat
+assert Nat. ReturnTypeof(Sub) == Int
+assert Nat. ReturnTypeof(Mul) == Nat
+assert Nat.ReturnTypeof(Div) == Positive Ratio
+```
+
+## 半群(一个二元运算的代数系统)
+
+```python
+SemiGroup Op: Kind 2 = Op(Self, Self)
+
+IntIsSemiGroupAdd = Patch Int, Impl=SemiGroupAdd
+
+Int <: SemiGroup Add
+```
+
+## 函子
+
+```python
+# * Identity law: x.map(id) == x
+# * Composition law: x.map(f).map(g) == x.map(f.then g)
+Functor = Trait {
+ .map|T, U: Type| = (Self(T), T -> U) -> Self U
+}
+```
+
+## 应用
+
+```python
+# * Identity law: x.app(X.pure(id)) == x
+Applicative = Subsume Functor, Additional: {
+ .pure|T: Type| = T -> Self T
+ .app|T, U: Type| = (Self(T), Self(T -> U)) -> Self U
+}
+```
+
+## 单子(交互式命令行工具以及面向对象的脚本技术)
+
+```python
+Monad = Subsume Applicative, Additional: {
+ .bind|T, U: Type| = (Self(T), T -> Self U) -> Self U
+}
+```
\ No newline at end of file
diff --git a/doc/zh_CN/API/modules/repl.md b/doc/zh_CN/API/modules/repl.md
new file mode 100644
index 00000000..9e87ca63
--- /dev/null
+++ b/doc/zh_CN/API/modules/repl.md
@@ -0,0 +1,26 @@
+# 模块`repl`
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/repl.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+提供REPL(Read-Eval-Print-Loop)相关的API。
+
+## 功能
+
+* `gui_help`
+
+在浏览器中查看有关对象的信息。 可以离线使用。
+
+## 类型
+
+### 猜测 = 对象
+
+#### 方法
+
+* `.guess`
+
+在给定参数和返回值的情况下推断函数。
+
+```python
+1.guess((1,), 2) #
+[1, 2].guess((3, 4), [1, 2, 3, 4]) #
+```
\ No newline at end of file
diff --git a/doc/zh_CN/API/modules/status.md b/doc/zh_CN/API/modules/status.md
new file mode 100644
index 00000000..b6750b75
--- /dev/null
+++ b/doc/zh_CN/API/modules/status.md
@@ -0,0 +1,8 @@
+ # 模块`status`
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/status.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+定义了一个类型来表示状态。请根据情况删除选项来使用它
+
+* ExecResult = {"success", "warning", "failure", "fatal", "unknown"}
+* ExecStatus = {"ready", "running", "sleeping", "plague", "completed", "terminated"}
\ No newline at end of file
diff --git a/doc/zh_CN/API/modules/unit.md b/doc/zh_CN/API/modules/unit.md
new file mode 100644
index 00000000..62b52bb3
--- /dev/null
+++ b/doc/zh_CN/API/modules/unit.md
@@ -0,0 +1,74 @@
+# 模块`unit`
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unit.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`unit` 模块是将数值计算中经常使用的单位定义为类型的模块。
+Erg 数值类型包括 `Nat`、`Int`、`Ratio` 等。但是,这些类型没有关于“数字的含义”的信息,因此可以执行诸如添加米和码之类的无意义计算。
+通过使用 `unit` 模块,您可以避免错误,例如将不同单位的数字传递给函数。
+这样的错误确实会发生,并且会导致诸如[由于错误的单位系统导致火星探测器丢失](http://www.sydrose.com/case100/287/)之类的严重错误。
+如果您希望代码在进行数值计算时更加健壮,您应该使用此模块。
+
+```python
+{*} = import "unit"
+
+x = 6m # 相当于 `x = Meter.new(6)`
+t = 3s # 相当于 `t = Sec.new(3)`
+#m/s是速度单位对象,类型为velocity
+print! x/t # 2m/s
+print! x + 4m # 10m
+print! x + 2s # 类型错误: `+`(Meter, Sec) 未实现
+```
+对象`m`、`s`和`m/s`被称为单元对象。它本身具有1m、1s、1m/s的含义。 `m/s`可以说是结合m和s创建的单位对象。
+
+在单元中,以下单元被定义为类型。它被称为SI(国际单位制)。
+
+* 长度:Meter(单位常数:m)
+* 质量:KiloGram(单位常数:kg,g = 0.001kg)
+* 时间:Sec(分、时、日、年等有分、时、日、年等常量由秒生成)
+* 电流:Amper(单位常数:a)
+* 温度:Kelvin(单位常数:k。华氏、摄氏度类型也可用,可相互转换)
+* 物质量:Mol(单位常数:mol)
+* 发光强度:Candela(单位常数:cd)
+
+此外,还定义了`Unit1`、`UnitMul`和`UnitDiv`类型,可以通过组合基本类型来创建新的单元。
+例如`UnitDiv(Unit1, Sec)`,因为频率单位赫兹(hertz)被定义为振动周期(秒)的倒数。
+如果要将此类型视为有意义的类型(例如添加专用方法),则应创建 [patch](./../../syntax/type/07_patch.md)。
+
+```python
+Hertz = Patch UnitDiv(Unit1, Sec)
+SquareMeter = Patch UnitMul(Meter, Meter)
+```
+
+一些辅助单元也是预定义的:
+
+* 频率: Hertz(hz)
+* 力: Newton(newton)
+* 能量: Joule(j)
+* 功率: Watt(w)
+* 电压: Volt(v)
+* 电阻: Ohm(ohm)
+* 速度: Velocity(m/s)
+* 面积: SquareMeter(m^2)
+* 体积: CubicMeter(m^3) (liter = 10e-3 m^3)
+* 角度: Degree(deg) (rad = 180/pi deg)
+* 长度: Feet, Yard, Inch, Mile, Ly, Au, Angstrom
+* 重量: Pound
+
+它还定义了一个前缀:
+
+* Femto = 1e-15
+* Pico = 1e-12
+* Nano = 1e-9
+* Micro = 1e-6
+* Milli = 1e-3
+* Centi = 1e-2
+* Deci = 1e-1
+* Hecto = 1e+2
+* Kilo = 1e+3
+* Mega = 1e+6
+* Giga = 1e+9
+* Tera = 1e+12
+* Peta = 1e+15
+* Exa = 1e+18
+
+* 与名字的由来相反,Erg基本采用MKS单位制。如果需要 CGS 单位制的单位模块,请使用外部库[cgs](https://github.com/mtshiba/cgs)等)。
\ No newline at end of file
diff --git a/doc/zh_CN/API/modules/unsound.md b/doc/zh_CN/API/modules/unsound.md
new file mode 100644
index 00000000..bfea9285
--- /dev/null
+++ b/doc/zh_CN/API/modules/unsound.md
@@ -0,0 +1,26 @@
+# 模块 `unsound`
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unsound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+让 API 执行在 Erg 的类型系统中无法保证的不健全和不安全的操作。
+
+## `unsafe!`
+
+执行“不安全”过程。 就像 Rust 一样,`Unsafe` API 不能直接调用,而是作为高阶函数传递给这个过程。
+
+```python
+unsound = import "unsound"
+
+i = unsound. unsafe! do!:
+ # 将 `Result Int` 转换为 `Int`
+ unsound.transmute input!().try_into(Int), Int
+```
+
+## transmit
+
+将第一个参数的对象转换为第二个参数的类型。没有进行类型检查。
+这个函数破坏了类型系统的类型安全。请在使用前进行验证。
+
+## 隐式转换
+
+与 `transmute` 不同,它会自动转换为预期的类型。与 Ocaml 的 `Obj.magic` 工作方式相同。
\ No newline at end of file
diff --git a/doc/zh_CN/API/operators.md b/doc/zh_CN/API/operators.md
new file mode 100644
index 00000000..e8086f5f
--- /dev/null
+++ b/doc/zh_CN/API/operators.md
@@ -0,0 +1,66 @@
+# 操作员
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/operators.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## 中缀运算符
+
+### `_+_`|R; O; A <: Add(R, O)|(x: A, y: R) -> O
+
+执行加法。
+
+### `_-_`|R; O; S <: Sub(R, O)|(x: S, y: R) -> O
+
+执行减法。
+
+### `*`|R; O; M <: Mul R, O|(x: M, y: R) -> O
+
+执行乘法。
+
+### `/`|R; O; D <: Div(R, O)|(x: D, y: R) -> O
+
+进行除法。
+
+## 中缀字母运算符
+
+### `and`(x: Bool, y: Bool) -> Bool
+
+执行 and 操作。
+
+### `or`(x: Bool, y: Bool) -> Bool
+
+执行 and 操作。
+
+## 前缀运算符
+
+### `+_`|T <: Num|(x: T) -> T
+
+默认与 id 相同。
+
+### `-_`|T <: Num|(x: T) -> T.Neg
+
+例如 Nat.`-`: Nat -> Neg 和返回值不同。
+
+### `!`|T <: Immut|(x: T) -> `T!`
+
+从不可变对象创建可变对象。
+该运算符本身不是程序性的,可以在函数内部使用。
+
+### `..`|T <: Ord|(x: T) -> Range T
+
+在 x 的末尾创建一个没有下限的 Range 对象。
+x..x 仅返回 x 作为迭代器。
+
+### `..<`|T <: Ord|(x: T) -> Range T
+
+x.. Range T
+
+创建一个从 x 开始没有上限的 Range 对象。
+
+### |T <: Ord|(x: T)`<..` -> Range T
\ No newline at end of file
diff --git a/doc/zh_CN/API/procs.md b/doc/zh_CN/API/procs.md
new file mode 100644
index 00000000..96bcfa6e
--- /dev/null
+++ b/doc/zh_CN/API/procs.md
@@ -0,0 +1,41 @@
+# 过程
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/procs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## print!
+
+```python
+打印!(x)->无类型
+```
+
+ 使用换行符返回 x。
+
+## 调试&排除;
+
+```python
+调试!(x,类型=信息)-> NoneType
+```
+
+用换行符调试 x(文件名、行号、变量名一起显示)。 在发布模式中删除。
+支持表情符号的终端根据类型加前缀。
+
+* type == Info: 💬
+* type == Ok: ✅
+* type == Warn: ⚠️
+* type == Hint: 💡
+
+## for!i: Iterable T, block: T => NoneType
+
+以块的动作遍历迭代器。
+
+## while!cond: Bool!, block: () => NoneType
+
+当cond为True时的执行块。
+
+## Lineno!() -> Nat
+
+## Filename!() -> Str
+
+## Namespace!() -> Str
+
+## Module!() -> Module
\ No newline at end of file
diff --git a/doc/zh_CN/API/special.md b/doc/zh_CN/API/special.md
new file mode 100644
index 00000000..0d164838
--- /dev/null
+++ b/doc/zh_CN/API/special.md
@@ -0,0 +1,177 @@
+# 特殊形式
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+特殊形式是不能在 Erg 类型系统中表达的运算符、子程序(等等)。它被`包围,但实际上无法捕获。
+此外,为方便起见,还出现了“Pattern”、“Body”和“Conv”等类型,但不存在此类类型。它的含义也取决于上下文。
+
+## `=`(pat: Pattern, body: Body) -> NoneType
+
+将 body 分配给 pat 作为变量。如果变量已存在于同一范围内或与 pat 不匹配,则引发错误。
+它还用于记录属性定义和默认参数。
+
+```python
+record = {i = 1; j = 2}
+f(x: Int, y = 2) = ...
+```
+
+当主体是类型或函数时,`=` 具有特殊行为。
+左侧的变量名嵌入到右侧的对象中。
+
+```python
+print! Class() # >
+print! x: Int -> x + 1 # >
+C = Class()
+print! c #
+f = x: Int -> x + 1
+print! f #
+g x: Int = x + 1
+print! g #
+K X: Int = Class(...)
+print! K #
+L = X: Int -> Class(...)
+print! L #
+```
+
+`=` 运算符的返回值为“未定义”。
+函数中的多个赋值和 `=` 会导致语法错误。
+
+```python
+i = j = 1 # SyntaxError: 不允许多次赋值
+print!(x=1) # SyntaxError: cannot use `=` in function arguments
+# 提示:您的意思是关键字参数(`x: 1`)吗?
+if True, do:
+ i = 0 # SyntaxError: 块不能被赋值表达式终止
+```
+
+## `->`(pat: Pattern, body: Body) -> Func
+
+生成匿名函数,函数类型。
+
+## `=>`(pat: Pattern, body: Body) -> Proc
+
+生成匿名过程,过程类型。
+
+## `:`(subject, T)
+
+确定主题是否与 T 匹配。如果它们不匹配,则抛出编译错误。
+
+```python
+a: Int
+f x: Int, y: Int = x / y
+```
+
+也用于 `:` 应用样式。
+
+```python
+f x:
+ y
+ z
+```
+
+像`:`和`=`一样,运算的结果是不确定的。
+
+```python
+_ = x: Int # 语法错误:
+print!(x: Int) # 语法错误:
+```
+
+## `.`(obj, attr)
+
+读取obj的属性。
+`x.[y, z]` 将 x 的 y 和 z 属性作为数组返回。
+
+## `|>`(obj, c: Callable)
+
+执行`c(obj)`。 `x + y |>.foo()` 与 `(x + y).foo()` 相同。
+
+### (x: Option T)`?` -> T | T
+
+后缀运算符。如果出现错误,请立即调用 `x.unwrap()` 和 `return`。
+
+## match(obj, ...lambdas: Lambda)
+
+对于 obj,执行与模式匹配的 lambda。
+
+```python
+match [1, 2, 3]:
+ (l: Int) -> log "this is type of Int"
+ [[a], b] -> log a, b
+ [...a] -> log a
+# (1, 2, 3)
+```
+
+## del(x: ...T) -> NoneType | T
+
+删除变量“x”。但是,无法删除内置对象。
+
+```python
+a = 1
+del a # OK
+
+del True # SyntaxError: cannot delete a built-in object
+```
+
+## do(body: Body) -> Func
+
+生成一个不带参数的匿名函数。 `() ->` 的语法糖。
+
+## do!(body: Body) -> Proc
+
+生成不带参数的匿名过程。 `() =>` 的语法糖。
+
+## `else`(l, r) -> Choice
+
+创建一个由两对组成的类元组结构,称为 Choice 对象。
+`l, r` 被懒惰地评估。也就是说,只有在调用 .get_then 或 .get_else 时才会计算表达式。
+
+```python
+choice = 1 else 2
+assert choice.get_then() == 1
+assert choice.get_else() == 2
+assert True.then(choice) == 1
+```
+
+## 集合运算符
+
+### `[]`(...objs)
+
+从参数创建一个数组或从可选参数创建一个字典。
+
+### `{}`(...objs)
+
+从参数创建一个集合。
+
+### `{}`(...fields: ((Field, Value); N))
+
+生成记录。
+
+### `{}`(layout, ...names, ...preds)
+
+生成筛型,等级2型。
+
+### `...`
+
+展开嵌套集合。它也可以用于模式匹配。
+
+```python
+[x, ...y] = [1, 2, 3]
+assert x == 1 and y == [2, 3]
+assert [x, ...y] == [1, 2, 3]
+assert [...y, x] == [2, 3, 1]
+{x; ...yz} = {x = 1; y = 2; z = 3}
+assert x == 1 and yz == {y = 2; z = 3}
+assert {x; ...yz} == {x = 1; y = 2; z = 3}
+```
+
+## 虚拟运算符
+
+用户不能直接使用的运算符。
+
+### ref(x: T) -> Ref T | T
+
+返回对对象的不可变引用。
+
+### ref!(x: T!) -> Ref!T! | T!
+
+返回对可变对象的可变引用。
\ No newline at end of file
diff --git a/doc/zh_CN/API/types.md b/doc/zh_CN/API/types.md
new file mode 100644
index 00000000..e4f25143
--- /dev/null
+++ b/doc/zh_CN/API/types.md
@@ -0,0 +1,264 @@
+# 内置 Erg 类型列表
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+类型本身的属性不存储在 `.__dict__` 中,不能从实例中引用
+
+## 基本类型
+
+### 对象
+
+* `__dir__`:将对象的属性作为数组返回(dir函数)
+* `__getattribute__`: 获取并返回一个属性
+* `__hash__`:返回对象的哈希值
+* `__repr__`:对象的字符串表示(不存在丰富/默认实现)
+* `__sizeof__`:返回对象的大小(包括在堆中分配的大小)
+
+### 显示
+
+* `__str__`:返回对象的字符串表示(丰富)
+
+### Fmt
+
+* `__format__`: 返回一个格式化的字符串
+
+### 文档
+
+* `__doc__`:对象描述
+
+### 命名
+
+* `__name__`: 对象的名称
+
+### 泡菜
+
+* `__reduce__`: 用 Pickle 序列化对象
+* `__reduce_ex__`: __reduce__ 允许你指定协议版本
+
+## 对象系统
+
+Trait 类相当于 Python 中的 ABC(抽象基类,接口)
+实例属于1、True、“aaa”等。
+类是 Int、Bool、Str 等。
+
+### 类型
+
+* `__父类__`:超类型(`__mro__` 是一个数组,但这个是一个 Set)
+* `__basicsize__`:
+* `__dictoffset__`:Evm 不支持
+* `__flags__`:
+* `__itemsize__`:实例的大小(如果不是类,则为 0)
+* `__weakrefoffset__`:Evm 不支持
+* `__membercheck__`: 相当于`ismember(x, T)`
+* `__subtypecheck__`:等价于`issubtype(U, T)`,别名`__subclasshook__`(兼容CPython)
+
+### 实例
+
+* `__class__`:返回创建实例的类(自动附加到使用 `.new` 创建的对象)
+
+### Class
+
+* `__mro__`:用于方法解析的类型数组(包括自身,始终以 Object 结尾)
+* `__base__`:基本类型(`__mro__[1]` 如果有多个)
+* `__new__`: 实例化
+* `__init__`: 初始化实例
+* `__init_subclass__`: 初始化实例
+* `__intstancecheck__`:使用类似于 `MyClass.__instancecheck__(x)`,等价于 `isinstance(x, MyClass)`
+* `__subclasscheck__`:等价于 `issubclass(C, MyClass)`
+
+## 运算符
+
+此处指定以外的运算符没有特殊类型
+
+### 方程
+
+* `__eq__(self, rhs: Self) -> Bool`: 对象比较函数 (==)
+* `__ne__`: 对象比较函数 (!=),默认实现
+
+### 秩序
+
+* `__lt__(self, rhs: Self) -> Bool`: 对象比较函数 (<)
+* `__le__`:对象比较函数(<=),默认实现
+* `__gt__`:对象比较函数(>),默认实现
+* `__ge__`:对象比较函数(>=),默认实现
+
+### BinAdd
+
+* 实现 `__add__(self, rhs: Self) -> Self`: `+`
+
+### 添加R
+
+* `__add__(self, rhs: R) -> Self.AddO`
+
+### Sub R
+
+* `__sub__(self, rhs: R) -> Self.SubO`
+
+### Mul R
+
+* `__mul__(self, rhs: R) -> Self.MulO`
+
+### BinMul <: Mul Self
+
+* `__pow__`:实现 `**`(默认实现)
+
+### Div R, O
+
+* 实现 `__div__(self, rhs: Self) -> Self`: `/`,可能会因为 0 而恐慌
+
+### BinDiv <: Div Self
+
+* `__mod__`: 实现 `%` (默认实现)
+
+## 数值型
+
+### Num (= Add and Sub and Mul and Eq)
+
+例如,除了Complex,Vector、Matrix和Tensor都是Num(Matrix和Tensor中的*分别与dot和product相同)
+
+### Complex (= Inherit(Object, Impl := Num))
+
+* `imag: Ratio`:返回虚部
+* `real: Ratio`:返回实部
+* `conjugate self -> Complex`:返回复共轭
+
+### Float (= Inherit(FloatComplex, Impl := Num))
+
+### Ratio (= Inherit(Complex, Impl := Num))
+
+* `numerator: Int`: 返回分子
+* `denominator: Int`: 返回分母
+
+### Int (= Inherit Ratio)
+
+### Nat (= Inherit Int)
+
+* `times!`: 运行 proc self 时间
+
+## 其他基本类型
+
+### 布尔值
+
+* `__and__`:
+* `__or__`:
+* `not`:
+
+## 字符串 (<: 序列)
+
+* `capitalize`
+* `chomp`: 删除换行符
+* `isalnum`:
+* `isascii`:
+* `isalpha`:
+* `isdecimal`:
+* `isdight`:
+* `isidentifier`
+* `islower`
+* `isnumeric`
+* `isprintable`
+* `isspace`
+* `istitle`
+* `isupper`
+* `lower`
+* `swapcase`
+* `title`
+* `upper`
+
+## 其他
+
+### 位
+
+* `from_bytes`:从字节转换
+* `to_bytes`:转换为字节(指定长度和字节序(字节序))
+* `bit_length`:返回位长度
+
+### 可迭代 T
+
+请注意,它不是 `Iterator` 本身的类型。 `Nat` 是 `Iterable` 但你不能 `Nat.next()`,你需要 `Nat.iter().next()`。
+
+* `iter`:创建一个迭代器。
+
+### 迭代器 T
+
+Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter().fold (sum, n) -> sum + n*2`等是可能的。
+由于所有和任何在使用后都会被破坏,因此没有副作用。这些应该使用没有副作用的 `next` 来实现,但内部使用 `Iterator!.next!` 来提高执行效率。
+
+* `next`:返回第一个元素和剩余的迭代器。
+* `all`
+* `any`
+* `filter`
+* `filter_map`
+* `find`
+* `find_map`
+* `flat_map`
+* `flatten`
+* `fold`
+* `for_each`
+* `map`
+* `map_while`
+* `nth`
+* `pos`
+* `take`
+* `unzip`
+* `zip`
+
+### Iterator!T = IteratorT 和 ...
+
+* `next!`:获取第一个元素。
+
+## SizedIterator T = 迭代器 T 和 ...
+
+有限数量元素的迭代器。
+
+* `len`:
+* `chain`:
+* `count`:
+* `is_empty`:
+* `rev`:
+* `next_back`:
+* `nth_back`:
+* `rfind`:
+* `rfold`:
+* `sum`:
+* `max`:
+* `min`:
+
+## Seq T = SizedIterable T 和 ...
+
+* `concat`: 合并两个 Seq
+* `__getitem__`:等同于使用 `[]` 访问(否则会出现恐慌)
+* 与 `get`: __getitem__ 不同,它返回 Option
+* `maketrans`:创建替换表(静态方法)
+* `replace`: 替换
+* `translate`:根据替换表替换
+* `insert`: 添加到 idx
+* `remove`: 删除 idx
+* `prepend`: 前置
+* `dequeue`: 移除头部
+* `push`:添加到末尾
+* `pop`: 取尾巴
+* `dedup`:删除连续值
+* `uniq`:删除重复元素(通过 sort |> dedup 实现,因此顺序可能会改变)
+* `swap`:交换元素
+* `reverse`:反转元素
+* `sort`: 排序元素
+* `first`:
+* `last`:
+
+### Seq!T (= Seq T and ...)
+
+* `__setitem__!`:
+* `__delitem__!`:
+* `插入!`:添加到 idx
+* `remove!`: 删除 idx
+* `prepend!`:前置
+* `dequeue!`: 删除开头
+* `push!`:添加到末尾
+* `pop!`:拿尾巴
+* `dedup!`:删除连续值
+* `uniq!`: 删除重复元素(通过排序实现!|> dedup!,因此顺序可能会改变)
+* `swap!`:交换元素
+* `reverse!`:反转元素
+* `set!`
+* `sort!`: 排序元素
+* `translate!`
\ No newline at end of file
diff --git a/doc/zh_CN/API/types/classes/Array!(T).md b/doc/zh_CN/API/types/classes/Array!(T).md
new file mode 100644
index 00000000..e89d474b
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Array!(T).md
@@ -0,0 +1,5 @@
+# Array! T
+
+[.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array!(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示可变长度数组的类型。在编译时长度未知时使用。 有一个语法糖叫做` [t]!`。在`Array! T = ArrayWithMutLength! T, !_`中被定义
\ No newline at end of file
diff --git a/doc/zh_CN/API/types/classes/Array(T).md b/doc/zh_CN/API/types/classes/Array(T).md
new file mode 100644
index 00000000..e8e7c3e9
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Array(T).md
@@ -0,0 +1,5 @@
+# Array T: Type
+
+[.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+由`Array T = ArrayWithLen T, _`定义。 有一种语法糖叫做`[T]`。
\ No newline at end of file
diff --git a/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md b/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md
new file mode 100644
index 00000000..012c97b5
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md
@@ -0,0 +1,36 @@
+# ArrayWithLen T: Type, N: Nat
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithLen(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`[T; N]`是语法糖。还有一个[`Array` 类型](./Array.md)省略了长度。
+
+## 方法
+
+* values_at(self, selectors: [Nat; N]) -> [T; N]
+
+```python
+assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"]
+```
+
+* all(self, pred: T -> Bool) -> Bool
+ 返回是否所有元素都满足 pred。
+ 如果元素为 0,则无论 pred 为 `True`,但会发出警告。
+ 该规范本身已被多种语言采用,是逻辑一致性所必需的。
+
+ ```python
+ assert [].all(_ -> False)
+ ```
+
+ ```python
+ assert all(False for _ in [])
+ ```
+
+## ArrayWithLen T, N | T <: Eq 的方法
+
+* freq self -> [{T: Nat}]
+ 返回对象出现的次数。
+
+```python
+assert ["a", "b", "c", "b", "c", "b"].freq() \
+== [{"a", 1}, {"b": 3}, {"c": 2}]
+```
diff --git a/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md
new file mode 100644
index 00000000..848c5047
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md
@@ -0,0 +1,28 @@
+# ArrayWithMutLength! T: Type, N: Nat!
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+一个可变长度数组,其长度在编译时已知。还有语法糖`ArrayWithMutLength(T, !N) == [T; !N]`
+
+## 方法
+
+* push! ref! self(N ~> N+1, ...), elem: T
+
+* pop! ref! (N ~> N-1, ...) -> T
+
+* sample!(ref! self) -> T
+* sample! ref! self, M: Nat -> [T; M]
+ 随机选择里面的一个元素并返回一个副本
+
+* shuffle!(ref! self)
+ 把里面的东西随机摆放
+
+* assert_len ref! self(_ ~> N, ...), N: Nat -> () or Panic
+ 验证长度。
+ `panic!` 如果长度无效。
+
+## Impl
+
+* From Range Int
+* From [T; N]
+* Num
diff --git a/doc/zh_CN/API/types/classes/Class.md b/doc/zh_CN/API/types/classes/Class.md
new file mode 100644
index 00000000..8cad7741
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Class.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Class.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/API/types/classes/Complex.md b/doc/zh_CN/API/types/classes/Complex.md
new file mode 100644
index 00000000..6356d002
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Complex.md
@@ -0,0 +1,16 @@
+# Complex
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Complex.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示复数的类型。在 Erg 中表示数字的类型,例如 Float、Int和Nat,通常派生于Complex
+
+## 父类
+
+Num 和 Norm
+
+## 方法
+
+* abs
+* conjugate
+* imag
+* real
diff --git a/doc/zh_CN/API/types/classes/Dict!.md b/doc/zh_CN/API/types/classes/Dict!.md
new file mode 100644
index 00000000..01405abd
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Dict!.md
@@ -0,0 +1,9 @@
+# Dict! K, V
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Dict!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示字典(哈希Map)的类型。 有一个语法糖叫做`{K: V}`
+
+## 方法
+
+* invert!(self) -> Self! V, K
diff --git a/doc/zh_CN/API/types/classes/Either.md b/doc/zh_CN/API/types/classes/Either.md
new file mode 100644
index 00000000..71b10f77
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Either.md
@@ -0,0 +1,14 @@
+# Either L, R = L or R
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Either.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示L或R的类型。 您可以将其视为Or类型的二元形式
+
+## 方法
+
+* orl
+* orr
+* andl
+* andr
+* mapl
+* mapr
diff --git a/doc/zh_CN/API/types/classes/Float.md b/doc/zh_CN/API/types/classes/Float.md
new file mode 100644
index 00000000..d4969334
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Float.md
@@ -0,0 +1,23 @@
+# Float size
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Float.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示实数(包含小数的数)的类型。符合IEEE 754的浮点数,在其他语言中一般是float的类型。
+Float的大小为8(1byte)~128(16byte)。如果只是Float,则表示`Float64`。
+Erg 中的 0.1 实际上属于 Ratio 类型,而不是 Float 类型。没有浮点类型字面量,它是由 `(Ratio object)f64` 生成的(例如 (1/2)f64, 15f64)。 f64 对应实数 1
+
+## 父类
+
+Complex 和 Ord
+
+## 方法
+
+* sgn(self) -> {-1, 0, 1}
+ 返回标志
+
+* truncate(self) -> Int
+ 返回最接近自身的整数
+
+* separate(self) -> [Str]
+* separate(self, dight: Nat) -> [Str]
+ 按digit位数划分。没有自变量
diff --git a/doc/zh_CN/API/types/classes/Function(N).md b/doc/zh_CN/API/types/classes/Function(N).md
new file mode 100644
index 00000000..08d6b7b0
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Function(N).md
@@ -0,0 +1,11 @@
+# Function N: Nat
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Function(N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## Function 1 的方法
+
+* then(self, g: Self) -> Self
+
+```python
+assert f(g(x)) == f.then(g) x
+```
diff --git a/doc/zh_CN/API/types/classes/Inf.md b/doc/zh_CN/API/types/classes/Inf.md
new file mode 100644
index 00000000..006ff76c
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Inf.md
@@ -0,0 +1,9 @@
+# Inf
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Inf.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+Inf是一个类,其唯一实例是inf。
+inf的主要用途是用于区间类型。
+例如,大于等于 2 的整数类型是 `2.. Self(L1+L2, R1+R2)
+
+正常加法。 `Int` 和 `Nat` 的添加在此定义为假装它在每个类中定义
+
+```python
+0..10 + 1..12 == 1..22
+Int + 0..10 == _..|Int|_ + 0..10 == _..|Int|_ == Int
+Nat + Nat == 0.._ + 0.._ == 0.._ == Nat
+```
diff --git a/doc/zh_CN/API/types/classes/Interval.md b/doc/zh_CN/API/types/classes/Interval.md
new file mode 100644
index 00000000..d3e95276
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Interval.md
@@ -0,0 +1,20 @@
+# Interval begin, end := WellOrder
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Interval.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+表示有序集合类型 (WellOrder) 的子类型的类型。Interval 类型具有派生类型,例如 PreOpen(x<..y)。
+
+```python
+Months = 1..12
+Alphabet = "a".."z"
+Weekdays = Monday..Friday
+Winter = November..December or January..February
+```
+
+```python
+0..1 # 整数范围
+0.0..1.0 # 真实(有理)范围
+# 或 0/1..1/1 相同
+```
+
+计算机无法处理无限位数的数字,所以实数的范围实际上是有理数的范围。
\ No newline at end of file
diff --git a/doc/zh_CN/API/types/classes/Iterator.md b/doc/zh_CN/API/types/classes/Iterator.md
new file mode 100644
index 00000000..d0af23ee
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Iterator.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Iterator.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/API/types/classes/Kind(N).md b/doc/zh_CN/API/types/classes/Kind(N).md
new file mode 100644
index 00000000..28843fe0
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Kind(N).md
@@ -0,0 +1,7 @@
+# Kind N: Nat
+
+[.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Kind(N).md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+```python
+Kind N: Nat = (Type; N) -> Type
+```
diff --git a/doc/zh_CN/API/types/classes/Matrix.md b/doc/zh_CN/API/types/classes/Matrix.md
new file mode 100644
index 00000000..2778181b
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Matrix.md
@@ -0,0 +1,9 @@
+# Matrix T: Num, Shape: [M, N]
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Matrix.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示矩阵的类型。 它继承自 Tensor[M, N]
+
+## 定义
+
+Inherit Tensor T, [M, N]
diff --git a/doc/zh_CN/API/types/classes/Module.md b/doc/zh_CN/API/types/classes/Module.md
new file mode 100644
index 00000000..135a64da
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Module.md
@@ -0,0 +1,5 @@
+# Module
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Module.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## 方法
diff --git a/doc/zh_CN/API/types/classes/Nat.md b/doc/zh_CN/API/types/classes/Nat.md
new file mode 100644
index 00000000..248a54c4
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Nat.md
@@ -0,0 +1,20 @@
+# Nat
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Nat.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+表示自然数的类型。 用于数组索引和范围类型
+
+## 定义
+
+```python
+Nat = 0.._
+```
+
+## 方法
+
+* times!(self, p: () => NoneType) -> NoneType
+
+```python
+100.times! () =>
+ print! "hello!"
+```
diff --git a/doc/zh_CN/API/types/classes/Neg.md b/doc/zh_CN/API/types/classes/Neg.md
new file mode 100644
index 00000000..4d76e168
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Neg.md
@@ -0,0 +1,10 @@
+# Neg
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Neg.md&commit_hash=290c43b09f7c3036112a164bed5fd07a1f6a5cda)
+
+表示负整数的类型。 Pos和Neg和{0} == Int
+它还具有一些值得注意的属性,例如不被零除和 Neg * Neg == Pos
+
+## 定义
+
+Inf<..-1
diff --git a/doc/zh_CN/API/types/classes/Never.md b/doc/zh_CN/API/types/classes/Never.md
new file mode 100644
index 00000000..bfd755d3
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Never.md
@@ -0,0 +1,15 @@
+# Never
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Never.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+它是所有类型的子类型。 它是一个`Class`,因为它拥有所有的方法,当然还有 `.new`。但是,它没有实例,并且Erg会在即将创建的那一刻停止。
+还有一种叫做`Panic`的类型没有实例,但是`Never`用于正常终止或故意无限循环,`Panic`用于异常终止。
+
+```python
+# Never <: Panic
+f(): Panic = exit 0 # OK
+g(): Never = panic() # TypeError
+```
+
+`Never`/`Panic`的 OR 类型,例如`T 或 Never`可以转换为`T`。 这是因为`Never`在语义上是一个从不出现的选项(如果出现了,程序会立即停止)。
+但是,在函数的返回值类型中使用时,`or Never`不能省略,因为它表示程序可能会终止。
\ No newline at end of file
diff --git a/doc/zh_CN/API/types/classes/NonZero.md b/doc/zh_CN/API/types/classes/NonZero.md
new file mode 100644
index 00000000..84457444
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/NonZero.md
@@ -0,0 +1,32 @@
+# NonZero N
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/NonZero.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示非零数的类。 保证除零的安全性
+
+```mermaid
+classDiagram
+ class NonZero~Int~ {
+ ...
+ }
+ class Int {
+ ...
+ }
+ class Div {
+ <>
+ /(Self, R) -> O or Panic
+ }
+ class SafeDiv {
+ <>
+ /(Self, R) -> O
+ }
+ Int <|-- NonZero~Int~: Inherit
+ Div <|-- SafeDiv: Subsume
+ SafeDiv <|.. NonZero~Int~: Impl
+ Div <|.. Int: Impl
+```
+
+## 方法
+
+@Impl SafeDiv R, O
+.`/`: Self.(R) -> O
diff --git a/doc/zh_CN/API/types/classes/Object.md b/doc/zh_CN/API/types/classes/Object.md
new file mode 100644
index 00000000..17e0656c
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Object.md
@@ -0,0 +1,9 @@
+# Object
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Object.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+它是所有类型的超类型
+
+## 方法
+
+* __sizeof__: Nat
diff --git a/doc/zh_CN/API/types/classes/Operator.md b/doc/zh_CN/API/types/classes/Operator.md
new file mode 100644
index 00000000..006d7dab
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Operator.md
@@ -0,0 +1,9 @@
+# Operator [...T], O
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Operator.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+是运算符的类型
+
+## 定义
+
+Inherit Func [...T], O
diff --git a/doc/zh_CN/API/types/classes/Option.md b/doc/zh_CN/API/types/classes/Option.md
new file mode 100644
index 00000000..2775da7c
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Option.md
@@ -0,0 +1,23 @@
+# Option T = T or NoneType
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Option.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+表示“可能失败”的类型。
+
+## 方法
+
+* unwrap(self, msg = "unwrapped a None value") -> T or Panic
+
+提取它,期望内容是 `T` 类型。 如果是 `None`,则输出 `msg` 并恐慌
+
+```python
+x = "...".parse(Int).into(Option Int)
+x.unwrap() # UnwrappingError: unwrapped a None value
+x.unwrap("failed to convert from string to number") # UnwrappingError: failed to convert from string to number
+```
+
+* unwrap_or(self, else: T) -> T
+
+* unwrap_or_exec(self, f: () -> T) -> T
+
+* unwrap_or_exec!(self, p!: () => T) -> T
diff --git a/doc/zh_CN/API/types/classes/Pos.md b/doc/zh_CN/API/types/classes/Pos.md
new file mode 100644
index 00000000..12632e37
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Pos.md
@@ -0,0 +1,10 @@
+# Pos
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Pos.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+Pos是一种表示正数(大于或等于1的整数)的类型。
+由于不包括0,因此具有消除被零除的可能性等优点。
+
+## 定义
+
+`Pos = 1.._`
diff --git a/doc/zh_CN/API/types/classes/Ratio.md b/doc/zh_CN/API/types/classes/Ratio.md
new file mode 100644
index 00000000..dfa56634
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Ratio.md
@@ -0,0 +1,7 @@
+# Ratio
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Ratio.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示有理数的类型。 它主要用于当您要使用分数时。
+实际上,Erg中的/运算符返回 Ratio。1/3等不被评估为 0.33333... 并且被处理为1/3。 此外,0.1 相当于 1/10。 所以`0.1 + 0.2 == 0.3`。 这听起来很明显,但在 Python中它是False。
+但是,Ratio类型的效率往往比Float类型略低。 在执行速度很重要且不需要精确数值的地方应该使用浮点类型。 然而,正如Rob Pike所说,过早优化是万恶之源。 在丢弃Ratio类型并使用Float类型之前,请进行真实的性能测试。 业余爱好者无条件偏爱较轻的模具。
diff --git a/doc/zh_CN/API/types/classes/Record.md b/doc/zh_CN/API/types/classes/Record.md
new file mode 100644
index 00000000..c1223a0e
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Record.md
@@ -0,0 +1,16 @@
+# Record
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Record.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+记录所属的类。例如,`{i = 1}` 是`Structural {i = Int}` 类型的元素,并且是`{i = Int}` 类的实例
+请注意,其他类的实例是记录类型的元素,而不是记录类的实例
+
+```python
+assert not Structural({i = Int}) in Class
+assert {i = Int} in Class
+
+C = Class {i = Int}
+c = C.new {i = 1}
+assert c in Structural {i = Int}
+assert not c in {i = Int}
+```
diff --git a/doc/zh_CN/API/types/classes/Result.md b/doc/zh_CN/API/types/classes/Result.md
new file mode 100644
index 00000000..64515cd0
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Result.md
@@ -0,0 +1,9 @@
+# Result T, E
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Result.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
+Result T, E <: Error = Either T, E
+```
+
+和 `Option` 一样,它代表“一个可能失败的值”,但它可以有失败的上下文。 用法与`Either`几乎相同。
\ No newline at end of file
diff --git a/doc/zh_CN/API/types/classes/Str!.md b/doc/zh_CN/API/types/classes/Str!.md
new file mode 100644
index 00000000..59a22a69
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Str!.md
@@ -0,0 +1,5 @@
+# StrWithLen! N: Nat! = Inherit StrWithLen N
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示可变长度字符串的类型
diff --git a/doc/zh_CN/API/types/classes/Str.md b/doc/zh_CN/API/types/classes/Str.md
new file mode 100644
index 00000000..b496517f
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Str.md
@@ -0,0 +1,11 @@
+# Str
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+(不变长度)表示字符串的类型。 简单的 `Str` 类型是删除了字符数的 `StrWithLen N` 类型(`Str = StrWithLen _`)
+
+## 方法
+
+* isnumeric
+
+返回字符串是否为阿拉伯数字。 使用 `isunicodenumeric` 判断汉字数字和其他表示数字的字符(注意此行为与 Python 不同)。
\ No newline at end of file
diff --git a/doc/zh_CN/API/types/classes/StrWithLen.md b/doc/zh_CN/API/types/classes/StrWithLen.md
new file mode 100644
index 00000000..67caca65
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/StrWithLen.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/StrWithLen.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/API/types/classes/Subroutine.md b/doc/zh_CN/API/types/classes/Subroutine.md
new file mode 100644
index 00000000..0c2ee7ab
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Subroutine.md
@@ -0,0 +1,21 @@
+# Subroutine
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Subroutine.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Func和Proc的基本类型。
+
+## 方法
+
+* return
+
+中断子程序并返回指定的值。 用于快速逃离嵌套
+
+```python
+f x =
+ for 0..10, i ->
+ if i == 5:
+ do
+ f::return i
+ do
+ log i
+```
diff --git a/doc/zh_CN/API/types/classes/Tensor.md b/doc/zh_CN/API/types/classes/Tensor.md
new file mode 100644
index 00000000..53eb1970
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Tensor.md
@@ -0,0 +1,26 @@
+# Tensor Shape: [Nat; N]
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tensor.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+ 用于有效操作多维数组的类。 它还定义了诸如多维数组上的乘法之类的操作
+ Matrix、Vector 等都继承自该类型
+
+```python
+Tensor.arange(0..9) # Tensor [10]
+```
+
+* reshape(self, NewShape: [Nat; M]) -> Self NewShape
+
+```python
+(1..9).into(Tensor).reshape [3, 3]
+```
+
+* identity i: Nat -> Self shape: [Nat; N]
+* zeros(Shape: [Nat; N]) -> Self
+* ones(Shape: [Nat; N]) -> Self
+
+* diag
+
+* linspace
+* logspace
+* geomspace
diff --git a/doc/zh_CN/API/types/classes/TransCell(T).md b/doc/zh_CN/API/types/classes/TransCell(T).md
new file mode 100644
index 00000000..a801e8b7
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/TransCell(T).md
@@ -0,0 +1,14 @@
+# TransCell! T: Type!
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/TransCell(T).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+它是一个单元格,其内容可以针对每个模具进行更改。 由于它是T类型的子类型,因此它也表现为T类型
+当它在初始化时输入T时很有用,并且在某个点之后总是输入U
+
+```python
+a = TransCell!.new None
+a: TransCell! !NoneType
+a.set! 1
+a: TransCell! !Int
+assert a + 1 == 2
+```
diff --git a/doc/zh_CN/API/types/classes/Tuple.md b/doc/zh_CN/API/types/classes/Tuple.md
new file mode 100644
index 00000000..498c1dd1
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Tuple.md
@@ -0,0 +1,29 @@
+# Tuple T: ...Type
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tuple.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+包含多种类型对象的集合
+
+## 方法
+
+* zip self, other
+
+ 组合两个有序集合(数组或元组)
+
+ ```python
+ assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4)
+ ```
+
+* zip_by self, op, other
+
+ 一种泛化 zip 的方法。 您可以指定一个二进制操作来组合
+ `()`、`[]`、`{}`、`{:}` 也可以指定为运算符,分别生成元组、数组、集合和字典
+
+ ```python
+ assert ([1, 2, 3].zip([4, 5, 6]))[0] == (1, 4)
+ assert ([1, 2, 3].zip_by((), [4, 5, 6]))[0] == (1, 4)
+ assert ([1, 2, 3].zip_by([], [4, 5, 6]))[0] == [1, 4]
+ assert ([1, 2, 3].zip_by({}, [4, 5, 6]))[0] == {1, 4}
+ assert ([1, 2, 3].zip_by({:}, [4, 5, 6]))[0] == {1: 4}
+ assert ([1, 2, 3].zip_by(`_+_`, [4, 5, 6]))[0] == 5
+ ```
diff --git a/doc/zh_CN/API/types/classes/Type.md b/doc/zh_CN/API/types/classes/Type.md
new file mode 100644
index 00000000..dae4a5c2
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Type.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/API/types/classes/Vector.md b/doc/zh_CN/API/types/classes/Vector.md
new file mode 100644
index 00000000..97e73f1e
--- /dev/null
+++ b/doc/zh_CN/API/types/classes/Vector.md
@@ -0,0 +1,5 @@
+# Vector T: Num, N: Nat
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Vector.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示向量的类型。与同名的Rust和C++类型不同,这种类型只处理数字。
\ No newline at end of file
diff --git a/doc/zh_CN/API/types/patches/BinOp.md b/doc/zh_CN/API/types/patches/BinOp.md
new file mode 100644
index 00000000..63146d8b
--- /dev/null
+++ b/doc/zh_CN/API/types/patches/BinOp.md
@@ -0,0 +1,9 @@
+# BinOp L, R, O
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/BinOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+二元运算符的类型
+
+## 修补程序
+
+Operator [L, R], O
diff --git a/doc/zh_CN/API/types/patches/UnaryOp.md b/doc/zh_CN/API/types/patches/UnaryOp.md
new file mode 100644
index 00000000..d38d1f25
--- /dev/null
+++ b/doc/zh_CN/API/types/patches/UnaryOp.md
@@ -0,0 +1,9 @@
+# UnaryOp T, O
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/UnaryOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+一元运算符的类型
+
+## 定义
+
+Operator [T], O
diff --git a/doc/zh_CN/API/types/traits/Add(R,O).md b/doc/zh_CN/API/types/traits/Add(R,O).md
new file mode 100644
index 00000000..cf36f359
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/Add(R,O).md
@@ -0,0 +1,36 @@
+# Add R
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Add(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
+Add R = Trait {
+ .AddO = Type
+ .`_+_` = (Self, R) -> Self.AddO
+}
+```
+
+`Add`是一种定义加法的类型。加法有两种类型的`+`:方法和函数
+`+`作为二元函数,即`_+_`,定义如下:
+
+```python
+`_+_`(l: Add(R, O), r: R): O = l.`_+_` r
+```
+
+这个定义的目的是让 `+` 可以被视为一个函数而不是一个方法
+
+```python
+assert [1, 2, 3].fold(0, `_+_`) == 6
+
+call op, x, y = op(x, y)
+assert call(`_+_`, 1, 2) == 3
+```
+
+加法是这样输入的
+
+```python
+f: |O: Type; A <: Add(Int, O)| A -> O
+f x = x + 1
+
+g: |A, O: Type; Int <: Add(A, O)| A -> O
+g x = 1 + x
+```
diff --git a/doc/zh_CN/API/types/traits/Div(R,O).md b/doc/zh_CN/API/types/traits/Div(R,O).md
new file mode 100644
index 00000000..8aa4af87
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/Div(R,O).md
@@ -0,0 +1,11 @@
+# Div R, O
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Div(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+如果除以零没有错误,请使用“SafeDiv”
+
+```python
+Div R, O = Trait {
+ .`/` = Self.(R) -> O or Panic
+}
+```
diff --git a/doc/zh_CN/API/types/traits/Eq.md b/doc/zh_CN/API/types/traits/Eq.md
new file mode 100644
index 00000000..6aed2ae0
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/Eq.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Eq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/API/types/traits/Into.md b/doc/zh_CN/API/types/traits/Into.md
new file mode 100644
index 00000000..1cafc6b4
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/Into.md
@@ -0,0 +1,13 @@
+# Into T
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Into.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+一种类型,表明它可以被类型转换为类型T。
+即使Self和T之间没有继承关系,也是在关系可以相互转换的时候定义的。
+与继承不同,没有隐式转换。您必须始终调用 `.into` 方法。
+
+## 方法
+
+* into(self, T) -> T
+
+ 変換を行います。
diff --git a/doc/zh_CN/API/types/traits/Iterable.md b/doc/zh_CN/API/types/traits/Iterable.md
new file mode 100644
index 00000000..ba458258
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/Iterable.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Iterable.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/API/types/traits/Num.md b/doc/zh_CN/API/types/traits/Num.md
new file mode 100644
index 00000000..71b5cabb
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/Num.md
@@ -0,0 +1,18 @@
+# Num
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Num.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 定义初始化
+
+```python
+Num R = Add(R) and Sub(R) and Mul(R) and Eq
+Num = Num Self
+```
+
+## 父类
+
+Add and Sub and Mul and Eq
+
+## 方法
+
+* `abs`
diff --git a/doc/zh_CN/API/types/traits/Ord.md b/doc/zh_CN/API/types/traits/Ord.md
new file mode 100644
index 00000000..3ef5f04a
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/Ord.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Ord.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/API/types/traits/SafeDiv(R,O).md b/doc/zh_CN/API/types/traits/SafeDiv(R,O).md
new file mode 100644
index 00000000..03595643
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/SafeDiv(R,O).md
@@ -0,0 +1,10 @@
+# SafeDiv R, O
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/SafeDiv(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
+SafeDiv R, O = Subsume Div, {
+ @Override
+ .`/` = Self.(R) -> O
+}
+```
diff --git a/doc/zh_CN/API/types/traits/Sample.md b/doc/zh_CN/API/types/traits/Sample.md
new file mode 100644
index 00000000..5eb0a24c
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/Sample.md
@@ -0,0 +1,33 @@
+# Sample
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Sample.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+具有“随机”选择实例的`sample`和`sample!`方法的特征。`sample`方法总是返回相同的实例,而`sample!`方法返回一个随机实例,该实例随调用而变化
+
+请注意,这是一个假设您想要一个适当的实例进行测试等的特征,并且它不一定是随机的。 如果您想要随机抽样,请使用“随机”模块。
+
+所有主要的值类都实现了 `Sample`。它还在由“Sample”类组成的元组类型、记录类型、Or类型和筛选类型中实现
+
+```python
+assert Int.sample() == 42
+assert Str.sample() == "example"
+# Int默认在64bit范围内采样
+print! Int.sample!() # 1313798
+print! {x = Int; y = Int}.sample!() # {x = -32432892, y = 78458576891}
+```
+
+下面是一个`Sample`的实现示例
+
+```python
+EmailAddress = Class {header = Str; domain = Str}, Impl=Sample and Show
+@Impl Show
+EmailAddress.
+ show self = "{self::header}@{self::domain}"
+@Impl Sample
+EmailAddress.
+ sample(): Self = Self.new "sample@gmail.com"
+ sample!(): Self =
+ domain = ["gmail.com", "icloud.com", "yahoo.com", "outlook.com", ...].sample!()
+ header = AsciiStr.sample!()
+ Self.new {header; domain}
+```
diff --git a/doc/zh_CN/API/types/traits/Seq.md b/doc/zh_CN/API/types/traits/Seq.md
new file mode 100644
index 00000000..007f7134
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/Seq.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Seq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/API/types/traits/Show.md b/doc/zh_CN/API/types/traits/Show.md
new file mode 100644
index 00000000..30763e02
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/Show.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Show.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/API/types/traits/Unpack.md b/doc/zh_CN/API/types/traits/Unpack.md
new file mode 100644
index 00000000..dabbd429
--- /dev/null
+++ b/doc/zh_CN/API/types/traits/Unpack.md
@@ -0,0 +1,15 @@
+# Unpack
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Unpack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+标记性状。实现时,元素可以像记录一样通过模式匹配来分解
+
+```python
+C = Class {i = Int}, Impl=Unpack
+C.new i = Self::new {i;}
+{i} = C.new(1)
+D = Class C or Int
+log match D.new(1):
+ (i: Int) -> i
+ ({i}: C) -> i
+```
diff --git a/doc/zh_CN/compiler/TODO_hint.md b/doc/zh_CN/compiler/TODO_hint.md
new file mode 100644
index 00000000..5f949d02
--- /dev/null
+++ b/doc/zh_CN/compiler/TODO_hint.md
@@ -0,0 +1,6 @@
+# 提示(未实现)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_hint.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+* `x 未定义`(x 已被`Del` 删除)=> `提示:在第 X 行删除`
+*补丁方法重复:“提示:指定补丁(如`T.foo(1)`)或使用`Del`删除任何`.foo`”
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/TODO_recov_suggest.md b/doc/zh_CN/compiler/TODO_recov_suggest.md
new file mode 100644
index 00000000..68a5164c
--- /dev/null
+++ b/doc/zh_CN/compiler/TODO_recov_suggest.md
@@ -0,0 +1,13 @@
+# 错误恢复建议(尚未实现)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_recov_suggest.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+* `1 or 2`, `1 and 2` => `{1, 2}`?
+* `U = Inherit T` => 非类类型不能被继承,或者`U = Class T`?
+* `Int and Str` => 不允许多重继承,或者`Int or Str`?
+* `: [1, 2]` => `: {1, 2}`?
+* `: [Int, 2]` => `: [Int; 2]`?
+* `[Int; Str]` => `(Int, Str)`(Tuple) 还是 `[Int: Str]`(Dict)?
+* `{x: Int}` => `{x = Int}`?
+* `{x = Int}!` => `{x = Int!}`?
+* `ref! immut_expr` => `ref! !immut_expr`?
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/TODO_warn.md b/doc/zh_CN/compiler/TODO_warn.md
new file mode 100644
index 00000000..1b25747f
--- /dev/null
+++ b/doc/zh_CN/compiler/TODO_warn.md
@@ -0,0 +1,7 @@
+# 警告(尚未实现)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_warn.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+* `t = {(record type)}` => `T = {(record type)}`?(只有定义为常量的类型才能用于类型说明)
+* `{I: Int | ...}!` => `{I: Int! | ...}`
+* for/while 块中的`return x`(`x != ()`) => `f::return`(外部块)?
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/abandoned.md b/doc/zh_CN/compiler/abandoned.md
new file mode 100644
index 00000000..547012b8
--- /dev/null
+++ b/doc/zh_CN/compiler/abandoned.md
@@ -0,0 +1,12 @@
+# 废弃/拒绝的语言规范
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/abandoned.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## 重载(临时多态性)
+
+被放弃了,因为它可以用参数+子类型多态来代替,并且与Python的语义不兼容。 有关详细信息,请参阅 [overload](../syntax/type/overloading.md) 文章。
+
+## 具有显式生命周期的所有权系统
+
+原计划引入 Rust 之类的所有权系统,但由于与 Python 的语义不兼容以及需要引入生命周期注解等复杂规范而被放弃,并且所有不可变对象都是 RC。托管的可变对象现在只有一个所有权.
+Dyne 没有 C# 和 Nim 那样的 GIL,策略是允许值对象和低级操作在安全范围内。
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/architecture.md b/doc/zh_CN/compiler/architecture.md
new file mode 100644
index 00000000..04135067
--- /dev/null
+++ b/doc/zh_CN/compiler/architecture.md
@@ -0,0 +1,44 @@
+# `ergc` 的架构
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/architecture.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1)
+
+## 1. 扫描 Erg 脚本 (.er) 并生成 `TokenStream` (parser/lex.rs)
+
+* parser/lexer/Lexer 生成`TokenStream`(这是一个Token的迭代器,TokenStream可以通过lexer.collect()生成)
+ * `Lexer` 由 `Lexer::new` 或 `Lexer::from_str` 构造,其中 `Lexer::new` 从文件或命令选项中读取代码。
+ * `Lexer` 可以作为迭代器按顺序生成令牌;如果您想一次获得 `TokenStream`,请使用 `Lexer::lex`。
+ * `Lexer` 输出 `LexError` 为错误,但 `LexError` 没有足够的信息显示自己。如果要显示错误,请使用 `LexerRunner` 转换错误。
+ * 如果你想单独使用 `Lexer`,也可以使用 `LexerRunner`;`Lexer` 只是一个迭代器,并没有实现 `Runnable` 特性。
+ * `Runnable` 由 `LexerRunner`、`ParserRunner`、`Compiler` 和 `VirtualMachine` 实现。
+
+## 2. 转换 `TokenStream` -> `AST` (parser/parse.rs)
+
+* `Parser` 和 `Lexer` 一样,有两个构造函数,`Parser::new` 和 `Parser::from_str`,而 `Parser::parse` 会给出 `AST`。
+* `AST` 是 `Vec` 的包装器类型。
+
+### 2.5 脱糖 `AST`
+
+* 扩展嵌套变量 (`Desugarer::desugar_nest_vars_pattern`)
+* desugar 多模式定义语法(`Desugarer::desugar_multiple_pattern_def`)
+
+## 3. 类型检查和推断,转换 `AST` -> `HIR` (compiler/lower.rs)
+
+* `HIR` 有每个变量的类型信息。它是用于“高级中间表示”的。
+* `HIR` 只保存变量的类型,但这已经足够了。在极端情况下,这是因为 Erg 只有转换(或运算符)应用程序的参数对象。
+* `ASTLower` 可以用与`Parser` 和`Lexer` 相同的方式构造。
+* 如果没有错误发生,`ASTLowerer::lower` 将输出 `HIR` 和 `CompileWarnings` 的元组。
+* `ASTLowerer`归`Compiler`所有。与传统结构不同,`ASTLowerer`处理代码上下文并且不是一次性的。
+* 如果类型推断的结果不完整(如果存在未知类型变量),名称解析时会出错。
+
+## 4. 检查副作用(compiler/effectcheck.rs)
+
+## 4. 检查所有权(compiler/memcheck.rs)
+
+## 5. 从`HIR`(compiler/codegen.rs)生成字节码(`CodeObj`)
+
+* 根据表达式的类型信息,将执行量化子程序的名称解析。
+
+##(6.(未来计划)转换字节码 -> LLVM IR)
+
+* 字节码是基于堆栈的,而 LLVM IR 是基于寄存器的。
+ 这个转换过程会多出几层中间过程。
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/errors.md b/doc/zh_CN/compiler/errors.md
new file mode 100644
index 00000000..444187d7
--- /dev/null
+++ b/doc/zh_CN/compiler/errors.md
@@ -0,0 +1,133 @@
+# Erg Compiler Errors
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/errors.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## AssignError
+
+尝试重写不可变变量时发生
+
+## AttributeError
+
+尝试访问不存在的属性时发生
+
+## PurityError
+
+当您在不允许副作用的范围内(函数、不可变类型等)编写导致副作用的代码时发生
+
+## MoveError
+
+尝试访问已移动的变量时发生
+
+## BorrowError
+
+在存在对对象的借用时尝试获取可变引用时发生
+
+## CyclicError
+
+当你有一个明显不可阻挡的循环时发生
+
+```python
+i: Int = i
+
+f(): Int = g()
+g() = f()
+
+h(): Int = module::h()
+
+T = U
+U = T
+```
+
+## BytecodeError
+
+当加载的字节码损坏时发生
+
+## CompileSystemError
+
+在编译器内部发生错误时发生
+
+## EnvironmentError
+
+如果您在安装期间没有访问权限,则会发生这种情况
+
+## FeatureError
+
+在检测到未正式提供的实验性功能时发生
+
+## ImportError
+
+## IndentationError
+
+检测到不良缩进时发生
+派生自SyntaxError
+
+## NameError
+
+当您访问不存在的变量时发生
+
+## NotImplementedError
+
+当您调用具有定义但没有实现的 API 时发生
+派生自 TypeError
+
+## PatternError
+
+当检测到非法模式时发生
+派生自SyntaxError
+
+## SyntaxError
+
+在检测到错误语法时发生
+
+## TabError
+
+在使用制表符进行缩进/间距时发生
+派生自SyntaxError
+
+## TypeError
+
+当对象类型不匹配时发生
+
+## UnboundLocalError
+
+在定义之前使用变量时发生
+更准确地说,它发生在以前使用过在范围内定义的变量时
+
+```python
+i = 0
+f x =
+ y = i + x
+ i = 1
+ y + i
+```
+
+在这段代码中,`y = i + x` 中的 `i` 是一个未定义的变量
+但是,常量可以在定义之前在另一个函数中调用
+
+```python
+f() = g()
+g() = f()
+```
+
+## Erg Compiler Warnings
+
+## SyntaxWarning
+
+它在语法上很好,但是当我们检测到冗余或不常见的代码(不必要的 `()` 等)时就会发生这种情况
+
+```python
+if (True): # SyntaxWarning: unnecessary parentheses
+ ...
+```
+
+## DeprecationWarning
+
+在不推荐使用引用的对象时发生
+(开发人员在生成此警告时应始终提供替代方法作为提示)
+
+## FutureWarning
+
+当您检测到将来可能导致问题的代码时发生
+此警告是由版本兼容性问题(包括库)以及语法和 API 的更改引起的
+
+## ImportWarning
diff --git a/doc/zh_CN/compiler/hir.md b/doc/zh_CN/compiler/hir.md
new file mode 100644
index 00000000..b95ecb81
--- /dev/null
+++ b/doc/zh_CN/compiler/hir.md
@@ -0,0 +1,150 @@
+# 高级中间表示(HIR, High-level Intermediate Representation)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/hir.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+HIR 是 Erg 编译器从 AST 生成的结构
+此结构包含源代码中每个表达式的完整类型信息,并且在语法上已脱糖
+AST与源代码一一对应(纯文本),但是HIR去掉了不必要的代码信息,添加了省略的类型信息,所以HIR可以转换为源代码很难恢复
+让我们在下面的代码中查看 HIR 的示例
+
+```python
+v = ![]
+for! 0..10, i =>
+ v.push! i
+log v.sum()
+```
+
+从此代码生成的 AST 如下所示:
+
+```python
+AST(Module[
+ VarDef{
+ sig: VarSignature{
+ pat: VarPattern::Ident(None, VarName("v")),
+ spec_t: None,
+ },
+ op: "=",
+ body: Block[
+ UnaryOp{
+ op: "!",
+ expr: Array([]),
+ },
+ ],
+ },
+ Call{
+ obj: Accessor::Local("for!"),
+ args: [
+ BinOp{
+ op: "..",
+ lhs: Literal(0),
+ rhs: Literal(10),
+ },
+ Lambda{
+ sig: LambdaSignature{
+ params: [
+ ParamSignature{
+ pat: ParamPattern::Name(VarName("i")),
+ },
+ ],
+ spec_ret_t: None,
+ },
+ body: Block[
+ Call{
+ obj: Accessor::Attr{"v", "push!"},
+ args: [
+ Accessor::Local("i"),
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ Call{
+ obj: Accessor::Local("log"),
+ args: [
+ Call{
+ obj: Accessor::Attr("v", "sum"),
+ args: [],
+ }
+ ],
+ }
+])
+```
+
+从 AST 生成的 HIR 如下所示:
+
+```python
+HIR(Module[
+ VarDef{
+ sig: VarSignature{
+ pat: VarPattern::Ident(None, Name("v")),
+ t: [0..10, _]!,
+ },
+ op: "=",
+ body: Block[
+ expr: UnaryOp{
+ op: "!",
+ expr: Array([]),
+ t: [0..10, 0]!,
+ },
+ ],
+ },
+ Call{
+ obj: Accessor::Local{
+ name: "for!",
+ t: (Range Nat, Nat => NoneType) => NoneType,
+ },
+ args: [
+ BinOp{
+ op: "..",
+ lhs: Literal(0),
+ rhs: Literal(10),
+ t: 0..10,
+ },
+ Lambda{
+ sig: LambdaSignature{
+ params: [
+ ParamSignature{
+ pat: ParamPattern::Name(Name("i")),
+ t: 0..10,
+ },
+ ],
+ t: 0..10 => NoneType,
+ },
+ body: Block[
+ Call{
+ obj: Accessor::Attr{
+ obj: Accessor::Local("v"),
+ field: "push!",
+ t: Ref!(Self![T ~> T, N ~> N+1]).(Nat) => NoneType,
+ },
+ args: [
+ Accessor::Local("i"),
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ Call{
+ obj: Accessor::Local{
+ name: "log",
+ t: ...Object => NoneType,
+ },
+ args: [
+ Call{
+ obj: Accessor::Attr{
+ obj: Accessor::Local("v"),
+ field: "sum",
+ t: [0..10, !_] -> Nat
+ },
+ args: [],
+ t: Nat
+ }
+ ],
+ }
+])
+```
+
+对象类型被推断为尽可能小。 另一方面,子例程推断实现存在的类型
+因此,实际参数的类型和形式参数的类型可能不匹配
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/index.md b/doc/zh_CN/compiler/index.md
new file mode 100644
index 00000000..33522b77
--- /dev/null
+++ b/doc/zh_CN/compiler/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/compiler/inference.md b/doc/zh_CN/compiler/inference.md
new file mode 100644
index 00000000..40b05ec8
--- /dev/null
+++ b/doc/zh_CN/compiler/inference.md
@@ -0,0 +1,440 @@
+# 类型推断算法
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/inference.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+> __Warning__:此部分正在编辑中,可能包含一些错误
+
+显示了下面使用的符号
+
+```python
+Free type variables (type, unbound): ?T, ?U, ...
+Free-type variables (values, unbound): ?a, ?b, ...
+type environment (Γ): { x: T, ... }
+Type assignment rule (S): { ?T --> T, ... }
+Type argument evaluation environment (E): { e -> e', ... }
+```
+
+我们以下面的代码为例:
+
+```python
+v = ![]
+v.push! 1
+print! v
+```
+
+Erg 的类型推断主要使用 Hindley-Milner 类型推断算法(尽管已经进行了各种扩展)。具体而言,类型推断是通过以下过程执行的。术语将在后面解释。
+
+1. 推断右值的类型(搜索)
+2. 实例化结果类型
+3. 如果是调用,执行类型替换(substitute)
+4. 解决已经单态化的特征
+5. 如果有类型变量值,求值/归约(eval)
+6. 删除链接类型变量(deref)
+7. 传播可变依赖方法的变化
+8. 如果有左值并且是Callable,则泛化参数类型(generalize)
+9. 如果有左值,对(返回值)类型进行泛化(generalize)
+10. 如果是赋值,则在符号表(`Context`)中注册类型信息(更新)
+
+具体操作如下。
+
+第 1 行。 Def{sig: v, block: ![]}
+ 获取块类型:
+ 获取 UnaryOp 类型:
+ getArray 类型:`['T; 0]`
+ 实例化:`[?T; 0]`
+ (替代,评估被省略)
+ 更新:`Γ: {v: [?T; 0]!}`
+ 表达式 返回`NoneType`:OK
+
+第 2 行 CallMethod {obj: v, name: push!, args: [1]}
+ 获取 obj 类型:`Array!(?T, 0)`
+ 搜索:`Γ Array!(?T, 0).push!({1})`
+ 得到:`= Array!('T ~> 'T, 'N ~> 'N+1).push!('T) => NoneType`
+ 实例化:`Array!(?T, ?N).push!(?T) => NoneType`
+ 替代(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!(Nat) => NoneType`
+ 评估: `Array!(Nat, 0 ~> 1).push!({1}) => NoneType`
+ 更新:`Γ:{v:[Nat; 1]!}`
+ 表达式 返回`NoneType`:OK
+
+第 3 行。调用 {obj: print!, args: [v]}
+ 获取参数类型:`[[Nat; 1]!]`
+ 获取 obj 类型:
+ 搜索:`Γ print!([Nat; 1]!)`
+ 得到:`= print!(...Object) => NoneType`
+ 表达式 返回`NoneType`:OK
+
+## 类型变量的实现
+
+类型变量最初在 [ty.rs](../../src/common/ty.rs) 的 `Type` 中表示如下。它现在以不同的方式实现,但本质上是相同的想法,所以我将以更天真的方式考虑这种实现。
+`RcCell` 是 `Rc>` 的包装类型。
+
+```rust
+pub enum Type {
+ ...
+ Var(RcCell>), // a reference to the type of other expression, see docs/compiler/inference.md
+ ...
+}
+```
+
+类型变量可以通过将实体类型保存在外部字典中来实现,并且类型变量本身只有它的键。但是,据说使用 `RcCell` 的实现通常更有效(需要验证,[来源](https://mobile.twitter.com/bd_gfngfn/status/1296719625086877696?s=21))。
+
+类型变量首先被初始化为 `Type::Var(RcCell::new(None))`。
+当分析代码并确定类型时,会重写此类型变量。
+如果内容直到最后都保持为 None ,它将是一个无法确定为具体类型的类型变量(当场)。例如,具有 `id x = x` 的 `x` 类型。
+我将这种状态下的类型变量称为 __Unbound 类型变量__(我不知道确切的术语)。另一方面,我们将分配了某种具体类型的变量称为 __Linked 类型变量__。
+
+两者都是自由类型变量(该术语显然以“自由变量”命名)。这些是编译器用于推理的类型变量。它之所以有这样一个特殊的名字,是因为它不同于程序员指定类型的类型变量,例如 `id: 'T -> 'T` 中的 `'T`。
+
+未绑定类型变量表示为`?T`、`?U`。在类型论的上下文中,经常使用 α 和 β,但这一种是用来简化输入的。
+请注意,这是出于一般讨论目的而采用的表示法,实际上并未使用字符串标识符实现。
+
+进入类型环境时,未绑定的类型变量 `Type::Var` 被替换为 `Type::MonoQuantVar`。这称为 __quantified 类型变量__。这类似于程序员指定的类型变量,例如“T”。内容只是一个字符串,并没有像自由类型变量那样链接到具体类型的工具。
+
+用量化类型变量替换未绑定类型变量的操作称为__generalization__(或泛化)。如果将其保留为未绑定类型变量,则类型将通过一次调用固定(例如,调用 `id True` 后,`id 1` 的返回类型将是 `Bool`),所以它必须是概括的。
+以这种方式,在类型环境中注册了包含量化类型变量的通用定义。
+
+## 概括、类型方案、具体化
+
+让我们将未绑定类型变量 `?T` 泛化为 `gen` 的操作表示。令生成的广义类型变量为 `|T: Type| T`。
+在类型论中,量化类型,例如多相关类型 `α->α`,通过在它们前面加上 `∀α.` 来区分(像 ∀ 这样的符号称为(通用)量词。)。
+这样的表示(例如`∀α.α->α`)称为类型方案。 Erg 中的类型方案表示为 `|T: Type| T -> T`。
+类型方案通常不被认为是一流的类型。以这种方式配置类型系统可以防止类型推断起作用。但是,在Erg中,在一定条件下可以算是一流的类型。有关详细信息,请参阅 [rank2 类型](../syntax/type/advanced/rank2type.md)。
+
+现在,当在使用它的类型推断(例如,`id 1`,`id True`)中使用获得的类型方案(例如`'T -> 'T(id's type scheme)`)时,必须释放generalize。这种逆变换称为 __instantiation__。我们将调用操作`inst`。
+
+```python
+gen ?T = 'T
+inst 'T = ?T (?T ∉ Γ)
+```
+
+重要的是,这两个操作都替换了所有出现的类型变量。 例如,如果你实例化 `'T -> 'T`,你会得到 `?T -> ?T`。
+实例化需要替换 dict,但为了泛化,只需将 `?T` 与 `'T` 链接以替换它。
+
+之后,给出参数的类型以获取目标类型。 此操作称为类型替换,将用 `subst` 表示。
+此外,如果表达式是调用,则获取返回类型的操作表示为 `subst_call_ret`。 第一个参数是参数类型列表,第二个参数是要分配的类型。
+
+类型替换规则 `{?T --> X}` 意味着将 `?T` 和 `X` 重写为相同类型。 此操作称为 __Unification__。 `X` 也可以是类型变量。
+[单独部分](./unification.md) 中描述了详细的统一算法。 我们将统一操作表示为“统一”。
+
+```python
+unify(?T, Int) == Ok(()) # ?T == (Int)
+
+# S为类型分配规则,T为适用类型
+subst(S: {?T --> X}, T: ?T -> ?T) == X -> X
+# Type assignment rules are {?T --> X, ?U --> T}
+subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y
+```
+
+## 半统一(semi-unification)
+
+统一的一种变体称为半统一(__Semi-unification__)。 这是更新类型变量约束以满足子类型关系的操作。
+在某些情况下,类型变量可能是统一的,也可能不是统一的,因此称为“半”统一。
+
+例如,在参数分配期间会发生半统一。
+因为实际参数的类型必须是形式参数类型的子类型。
+如果参数类型是类型变量,我们需要更新子类型关系以满足它。
+
+```python
+# 如果形参类型是T
+f(x: T): T = ...
+
+a: U
+# 必须为 U <: T,否则类型错误
+f(a)
+```
+
+## 泛化
+
+泛化不是一项简单的任务。 当涉及多个作用域时,类型变量的“级别管理”就变得很有必要了。
+为了看到层级管理的必要性,我们首先确认没有层级管理的类型推断会导致问题。
+推断以下匿名函数的类型。
+
+```python
+x ->
+ y = x
+ y
+```
+
+首先,Erg 分配类型变量如下:
+y 的类型也是未知的,但暂时未分配。
+
+```python
+x(: ?T) ->
+ y = x
+ y
+```
+
+首先要确定的是右值 x 的类型。 右值是一种“用途”,因此我们将其具体化。
+但是 x 的类型 `?T` 已经被实例化了,因为它是一个自由变量。 Yo`?T` 成为右值的类型。
+
+```python
+x(: ?T) ->
+ y = x (: inst ?T)
+ y
+```
+
+注册为左值 y 的类型时进行泛化。 然而,正如我们稍后将看到的,这种概括是不完善的,并且会产生错误的结果。
+
+```python
+x(: ?T) ->
+ y(:gen?T) = x(:?T)
+ y
+```
+
+```python
+x(: ?T) ->
+ y(: 'T) = x
+ y
+```
+
+y 的类型现在是一个量化类型变量“T”。 在下一行中,立即使用 `y`。 具体的。
+
+```python
+x: ?T ->
+ y(: 'T) = x
+ y(: inst 'T)
+```
+
+请注意,实例化必须创建一个与任何已经存在的(自由)类型变量不同的(自由)类型变量(概括类似)。 这样的类型变量称为新类型变量。
+
+```python
+x: ?T ->
+ y = x
+ y(: ?U)
+```
+
+并查看生成的整个表达式的类型。 `?T -> ?U`。
+但显然这个表达式应该是`?T -> ?T`,所以我们知道推理有问题。
+发生这种情况是因为我们没有“级别管理”类型变量。
+
+所以我们用下面的符号来介绍类型变量的层次。 级别表示为自然数。
+
+```python
+# 普通类型变量
+?T<1>, ?T<2>, ...
+# 具有子类型约束的类型变量
+?T<1>(<:U) or ?T(<:U)<1>, ...
+```
+
+让我们再尝试一次:
+
+```python
+x ->
+ y = x
+ y
+```
+
+首先,按如下方式分配一个 leveled 类型变量: toplevel 级别为 1。随着范围的加深,级别增加。
+函数参数属于内部范围,因此它们比函数本身高一级。
+
+```python
+# level 1
+x (: ?T<2>) ->
+ # level 2
+ y = x
+ y
+```
+
+首先,实例化右值`x`。和以前一样,没有任何改变。
+
+```python
+x (: ?T<2>) ->
+ y = x (: inst ?T<2>)
+ y
+```
+
+这是关键。 这是分配给左值`y`的类型时的概括。
+早些时候,这里的结果很奇怪,所以我们将改变泛化算法。
+如果类型变量的级别小于或等于当前范围的级别,则泛化使其保持不变。
+
+```python
+gen ?T = if n <= current_level, then= ?T, else= 'T
+```
+
+```python
+x (: ?T<2>) ->
+ # current_level = 2
+ y(: gen ?T<2>) = x(: ?T<2>)
+ y
+```
+
+That is, the lvalue `y` has type `?T<2>`.
+
+```python
+x (: ?T<2>) ->
+ # ↓ 不包括
+ y(: ?T<2>) = x
+ y
+```
+
+y 的类型现在是一个未绑定的类型变量 `?T<2>`。 具体如下几行:但是 `y` 的类型没有被概括,所以什么也没有发生
+
+```python
+x (: ?T<2>) ->
+ y(: ?T<2>) = x
+ y (: inst ?T<2>)
+```
+
+```python
+x (: ?T<2>) ->
+ y = x
+ y (: ?T<2>)
+```
+
+我们成功获得了正确的类型`?T<2> -> ?T<2>`。
+
+让我们看另一个例子。 这是更一般的情况,具有函数/运算符应用程序和前向引用。
+
+```python
+fx, y = id(x) + y
+id x = x
+
+f10,1
+```
+
+让我们逐行浏览它。
+
+在 `f` 的推断过程中,会引用后面定义的函数常量 `id`。
+在这种情况下,在 `f` 之前插入一个假设的 `id` 声明,并为其分配一个自由类型变量。
+注意此时类型变量的级别是`current_level`。 这是为了避免在其他函数中泛化。
+
+```python
+id: ?T<1> -> ?U<1>
+f x (: ?V<2>), y (: ?W<2>) =
+ id(x) (: subst_call_ret([inst ?V<2>], inst ?T<1> -> ?U<1>)) + y
+```
+
+类型变量之间的统一将高级类型变量替换为低级类型变量。
+如果级别相同,则无所谓。
+
+类型变量之间的半统一有点不同。
+不同级别的类型变量不得相互施加类型约束。
+
+```python
+# BAD
+f x (: ?V<2>), y (: ?W<2>) =
+ # ?V<2>(<: ?T<1>)
+ # ?T<1>(:> ?V<2>)
+ id(x) (: ?U<1>) + y (: ?W<2>)
+```
+
+这使得无法确定在何处实例化类型变量。
+对于 Type 类型变量,执行正常统一而不是半统一。
+也就是说,统一到下层。
+
+```python
+# OK
+f x (: ?V<2>), y (: ?W<2>) =
+ # ?V<2> --> ?T<1>
+ id(x) (: ?U<1>) + y (: ?W<2>)
+```
+
+```python
+f x (: ?T<1>), y (: ?W<2>) =
+ (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], inst |'L <: Add('R)| ('L, 'R) -> 'L .AddO)
+```
+
+```python
+f x (: ?T<1>), y (: ?W<2>) =
+ (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], (?L(<: Add(?R<2>))<2>, ?R<2 >) -> ?L<2>.AddO)
+```
+
+```python
+id: ?T<1> -> ?U<1>
+f x (: ?T<1>), y (: ?W<2>) =
+ # ?U<1>(<: Add(?W<2>)) # Inherit the constraints of ?L
+ # ?L<2> --> ?U<1>
+ # ?R<2> --> ?W<2> (not ?R(:> ?W), ?W(<: ?R))
+ (id(x) + x) (: ?U<1>.AddO)
+```
+
+```python
+# current_level = 1
+f(x, y) (: gen ?T<1>, gen ?W<2> -> gen ?U<1>.AddO) =
+ id(x) + x
+```
+
+```python
+id: ?T<1> -> ?U<1>
+f(x, y) (: |'W: Type| (?T<1>, 'W) -> gen ?U<1>(<: Add(?W<2>)).AddO) =
+ id(x) + x
+```
+
+```python
+f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) =
+ id(x) + x
+```
+
+定义时,提高层次,使其可以泛化。
+
+```python
+# ?T<1 -> 2>
+# ?U<1 -> 2>
+id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>)
+```
+
+如果已经分配了返回类型,则与结果类型统一(`?U<2> --> ?T<2>`)。
+
+```python
+# ?U<2> --> ?T<2>
+f(x, y) (: |'W: Type| (?T<2>, 'W) -> ?T<2>(<: Add(?W<2>)).AddO) =
+ id(x) + x
+# current_level = 1
+id(x) (: gen ?T<2> -> gen ?T<2>) = x (: ?T<2>)
+```
+
+如果类型变量已经被实例化为一个简单的类型变量,
+依赖于它的类型变量也将是一个 Type 类型变量。
+广义类型变量对于每个函数都是独立的。
+
+```python
+f(x, y) (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) =
+ id(x) + x
+id(x) (: |'T: Type| 'T -> gen 'T) = x
+```
+
+```python
+f x, y (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) =
+ id(x) + y
+id(x) (: 'T -> 'T) = x
+
+f(10, 1) (: subst_call_ret([inst {10}, inst {1}], inst |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T .AddO)
+```
+
+```python
+f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<1>) -> ? T<1>.AddO))
+```
+
+类型变量绑定到具有实现的最小类型
+
+```python
+# ?T(:> {10} <: Add(?W<1>))<1>
+# ?W(:> {1})<1>
+# ?W(:> {1})<1> <: ?T<1> (:> {10}, <: Add(?W(:> {1})<1>))
+# serialize
+# {1} <: ?W<1> or {10} <: ?T<1> <: Add({1}) <: Add(?W<1>)
+# Add(?W)(:> ?V) 的最小实现特征是 Add(Nat) == Nat,因为 Add 相对于第一个参数是协变的
+# {10} <: ?W<1> or {1} <: ?T<1> <: Add(?W<1>) <: Add(Nat) == Nat
+# ?T(:> ?W(:> {10}) or {1}, <: Nat).AddO == Nat # 如果只有一个候选人,完成评估
+f(10, 1) (: (?W(:> {10}, <: Nat), ?W(:> {1})) -> Nat)
+# 程序到此结束,所以去掉类型变量
+f(10, 1) (: ({10}, {1}) -> Nat)
+```
+
+整个程序的结果类型是:
+
+```python
+f|W: Type, T <: Add(W)|(x: T, y: W): T.AddO = id(x) + y
+id|T: Type|(x: T): T = x
+
+f(10, 1): Nat
+```
+
+我还重印了原始的、未明确键入的程序。
+
+```python
+fx, y = id(x) + y
+id x = x
+
+f(10, 1)
+```
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/overview.md b/doc/zh_CN/compiler/overview.md
new file mode 100644
index 00000000..933d2021
--- /dev/null
+++ b/doc/zh_CN/compiler/overview.md
@@ -0,0 +1,38 @@
+# `erg` 概览
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/overview.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+我们将介绍每一层的功能以及特别重要的功能和方法。
+
+## 1. 词法分析
+
+* `Lexer` 进行词法分析。 `Lexer::next`(`Lexer`被实现为一个迭代器)负责词法分析的主要逻辑。 `Token` 作为解析的结果输出。
+
+## 2. 解析
+
+* `Parser` 进行解析。特别重要的是`Parser::parse_expr`。作为解析的结果,输出作为`ast::Expr`的集合的`AST`。
+
+## 3. 脱糖
+
+* 脱糖由 `Desugarer` 完成。 `AST` 将被输出。
+
+## 4. 类型检查/类型推断
+
+* `ASTLowerer` 进行打字。类型检查主要由 `Context` 完成。尤其重要的是 `Context::supertype_of`(确定子类型关系)、`Context::unify/sub_unify`(统一/半统一类型变量)、`Context::init_builtin_*`(定义内置 API)。 `HIR` 作为分析结果输出。
+
+## 5. 副作用检查
+
+* `SideEffectChecker` 可以。
+
+## 6. 所有权检查
+
+* `OwnershipChecker` 可以。
+
+## 7. 字节码生成
+
+* `CodeGenerator` 将 `HIR` 转换为 `CodeObj`。 `CodeObj` 保存字节码和执行配置。特别重要的是`CodeGenerator::compile_expr`。
+
+---
+
+* 以上所有的处理都是由`Compiler`作为一个门面组合起来的。
+* 当然 Python 会执行生成的字节码,称为 `DummyVM`。
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/parsing.md b/doc/zh_CN/compiler/parsing.md
new file mode 100644
index 00000000..1db31cde
--- /dev/null
+++ b/doc/zh_CN/compiler/parsing.md
@@ -0,0 +1,35 @@
+# 解析 Erg 语言
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/parsing.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 空格的处理
+
+Erg语法的一个特点是它对空间敏感。
+这是为了弥补因省略`()`而造成的表达力损失。在 Nim 中可以找到类似的语法,它也允许省略 `()`。
+
+```python
+f +1 == f(+1)
+f + 1 == `+`(f, 1)
+f (1,) == f((1,))
+f(1,) == f(1)
+(f () -> ...) == f(() -> ...)
+(f() -> ...) == (f() -> ...)
+```
+
+## 左值,右值
+
+在 Erg 中,左侧的值并不像 `=` 的左侧那么简单。
+事实上,`=` 左侧有一个右值(非常令人困惑),而 `=` 右侧有一个左值。
+右值中甚至可以有左值。
+
+```python
+# i 是左边的值,Array(Int) 和 [1, 2, 3] 是右边的值
+i: Array(Int) = [1, 2, 3]
+# `[1, 2, 3].iter().map i -> i + 1`是右边的值,但是->左边的i是左边的值
+a = [1, 2, 3].iter().map i -> i + 1
+# {x = 1; y = 2} 是右侧值,但 x, y 是左侧值
+r = {x = 1; y = 2}
+```
+
+左侧和右侧值的精确定义是“如果它是可评估的,则为右侧值,否则为左侧值”。
+例如,考虑代码 ``i = 1; i``,其中第二个 `i` 是右侧值,因为它是可评估的,但第一个 `i` 是左侧值。
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/refinement_subtyping.md b/doc/zh_CN/compiler/refinement_subtyping.md
new file mode 100644
index 00000000..de5b0c36
--- /dev/null
+++ b/doc/zh_CN/compiler/refinement_subtyping.md
@@ -0,0 +1,149 @@
+# 筛子类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/refinement_subtyping.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
+{I: Int | I >= 0}
+{S: StrWithLen N | N >= 1}
+{T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0}
+```
+
+Erg 通过将 Enum 和 Interval 类型转换为筛选类型来实现类型确定。
+
+## 转换为筛型
+
+在 [Sieve types] 一节中,我们说过区间类型和枚举类型是 sieve 类型的语法糖。每个转换如下。
+
+* {0} -> {I: Int | I == 0}
+* {0, 1} -> {I: Int | I == 0 or I == 1}
+* 1.._ -> {I: Int | I >= 1}
+* 1<.._ -> {I: Int | I > 1} -> {I: Int | I >= 2}
+* {0} or 1.._ -> {I: Int | I == 0 or I >= 1}
+* {0} or {-3, -2} or 1.._ -> {I: Int | I == 0 or (I == -2 or I == -3) or I >= 1}
+* {0} and {-3, 0} -> {I: Int | I == 0 and (I == -3 or I == 0)}
+* {0} not {-3, 0} or 1.._ -> {I: Int | I == 0 and not (I == -3 or I == 0) or I >= 1}
+
+## 筛型检测
+
+描述了一种用于确定筛类型 A 是否是另一筛类型 B 的子类型的算法。正式地,(所有)子类型定义如下:
+
+```console
+A <: B <=> ∀a∈A; a∈B
+```
+
+具体而言,应用以下推理规则。假定布尔表达式是简化的。
+
+* 间隔规则(从类型定义自动完成)
+ * `Nat` => `{I: Int | I >= 0}`
+* 围捕规则
+ * `{I: Int | I < n}` => `{I: Int | I <= n-1}`
+ * `{I: Int | I > n}` => `{I: Int | I >= n+1}`
+ * `{R: Ratio | R < n}` => `{R: Ratio | R <= n-ε}`
+ * `{R: Ratio | R > n}` => `{R: Ratio | R >= n+ε}`
+* 反转规则
+ * `{A not B}` => `{A and (not B)}`
+* 德摩根规则
+ * `{not (A or B)}` => `{not A and not B}`
+ * `{not (A and B)}` => `{not A or not B}`
+* 分配规则
+ * `{A and (B or C)} <: D` => `{(A and B) or (A and C)} <: D` => `({A and B} <: D) and ( {A and C} <: D)`
+ * `{(A or B) and C} <: D` => `{(C and A) or (C and B)} <: D` => `({C and A} <: D) and ( {C and B} <: D)`
+ * `D <: {A or (B and C)}` => `D <: {(A or B) and (A or C)}` => `(D <: {A or B}) and ( D <: {A or C})`
+ * `D <: {(A and B) or C}` => `D <: {(C or A) and (C or B)}` => `(D <: {C or A}) and ( D <: {C or B})`
+ * `{A or B} <: C` => `({A} <: C) and ({B} <: C)`
+ * `A <: {B and C}` => `(A <: {B}) and (A <: {C})`
+* 终止规则
+ * {I: T | ...} <: T = True
+ * {} <: _ = True
+ * _ <: {...} = True
+ * {...} <: _ = False
+ * _ <: {} == False
+ * {I >= a and I <= b} (a < b) <: {I >= c} = (a >= c)
+ * {I >= a and I <= b} (a < b) <: {I <= d} = (b <= d)
+ * {I >= a} <: {I >= c or I <= d} (c >= d) = (a >= c)
+ * {I <= b} <: {I >= c or I <= d} (c >= d) = (b <= d)
+ * {I >= a and I <= b} (a <= b) <: {I >= c or I <= d} (c > d) = ((a >= c) or (b <= d ))
+ * 基本公式
+ * {I >= l} <: {I >= r} = (l >= r)
+ * {I <= l} <: {I <= r} = (l <= r)
+ * {I >= l} <: {I <= r} = False
+ * {I <= l} <: {I >= r} = False
+
+布尔表达式的简化规则如下。 min, max 不能被删除。此外,多个 or, and 被转换为嵌套的 min, max。
+
+* 组合规则
+ * `I == a` => `I >= a 和 I <= a`
+ * `i != a` => `I >= a+1 或 I <= a-1`
+* 一致性规则
+ * `I >= a 或 I <= b (a < b)` == `{...}`
+* 恒常规则
+ * `I >= a 和 I <= b (a > b)` == `{}`
+* 替换规则
+ * 以 `I >= n` 和 `I <= n` 的顺序替换顺序表达式。
+* 扩展规则
+ * `I == n 或 I >= n+1` => `I >= n`
+ * `I == n 或 I <= n-1` => `I <= n`
+* 最大规则
+ * `I <= m 或 I <= n` => `I <= max(m, n)`
+ * `I >= m 和 I >= n` => `I >= max(m, n)`
+* 最低规则
+ * `I >= m 或 I >= n` => `I >= min(m, n)`
+ * `I <= m 和 I <= n` => `I <= min(m, n)`
+* 淘汰规则
+ * 当 `I >= a (n >= a)` 或 `I <= b (n <= b)` 或 `I == n` 在右侧时,左侧的 `I == n` 被删除能够。
+ * 如果无法消除所有左手方程,则为 False
+
+例如
+
+```python
+1.._<: Nat
+=> {I: Int | I >= 1} <: {I: Int | I >= 0}
+=> {I >= 1} <: {I >= 0}
+=> (I >= 0 => I >= 1)
+=> 1 >= 0
+=> True
+# {I >= l} <: {I >= r} == (l >= r)
+# {I <= l} <: {I <= r} == (l <= r)
+```
+
+```python
+{I: Int | I >= 0} <: {I: Int | I >= 1 or I <= -3}
+=> {I >= 0} <: {I >= 1 or I <= -3}
+=> {I >= 0} <: {I >= 1} or {I >= 0} <: {I <= -3}
+=> False or False
+=> False
+```
+
+```python
+{I: Int | I >= 0} <: {I: Int | I >= -3 and I <= 1}
+=> {I >= 0} <: {I >= -3 and I <= 1}
+=> {I >= 0} <: {I >= -3} and {I >= 0} <: {I <= 1}
+=> True and False
+=> False
+```
+
+```python
+{I: Int | I >= 2 or I == -2 or I <= -4} <: {I: Int | I >= 1 or I <= -1}
+=> {I >= 2 or I <= -4 or I == -2} <: {I >= 1 or I <= -1}
+=> {I >= 2 or I <= -4} <: {I >= 1 or I <= -1}
+ and {I == -2} <: {I >= 1 or I <= -1}
+=> {I >= 2} <: {I >= 1 or I <= -1}
+ and {I <= -4} <: {I >= 1 or I <= -1}
+ and
+ {I == -2} <: {I >= 1}
+ or {I == -2} <: {I <= -1}
+=> {I >= 2} <: {I >= 1}
+ or {I >= 2} <: {I <= -1}
+ and
+ {I <= -4} <: {I >= 1}
+ or {I <= -4} <: {I <= -1}
+ and
+ False or True
+=> True or False
+ and
+ False or True
+ and
+ True
+=> True and True
+=> True
+```
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/trait_method_resolving.md b/doc/zh_CN/compiler/trait_method_resolving.md
new file mode 100644
index 00000000..fff36fad
--- /dev/null
+++ b/doc/zh_CN/compiler/trait_method_resolving.md
@@ -0,0 +1,97 @@
+# 解决补丁方法
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/trait_method_resolving.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`Nat` 是零个或多个`Int`,`Int` 的子类型。
+`Nat` 在 Python 类层次结构中不存在。 我想知道 Erg 是如何解决这个补丁方法的?
+
+```python
+1.times do:
+ log "hello world"
+```
+
+`.times` 是一种 `NatImpl` 补丁方法。
+由于`1`是`Int`的一个实例,首先通过跟踪`Int`的MRO(方法解析顺序)来搜索它。
+Erg 在 `Int` 的 MRO 中有 `Int`、`Object`。它来自 Python(Python 中的`int.__mro__ == [int, object]`)。
+`.times` 方法在它们中都不存在。现在让我们探索那个子类型。
+
+~
+
+整数显然应该在其超类型中包含实数、复数甚至整数,但这一事实并没有出现在 Python 兼容层中。
+然而,`1 in Complex` 和 `1 in Num` 在 Erg 中实际上是 `True`。
+至于`Complex`,即使是与`Int`没有继承关系的类,也被判断为类型兼容。这到底是怎么回事?
+
+~
+
+一个对象有无数种它所属的类型。
+但是我们真的只需要考虑带有方法的类型,即带有名称的类型。
+
+Erg 编译器有一个补丁类型的哈希图,其中包含所有提供的方法及其实现。
+每次定义新类型时都会更新此表。
+
+```python
+provided_method_table = {
+ ...
+ "foo": [Foo],
+ ...
+ ".times": [Nat, Foo],
+ ...
+}
+```
+
+具有 `.times` 方法的类型是 `Nat`、`Foo`。从这些中,找到与“{1}”类型匹配的一个。
+有两种类型的符合性确定。它们是筛式判断和记录式判断。这是通过筛子类型确定来完成的。
+
+##筛型确定
+
+检查候选类型是否与 `1` 的类型 `{1}` 兼容。与“{1}”兼容的筛子类型有“{0, 1}”、“0..9”等。
+有限元代数类型,例如 `0..1 或 3..4`、`-1..2 和 0..3`,在声明为基本类型(即 {0, 1, 3, 4}`,`{0, 1, 2}`)。
+在这种情况下,`Nat` 是 `0.._ == {I: Int | I >= 0}`,所以 `{1}` 与 `Nat` 兼容。
+
+## 确定记录类型
+
+检查候选类型是否与 `Int` 兼容,1 类。
+其他是`Int`的修复程序并且`Int`具有所有必需属性的也是兼容的。
+
+~
+
+所以`Nat`适合。但是,如果 `Foo` 也匹配,则由 `Nat` 和 `Foo` 之间的包含关系决定。
+即,选择子类型方法。
+如果两者之间没有包含关系,则会发生编译错误(这是一种安全措施,防止违背程序员的意图执行方法)。
+要消除错误,您需要明确指定补丁。
+
+```python
+o.method(x) -> P.method(o, x)
+```
+
+## 通用方法解析修补程序
+
+像这样定义一个补丁:
+
+```python
+FnType T: Type = Patch T -> T
+FnType.type = T
+```
+
+在 `FnType` 补丁下可以使用如下代码。 我想知道这将如何解决。
+
+```python
+assert (Int -> Int).type == Int
+```
+
+首先,`FnType(T)` 以下列格式注册到`provided_method_table` 中。
+
+```python
+provided_method_table = {
+ ...
+ "type": [FnType(T)],
+ ...
+}
+```
+
+`FnType(T)` 检查匹配类型。 在这种情况下,`FnType(T)` 补丁类型是 `Type -> Type`。
+这匹配 `Int -> Int`。 如果合适,进行单态化和替换(取 `T -> T` 和 `Int -> Int`、`{T => Int}` 的差异)。
+
+```python
+assert FnType(Int).type == Int
+```
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/transpile.md b/doc/zh_CN/compiler/transpile.md
new file mode 100644
index 00000000..2027f17b
--- /dev/null
+++ b/doc/zh_CN/compiler/transpile.md
@@ -0,0 +1,92 @@
+# Erg 代码如何转译成 Python 代码?
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/transpile.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+准确地说,Erg 代码被转译为 Python 字节码。
+但是,由于 Python 字节码几乎可以重构为 Python 代码,因此这里以等效的 Python 代码为例。
+顺便说一句,这里展示的示例是低优化级别。
+更高级的优化消除了不需要实例化的东西。
+
+## 记录,记录类型
+
+它将被转译为一个命名元组。
+对于 namedtuple,请参阅 [此处](https://docs.python.jp/3/library/collections.html#collections.namedtuple)。
+有一个类似的函数,dataclass,但是由于 `__eq__` 和 `__hash__` 的自动实现,dataclass 的性能略有下降。
+
+```python
+Employee = Class {.name = Str; .id = Int}
+
+employee = Employee.new({.name = "John Smith"; .id = 100})
+
+assert employee.name == "John Smith"
+```
+
+```python
+from typing import NamedTuple
+
+class Employee(NamedTuple):
+ __records__ = ['name', 'id']
+ name: str
+ id: int
+
+employee = Employee('John Smith', 100)
+
+assert employee.name == 'John Smith'
+```
+
+如果可以进一步优化,它也将转换为简单的元组。
+
+## 多态类型
+
+> 在制品
+
+## 即时范围
+
+如果没有发生命名空间冲突,它只会被破坏和扩展。
+`x::y` 等名称在字节码中使用,不能与 Python 代码关联,但如果强制表示,则会如下所示。
+
+```python
+x =
+ y = 1
+ y+1
+```
+
+```python
+x::y = 1
+x = x::y + 1
+```
+
+万一发生冲突,定义和使用只能在内部引用的函数。
+
+```python
+x =
+ y = 1
+ y+1
+```
+
+```python
+def _():
+ x=1
+ y = x
+ return y + 1
+x = _()
+```
+
+## 可见性
+
+它对公共变量没有任何作用,因为它是 Python 的默认值。
+私有变量由 mangling 处理。
+
+```python
+x=1
+y =
+ x = 2
+ assert module::x == 2
+```
+
+```python
+module::x = 1
+y::x = 2
+assert module::x == 2
+y = None
+```
\ No newline at end of file
diff --git a/doc/zh_CN/compiler/type_var_normalization.md b/doc/zh_CN/compiler/type_var_normalization.md
new file mode 100644
index 00000000..31f4785e
--- /dev/null
+++ b/doc/zh_CN/compiler/type_var_normalization.md
@@ -0,0 +1,41 @@
+# 归一化
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/type_var_normalization.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+* Erg 的类型参数规范化基于 SymPy 的简化函数。
+
+例如,当您定义 `concat: |T, M, N|([T; M], [T; N] -> [T; M+N])` 时,您可以匹配类型变量和参数而无需实例化它们.必须作出判断。
+平等判断自然有其局限性,但目前可能的判断及其方法如下。
+
+* 加法/乘法对称性:
+
+ `n+m == m+n`
+
+ 类型变量被排序和规范化为字符串。
+
+* 加法、乘法、减法和除法等价:
+
+ `n+n == 2*n`
+
+ 归一化为 Σ[c] x == c*x,其中 c 是一个常数。
+ 常量通过将它们放在二进制操作的左侧进行标准化。
+
+* 双重表达式的相等性:
+
+ `n+m+l == m+n+l == l+m+n == ...`
+ `n+m*l == m*l+n`
+
+ 通过排序归一化确定。
+ 乘法和除法块放置在加法和减法的左侧。通过比较最左侧的类型变量对块进行排序。
+
+* 基本不等式:
+
+ `n > m -> m + 1 > n`
+
+* 平等:
+
+ `n >= m 和 m >= n -> m == n`
+
+* 不等式的传递性:
+
+ `n > 0 -> n > -1`
\ No newline at end of file
diff --git a/doc/zh_CN/dev_guide/branches.md b/doc/zh_CN/dev_guide/branches.md
new file mode 100644
index 00000000..e7f01c04
--- /dev/null
+++ b/doc/zh_CN/dev_guide/branches.md
@@ -0,0 +1,37 @@
+# 分支机构命名和运营策略
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/branches.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1)
+
+## main
+
+* 主要开发分支
+* 必须满足以下条件
+
+* 编译成功
+
+## beta(目前不创建)
+
+* 最新的 Beta 版本
+* 必须满足以下条件
+
+* 编译成功
+* 所有测试都会成功
+
+## feature-*
+
+* 开发特定功能的分支
+* 切开 main
+
+* 没有条件
+
+## issue-*
+
+* 解决特定 issue 的分支
+
+* 没有条件
+
+## fix-*
+
+* 修复特定错误的分支(如果该问题是一个错误,则代替`issue-*`创建)。
+
+* 没有条件。
\ No newline at end of file
diff --git a/doc/zh_CN/dev_guide/build_features.md b/doc/zh_CN/dev_guide/build_features.md
new file mode 100644
index 00000000..507b6b48
--- /dev/null
+++ b/doc/zh_CN/dev_guide/build_features.md
@@ -0,0 +1,23 @@
+# `erg` 构建功能
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/build_features.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 调试
+
+进入调试模式。结果,Erg 内部的行为顺序显示在日志中。
+独立于 Rust 的 `debug_assertions` 标志。
+
+## japanese
+
+将系统语言设置为日语。
+Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为日语。
+
+## simplified_chinese
+
+将系统语言设置为简体中文。
+Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为简体中文。
+
+## traditional_chinese
+
+将系统语言设置为繁体中文。
+Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为繁体中文。
\ No newline at end of file
diff --git a/doc/zh_CN/dev_guide/directories.md b/doc/zh_CN/dev_guide/directories.md
new file mode 100644
index 00000000..7f8a7867
--- /dev/null
+++ b/doc/zh_CN/dev_guide/directories.md
@@ -0,0 +1,26 @@
+# Erg存储表结构
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/directories.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1)
+
+```console
+ └─┬ assets:图片等
+ ├─ CODE_OF_CONDUCT:行为准则
+ ├─┬ compiler
+ │ ├─ erg_common:通用工具
+ │ ├─ erg_compiler
+ │ └─ erg_parser:解析器
+ ├─┬ doc: 文档
+ │ ├─┬ CN
+ │ │ ├─ API:Erg标准API
+ │ │ ├─ compiler:关于编译器实现
+ │ │ ├─ dev_guide:开发者和贡献者指南
+ │ │ ├─ python:Erg开发必备的Python知识
+ │ │ ├─ syntax:Erg语法
+ │ │ └─ tools:Erg命令行工具
+ │ └─┬ JA
+ │ ...
+ ├─ examples:示例代码
+ ├─ library:Erg脚本库
+ ├─ src:main.rs和驱动所在目录
+ └─ tests:测试代码
+```
\ No newline at end of file
diff --git a/doc/zh_CN/dev_guide/doc_guideline.md b/doc/zh_CN/dev_guide/doc_guideline.md
new file mode 100644
index 00000000..07749069
--- /dev/null
+++ b/doc/zh_CN/dev_guide/doc_guideline.md
@@ -0,0 +1,15 @@
+# 格式
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/doc_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+任何不符合以下规则的文件都将得到更正。
+
+* 以某种语气写代码注释或内部文档。
+* 向外部(普通用户)展示的文档应该越来越多地编写。
+* 始终包含定义、含义或文档中首次出现的术语的链接。
+* 仅对理解正文所必需的补充句子使用括号作为附加条件,对于理解正文不是必需的句子使用脚注[1 ]( #1)。
+* 如果文档内容过时,按照【此方法】更新(https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)。
+
+---
+
+1 参见这里了解如何编写脚注。[↩](#f1)
\ No newline at end of file
diff --git a/doc/zh_CN/dev_guide/env.md b/doc/zh_CN/dev_guide/env.md
new file mode 100644
index 00000000..ab2a43a1
--- /dev/null
+++ b/doc/zh_CN/dev_guide/env.md
@@ -0,0 +1,21 @@
+# 开发环境
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## 你需要安装什么
+
+* Rust(与 rustup 一起安装)
+
+ * 版本 >= 1.63.0
+ * 2021年版
+
+* [预提交](https://pre-commit.com/)
+
+* Python3 解释器
+
+## 推荐
+
+* 编辑器:Visual Studio Code
+* VSCode 扩展:Rust-analyzer、GitLens、Git Graph、GitHub Pull Requests and Issues、Markdown All in One、markdownlint
+* 操作系统:Windows 10/11 | Ubuntu 20.04/22.04 | Mac OS Monterey
+* 其他:pyenv、模具
\ No newline at end of file
diff --git a/doc/zh_CN/dev_guide/faq_syntax.md b/doc/zh_CN/dev_guide/faq_syntax.md
new file mode 100644
index 00000000..5f236bfe
--- /dev/null
+++ b/doc/zh_CN/dev_guide/faq_syntax.md
@@ -0,0 +1,106 @@
+# Erg design's "Why" and Answers
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/faq_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 当我们有所有权系统时,为什么要与 GC 共存?
+
+因为 Erg 推出所有权系统的动机并不是为了 Rust 那样的“不依赖 GC 的内存管理”。最初,由于 Erg 是一种语言,目前使用 Python VM,因此最终仍使用 GC。Erg 引入产权系统的目标是“可变状态的局部化”。在 Erg 中,可变对象具有所有权概念。这是根据共享可变状态容易成为 bug 的温床,甚至是类型安全性的侵犯(详见)来判断的。
+
+## 为什么类型参数周围的括号不是 <> 或 []?
+
+因为在和中会发生语法冲突。
+
+```python
+# []版
+id[T: Type] [t]: [T] = t
+y = id[Int] # 这是一个功能吗?
+# <>版
+id {t: T} = t
+y = (id 1) # 这是一个元组吗?
+# {}版
+id{T: Type} {t: T} = t
+y = id{Int} # 这是一个功能吗?
+# ||版
+id|T: Type| t: T = t
+y = id|Int| # OK
+```
+
+## {i=1} 的类型为 {i=Int},但在 OCaml 等环境中为 {i:Int}。为什么 Erg 采用前者的语法?
+
+Erg 设计为将类型本身也视为值。
+
+```python
+A = [Int; 3]
+assert A[2] == Int
+T = (Int, Str)
+assert T.1 == Str
+D = {Int: Str}
+assert D[Int] == Str
+S = {.i = Int}
+assert S.i == Int
+```
+
+## 你打算在 Erg 中实现宏吗?
+
+目前没有。宏观大致分为四个目的。第一个是编译时计算。这在 Erg 中由编译时函数负责。第二,代码执行的延迟。这可以用 do 块来代替。第三个是处理通用化,对此多相关数和全称类型是比宏观更好的解决方案。第四个是自动生成代码,但这会造成可读性的下降,所以我们不敢在 Erg 中实现。因此,宏的大部分功能都由 Erg 型系统承担,因此没有动力进行部署。
+
+## 为什么 Erg 没有例外机制?
+
+在许多情况下,错误处理类型是更好的解决方案。类型 是一种错误处理方法,通常在较新的编程语言中使用。
+
+在 Erg 中,运算符使你可以在不太注意错误的情况下编写。
+
+```python
+read_file!() =
+ f = open!("foo.txt")? # 如果失败则立即返回错误,所以 f 是文件类型
+ f.read_all!()
+
+# 也可以使用 try 过程捕获类似的异常
+try!:
+ do!
+ s = read_file!()?
+ print! s
+ e =>
+ # 发生错误时执行的块
+ print! e
+ exit 1
+```
+
+在引入 Python 函数时,缺省情况下,所有函数都被视为包含异常,返回类型为。如果你知道不调度异常,请在 中指明。
+
+此外,Erg 没有引入异常机制的另一个原因是它计划引入并行编程的功能。这是因为异常机制与并行执行不兼容(例如,如果并行执行导致多个异常,则很难处理)。
+
+## Erg 似乎消除了 Python 被认为是坏做法的功能,但为什么没有取消继承?
+
+Python 的库中有一些类设计为继承,如果完全取消继承,这些操作就会出现问题。然而,由于 Erg 的类默认为 final,并且原则上禁止多重和多层继承,因此继承的使用相对安全。
+
+## 为什么多相关数的子类型推理默认指向记名trait?
+
+默认情况下,指向结构托盘会使类型指定变得复杂,并且可能会混合程序员的非预期行为。
+
+```python
+# 如果 T 是结构特征的子类型...
+# f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T
+f|T| x, y: T = x + y - x
+# T 是名义特征的子类型
+# g: |T <: Add() and Sub()| (T, T) -> T
+g|T| x, y: T = x + y - x
+```
+
+## Erg 是否实现了定义自己的运算符的功能?
+
+A:没有那个计划。最重要的原因是,如果允许定义自己的运算符,就会出现如何处理组合顺序的问题。可以定义自己的运算符的 Scala 和 Haskell 等都有不同的对应,但这可以看作是可能产生解释差异的语法的证据。此外,独立运算符还有一个缺点,那就是可能产生可读性较低的代码。
+
+## 为什么 Erg 取消了 += 这样的扩展赋值运算符?
+
+首先,Erg 中没有变量的可变性。也就是不能重新赋值。一旦对象与一个变量关联,它将一直绑定到该变量,直到它脱离作用域并被释放。在 Erg 中,可变性是指对象的可变性。明白了这个,故事就简单了。例如,表示 ,但由于变量是不可重新赋值的,因此这种语法是非法的。还有一个 Erg 的设计原则是运算符没有副作用。Python 通常也是如此,但对于某些对象(如 Dict),扩展赋值运算符会更改对象的内部状态。这算不上是一个很漂亮的设计。因此,扩展赋值运算符被完全废弃。
+
+## 为什么 Erg 在语法上特别对待有副作用的过程?
+
+副作用的局部化是代码维护的一个关键因素。
+
+但是,确实也不是没有方法可以不在语言上特殊对待副作用。例如,可以用代数效果(类型系统上的功能)替代过程。但这样的合一并不总是正确的。例如,Haskell 没有对字符串进行特殊处理,只是一个字符数组,但这种抽象是错误的。
+
+什么情况下,可以说合一化是错的?一个指标是“是否会因其合一而难以看到错误信息”。Erg 设计师发现,将副作用特殊处理会使错误消息更容易阅读。
+
+Erg 有一个强大的类型系统,但并不是所有的类型都决定了它。如果这样做了,你的下场就跟 Java 试图用类来控制一切一样。
\ No newline at end of file
diff --git a/doc/zh_CN/dev_guide/i18n_messages.md b/doc/zh_CN/dev_guide/i18n_messages.md
new file mode 100644
index 00000000..96f6eceb
--- /dev/null
+++ b/doc/zh_CN/dev_guide/i18n_messages.md
@@ -0,0 +1,57 @@
+# 多语言错误信息
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/i18n_messages.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+Erg 正在推动消息(开始、选项、文档、提示、警告、错误消息等)的多语言化。如果你不熟悉 Rust 或 Erg,也可以参与此项目。请务必配合。
+
+以下是多语种方法的说明。
+
+## 查找`switch_lang!`
+
+在 Erg 源代码中找到(使用 grep 或编辑器的搜索功能)。我们应该能找到下面这样的东西。
+
+```rust
+switch_lang!(
+ "japanese" => format!("この機能({name})はまだ正式に提供されていません"),
+ "english" => format!("this feature({name}) is not implemented yet"),
+),
+```
+
+此消息目前仅支持日语和英语。让我们尝试添加简体消息。
+
+## 添加消息
+
+请在查看其他语言内容的同时添加翻译消息。最后不要忘记逗号(,)。
+
+```rust
+switch_lang!(
+ "japanese" => format!("この機能({name})はまだ正式に提供されていません"),
+ "simplified_chinese" => format!("该功能({name})还没有正式提供"),
+ "english" => format!("this feature({name}) is not implemented yet"),
+),
+```
+
+另外,英语是默认设置,一定要排在最后。
+
+`{name}`部分是 Rust 的格式化功能,允许你将变量的内容(`name`)嵌入到字符串中。
+
+## 构建
+
+现在,我们使用选项构建它。
+
+
+
+你做到了!
+
+## FAQ
+
+Q:像这样的指定是什么意思?A:{RED} 及更高版本将显示为红色。重新启动交互渲染。
+
+Q:如果想添加自己的语言,该如何替换部分?答:目前支持以下语言。
+
+* "english"(默认设置)
+* "japanese" (日语)
+* "simplified_chinese" (简体中文)
+* "traditional_chinese" (繁体中文)
+
+如果你想添加其他语言,请提出请求。
\ No newline at end of file
diff --git a/doc/zh_CN/dev_guide/index.md b/doc/zh_CN/dev_guide/index.md
new file mode 100644
index 00000000..0e41be9e
--- /dev/null
+++ b/doc/zh_CN/dev_guide/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/index.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96)
+
diff --git a/doc/zh_CN/dev_guide/rust_code_guideline.md b/doc/zh_CN/dev_guide/rust_code_guideline.md
new file mode 100644
index 00000000..24c4e3e4
--- /dev/null
+++ b/doc/zh_CN/dev_guide/rust_code_guideline.md
@@ -0,0 +1,25 @@
+# Rust 代码指南
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/rust_code_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## 本地规则
+
+* 使用 `log!` 进行调试输出(使用 `println!` 等进行输出处理,这也是发布所必需的)。
+* 未使用或内部变量/方法(私有且仅用于特定功能)必须以 `_` 为前缀。如果要避免与保留字冲突,请在末尾添加一个`_`。
+
+## 推荐代码
+
+* 定义和使用特定领域的枚举而不是数字枚举或布尔值。
+* 将访问修饰符保持在最低限度。即使在发布时也要优先使用 `pub(mod)` 或 `pub(crate)`。
+* 将 for 表达式中的可迭代对象显式转换为迭代器(`for i in x.iter()` 而不是 `for i in x`)。
+* 懒惰的评价。例如,如果 `default` 不是文字,请使用 `unwrap_or_else` 而不是 `unwrap_or`。
+
+## 不鼓励使用代码
+
+* 大量使用返回类型重载。特别是使用大量非显而易见的 `.into` 的代码。这是因为类型推断结果可能违反直觉。在这种情况下,建议使用 `from` 代替。
+* 大量使用 `Deref`。这有效地提出了与继承相同的问题。
+
+## 根据上下文做出决策的代码
+
+* 定义未使用的辅助方法。
+* 大量使用 `unwrap` 和 `clone`。在某些情况下,没有什么比这样做更好的了。
\ No newline at end of file
diff --git a/doc/zh_CN/dev_guide/terms.md b/doc/zh_CN/dev_guide/terms.md
new file mode 100644
index 00000000..66bf0055
--- /dev/null
+++ b/doc/zh_CN/dev_guide/terms.md
@@ -0,0 +1,840 @@
+# 词汇表
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 象征
+
+### !
+
+添加到标识符末尾的标记以指示它是过程,变量类型或变异运算符。
+
+### [#](../syntax/00_basic.md/# comment)
+
+### $
+
+### %
+
+### &
+
+### ′ (single quote)
+
+### ()
+
+### *
+
+### +
+
+### ,
+
+### −
+
+### ->
+
+### .
+
+### /
+
+### :
+
+### ::
+
+### ;
+
+### <
+
+### <:
+
+### <<
+
+### <=
+
+### =
+
+### ==
+
+### =>
+
+### >
+
+### >>
+
+### >=
+
+### ?
+
+### @
+
+### []
+
+### \
+
+### ^
+
+### ^^
+
+### _
+
+### ``
+
+### {}
+
+### {:}
+
+### {=}
+
+### |
+
+### ||
+
+### ~
+
+## A
+
+### [algebraic type]
+
+### [And]
+
+### [and]
+
+### [assert]
+
+### [attribute]
+
+## B
+
+### [Base]
+
+### [Bool]
+
+## C
+
+### [Class]
+
+## D
+
+### Deprecated
+
+### [distinct]
+
+## E
+
+### [enum type]
+
+### [Eq]
+
+### [Erg]
+
+## F
+
+### [for]
+
+## G
+
+## H
+
+## I
+
+### [if]
+
+### [import]
+
+### [in]
+
+### [Int]
+
+## J
+
+## K
+
+## L
+
+### let-polymorphism -> [rank 1 polymorphism]
+
+### [log]
+
+## M
+
+### [match]
+
+## N
+
+### [Nat]
+
+### Never
+
+### None
+
+### [Not]
+
+### [not]
+
+## O
+
+### [Option]
+
+### [Or]
+
+### [or]
+
+### [Ord]
+
+## P
+
+### panic
+
+### [print!](../syntax/../API/procs.md#print)
+
+### [Python]
+
+## Q
+
+## R
+
+### ref
+
+### ref!
+
+### [Result]
+
+### [rootobj]
+
+## S
+
+### self
+
+### [Self](../syntax/type/special.md)
+
+### [side-effect](../syntax/07_side_effect.md)
+
+### [Str]
+
+## T
+
+### Traits
+
+### [True]
+
+### [Type]
+
+### [type]
+
+## U
+
+## V
+
+## W
+
+### [while!]
+
+## X
+
+## Y
+
+## Z
+
+## A line
+
+### [Assertion]
+
+检查(通常在运行时)代码中的条件是否为真。 这是使用 `assert` 函数等来完成的。
+
+```python
+sum = !0
+for! 0..10, i =>
+ sum.add!i
+
+assert sum == 55
+```
+
+### 值对象
+
+在 Erg 中,相当于基础对象。 它可以在编译时进行评估,并且具有简单的比较方法。
+
+### [附件补丁](../syntax/29_decorator.md#attach)
+
+为特征提供标准实现的补丁。
+
+### Ad hoc 多态性 -> [无重载](../syntax/type/overloading.md)
+
+具有所谓重载的多态性。
+
+### 属性-> [属性]
+
+`x.y` 标识符中的 `y` 部分。
+
+### Arity
+
+运算符需要多少个操作数。
+
+### [依赖类型](../syntax/type/dependent_type.md)
+
+参数是值的类型(习惯上说,不是类型)。
+
+### 不可变 -> [不可变]
+
+表示目标不会改变。
+其他语言中的变量也是不可变/可变的,但是在 Erg 中所有的变量都是不可变的。
+
+### 参数 -> [参数]
+
+### 实例
+
+由类创建的对象。 类类型的元素。
+
+### [即时封锁](../syntax/00_basic.md#expression separator)
+
+```python
+x =
+ y = f(a)
+ z = g(b,c)
+ y+z
+```
+
+### 指数
+
+形式为“x[i]”,或其“i”部分。我们称 `x` 为 Indexable 对象。
+
+### [缩进](../syntax/00_basic.md#indent)
+
+通过向空格移动将文本向右对齐。缩进。
+Ergs 通过缩进表示块。这称为越位规则。
+
+### 别名
+
+别名。
+
+### 错误
+
+规范中定义的异常情况。
+
+* [错误处理]
+
+### [运算符](../syntax/06_operator.md)
+
+将操作应用于其操作数的对象。或表示该对象的符号。
+
+* [运算符绑定强度]
+
+### 覆盖
+
+在子类中覆盖超类方法。
+在 Erg 中,您必须在覆盖时添加 `Override` 装饰器。
+
+### [不重载](../syntax/type/overloading.md)
+
+### 越位规则-> [缩进](../syntax/00_basic.md#indent)
+
+### [目的]
+
+* 面向对象
+
+### 操作数 -> [操作数](../syntax/06_operator.md)
+
+### 运算符 -> [运算符](../syntax/06_operator.md)
+
+##嘉线
+
+### [种类](../syntax/type/advanced/kind.md)
+
+所谓类型的类型。
+
+### [可见性]
+
+标识符是否可以被外部引用(超出范围,或在另一个模块或包中)的属性。
+
+### [类型]
+
+对术语进行分组的对象。
+
+* [类型规格]
+* [类型擦除](../syntax/type/advanced/erasure.md)
+* [类型推断]
+* [类型注释](../syntax/type/conv_type.md)
+* [类型参数]
+* [类型添加](../syntax/type/advanced/erasure.md)
+* [类型变量](../syntax/type/type_variable.md)
+* [类型约束]
+
+### 监视
+
+### 封装
+
+隐藏实现细节。
+
+### [多变的]
+
+不能是一成不变的。
+
+* [可变对象]
+* [多变的]
+* [变量参考]
+* [变量数组]
+* [可变参数]
+
+### [函数](../syntax/04_function.md)
+
+没有副作用的子程序。
+
+* [函数式编程](../syntax/23_scope.md#避免可变状态函数式编程)
+
+### 基本类型
+
+###主格
+
+通过名称而不是对称结构来区分。
+
+* [命名类型] -> [类](../syntax/type/04_class.md)
+* [报喜]
+* [名义子类型](../syntax/type/05_nst_vs_sst.md)
+
+### 捕获-> [关闭]
+
+### [协变]
+
+在 Erg 中,如果 `T <: U` 则 `K(T) <: K(U)` 则称 `K` 是协变的。
+
+### [关键字参数]
+
+`k` 以函数调用 `f(k: v)` 的形式出现。您可以通过形式参数名称而不是按顺序指定实际参数。
+
+### 空集 -> [{}]
+
+### 部分
+
+* [区间类型](../syntax/type/11_interval.md)
+* 区间运算符
+
+### 嵌入式
+
+Erg 标准 API 未在 .er 文件中实现。
+
+### [类](../syntax/type/04_class.md)
+
+具有继承功能的结构/抽象数据类型。在 Erg 中,它是一种实现命名子类型化和覆盖的类型。
+在 Erg 中,模块是模块对象负责,类型是类型对象,而其他语言可能负责模块和类型。
+
+### [关闭]
+
+### [全局变量]
+
+### [克隆]
+
+### [继承](../syntax/type/07_inheritance.md)
+
+定义一个类是另一个类的父类集。
+继承的类称为超类,继承的类称为子类。
+子类具有其超类的所有功能。
+
+### 高楼层
+
+* [高阶种类](../syntax/type/advanced/kind.md)
+* 高阶类型
+* 高阶函数
+
+### [公共变量]
+
+### [结构子类型]
+
+### ~~后向引用~~ -> [后向引用]
+
+### [复制]
+
+### 评论
+
+### [集合](../syntax/10_array.md)
+
+### 冒号 -> [:]
+
+### [构造函数](../syntax/type/04_class.md)
+
+### 容器
+
+### 编译器
+
+### [编译时计算](../syntax/04_function.md#compile-time function)
+
+### 逗号 -> [,]
+
+## sa线
+
+### 递归
+
+参考自己。
+
+* 递归
+* [递归函数](../syntax/04_function.md#递归函数)
+
+### 下标 -> [索引]
+
+### [子类型多态性](../syntax/type/overloading.md)
+
+具有子类型的多态性。子类型对应于类型中的集合包含。
+
+### 子程序
+
+模块化处理的对象。 Erg 中函数、过程和方法的通用术语。
+
+### [参考](../syntax/18_memory_management.md#borrowed)
+
+* 参考对象
+* [引用计数 (RC)](../syntax/18_memory_management.md#memory management)
+* 引用相等 -> [副作用](../syntax/07_side_effect.md)
+
+### [标识符](../syntax/02_variable.md/# 赋值)
+
+### 签名
+
+* 类型签名
+
+### [dict](../syntax/11_dict.md)
+
+### 自然数 -> Nat
+
+### 泛型 -> 泛型
+
+### 发电机
+
+### 投影类型
+
+### 借用-> [参考](../syntax/18_memory_management.md#borrowed)
+
+### [阴影](../syntax/02_name.md# variables)
+
+通过在内部范围内定义具有相同名称的变量来覆盖对变量的引用。
+
+### kind -> [kind](../syntax/type/advanced/kind.md)
+
+大致类型的类型。
+
+### set -> set
+
+在 Erg 中,它表示一个 Set 对象。
+
+### 谓词
+
+* 谓词函数
+
+返回布尔类型的函数。
+
+### 条件分支
+
+### 所有权
+
+对象唯一性的概念。
+如果您拥有对象的所有权,则可以使用 mutable 参考它。
+
+### Boolean -> Bool
+
+### 单例
+
+从只能创建一个实例的类创建的实例。一种设计模式,可确保只创建一个类的一个实例。
+
+### [Symbol] -> [Identifier](../syntax/02_name.md)
+
+* 符号化
+
+### [脚本](../syntax/00_basic.md# 脚本)
+
+包含 Erg 程序的文件。
+
+### 范围
+
+变量管理单元。外部作用域不能引用内部作用域中存在的变量。
+当范围退出时,引用计数为 0 的对象将被释放。
+
+### 扩展运算符 -> expansion assignment
+
+### [切片](../syntax/10_array.md#slice)
+
+表示数组子序列的对象,以 `x[a..b]` 的形式生成。
+
+### 控制字符
+
+### 整数 -> Int
+
+一组自然数加上负数。
+
+### [设置](../syntax/12_set.md)
+
+### 分号 -> ;
+
+### [声明](../syntax/03_declaration.md)
+
+显式类型变量。
+
+### 全名
+
+* 通用类型 -> [多态类型](../syntax/type/quantified.md)
+ * 封闭式通用
+ * 打开通用
+* 通用函数 -> 多相关函数
+* 通用量化
+
+### 前缀运算符
+
+运算符 `∘` 以 `∘x` 的形式应用。
+
+### 相互递归
+
+### 下标 -> index
+
+### 属性
+
+* 属性子类型
+
+## 塔线
+
+### [代数](../syntax/02_name.md)
+
+* [代数类型](../syntax/type/13_algebraic.md)
+* 代数数据类型
+
+### [赋值](../syntax/02_variable.md/#assignment)
+
+### 多
+
+* [多重继承](../syntax/type/07_inheritance.md/#禁止多重继承)
+* 多重赋值
+* 重载 -> [不重载]
+
+### 多态性
+
+* [多态类型](../syntax/type/quantified.md)
+* 多相关系数
+
+### 多态性 -> [多态性]
+
+### 鸭子类型
+
+### [元组](../syntax/11_tuple.md)
+
+### 单相
+
+* 单相
+* 单相型
+* 单相关系数
+
+### [延迟初始化]
+
+### 提取分配
+
+### 抽象语法树 -> [AST]
+
+### 中缀运算符
+
+运算符 `∘` 以 `x∘y` 的形式应用。
+
+### [常数](../syntax/02_name.md/#constant)
+
+不可变的,编译时可评估的代数。
+
+* [常量类型](../syntax/type/advanced/const.md)
+* [常量表达式](../syntax/type/advanced/const.md)
+
+### 定义
+
+分配与变量对应的对象。
+
+### 提供的属性
+
+可作为 API 使用的属性。特别是由特征自动实现的属性。
+
+### 申请
+
+将参数传递给函数对象并获取评估结果。
+
+### [装饰器](../syntax/29_decorator.md)
+
+``` python
+@deco
+f x = ...
+```
+
+语法糖,或“装饰”。大致等于`_f x = ...; f = 装饰 _f`。 `deco` 本身只是一个高阶子程序。
+
+### 析构函数
+
+对象被销毁时调用的方法。
+
+### 程序 -> [procedure](../syntax/08_procedure.md)
+
+读取和写入可变状态的子程序。
+有时会说程序的执行结果可以根据调用过程的顺序而改变,但如果我们谈论交换性,这是不正确的。
+例如,作为函数子类型的运算符通常不可交换。
+
+### [默认参数](../syntax/04_function.md/#default arguments default-parameters)
+
+通过指定形式参数的默认值,可以在调用时省略实际参数的指定的函数。
+
+### 扩张
+
+* 扩展运算符
+* 扩展分配
+
+### [特殊格式](../syntax/../API/special.md)
+
+不能作为实际参数传递的对象。
+
+### 匿名函数 -> [anonymous function](../syntax/20_lambda.md)
+
+由匿名函数运算符`->`创建的函数对象。可以在不定义名称的情况下使用。
+
+### 点运算符 (`.`) -> attribute reference
+
+### 顶部
+
+* 顶部类型 -> [结构对象]
+* 顶级 -> [对象]
+
+### [特征](../syntax/type/03_trait.md)
+
+## na line
+
+### [理解](../syntax/27_comprehension.md)
+
+### ~~中缀运算符~~ -> 中缀运算符
+
+### 命名空间
+
+## 是一行
+
+### [数组](../syntax/10_array.md)
+
+### [派生类型](../syntax/type/variances.md/# 用户定义的类型变体)
+
+### [模式(匹配)](../syntax/26_pattern_matching.md)
+
+### [包](../syntax/33_package_system.md)
+
+### hashmap -> [dict](../syntax/11_dict.md)
+
+### [补丁](../syntax/type/07_patch.md)
+
+### 公共变量-> [public variables](../syntax/19_visibility.md)
+
+### 参数 -> [argument](../syntax/04_function.md)
+
+### [参数多态](../syntax/type/overloading.md)
+
+### [逆变](../syntax/type/advanced/variance.md)
+
+### 相比
+
+* 比较运算符
+* 可比类型
+
+### [私有变量](../syntax/19_visibility.md)
+
+### 标准
+
+* 标准输出
+* 标准输入
+* 标准库
+
+### [副作用](../syntax/07_side_effect.md)
+
+代码应该/不应该读/写外部可变状态。
+
+### 复数 -> 复数
+
+### 浮动 -> 浮动
+
+### 私有变量 -> 私有变量
+
+### 布尔代数-> Bool
+
+### [程序](../syntax/08_procedure.md)
+
+### [参数](../syntax/04_function.md)
+
+### 部分类型 -> Subtyping
+
+### [不可变]
+
+在 Erg 中,一个对象永远不应该改变它的内容。
+
+* [不可变对象]
+* [不可变类型]
+* [不可变引用]
+
+### [筛子类型](../syntax/type/12_refinement.md)
+
+### [堵塞]
+
+### 解构赋值
+
+### [变量](../syntax/02_variable.md)
+
+### 底部
+
+* 底部类型 -> [{}]
+* 底层 -> [从不]
+
+### [多态性]
+
+## ma line
+
+### ~~ 前缀运算符 ~~ -> 前缀运算符
+
+### [标记类型](../syntax/type/advanced/marker_trait.md)
+
+### [匿名函数](../syntax/21_lambda.md)
+
+### 可变 -> [可变]
+
+### [移动]
+
+### 方法
+
+### 元字符
+
+### [模块](../syntax/24_module.md)
+
+### [字符串] -> [字符串]
+
+* [字符串插值](../syntax/01_literal.md/#Str 字面量)
+
+### 返回值
+
+## 或行
+
+### [幻像类型](../syntax/type/advanced/phantom.md)
+
+### 请求属性
+
+### [元素]
+
+### [称呼]
+
+## 拉线
+
+### [图书馆]
+
+### lambda 表达式 -> [匿名函数](../syntax/20_lambda.md)
+
+### 排名
+
+* [rank2 多态性](../syntax/type/advanced/rank2type.md)
+
+### [文字](../syntax/01_literal.md)
+
+* [文字标识符](../syntax/18_naming_rule.md/#literal identifier)
+
+### [量化](../syntax/type/quantified.md)
+
+### [布局](../syntax/type/mut.md)
+
+### [枚举](../syntax/type/10_enum.md)
+
+### [记录](../syntax/12_record.md)
+
+* [记录类型]
+* 记录多态 -> Column Polymorphism
+
+### 列多态
+
+### [局部变量](../syntax/19_visibility.md)
+
+## 线
+
+### 通配符
\ No newline at end of file
diff --git a/doc/zh_CN/dev_guide/unify_terms.md b/doc/zh_CN/dev_guide/unify_terms.md
new file mode 100644
index 00000000..1161bf5b
--- /dev/null
+++ b/doc/zh_CN/dev_guide/unify_terms.md
@@ -0,0 +1,58 @@
+# 术语统一
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/unify_terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 可访问性,可见性
+
+使用可见性。
+
+## 类型绑定,类型约束
+
+给定量化和细化类型的谓词表达式列表。使用类型边界。
+
+## 子程序、例程、子程序
+
+使用子程序。
+
+## 引用透明/不透明,有/没有副作用
+
+使用有/无副作用。
+
+## 标识符、代数、变量、名称、符号
+
+就其本义而言,
+
+* 符号:在源代码中实心编写的字符(符号、控制字符等除外),不是字符串对象(未包含在“”中)。符号在 Ruby、Lisp 等中作为原始类型存在,但在 Erg 中它们不被视为对象。
+* 标识符:(并且可以)引用某个对象的符号,而不是保留字。例如,在 Python 中 class 和 def 不能用作标识符。由于 Erg 没有保留字,所以除了某些符号外,所有符号都可以用作标识符。
+* 名称:与标识符的含义几乎相同。它有时与 Erg 中的代数同义使用。
+* 代数名称:相当于Erg中的标识符。在 C 中,函数名称是标识符,而不是代数名称。 “代数”指的是语言特性本身,它允许您使用 `=`(变量赋值运算符)或 `=`(常量赋值运算符)来分配对象。
+
+```python
+代数名称<:(名称==标识符)<:符号
+变量 + 常数 == 代数
+```
+
+然而,应该称为“代数”的东西,往往被称为“变量”。这就是数学术语的效果。
+值内容可以改变的变量是可变变量,值内容不改变的变量是不可变变量。
+请注意,常量始终是不可变的。
+
+Erg 中不使用代数名称和名称,使用统一标识符。
+但是,一般来说,具有 `v = 1` 的 `v` 称为“变量 v”,而具有 `C = 1` 的 `C` 称为“常量 C”。 .
+
+## 属性、字段、属性
+
+使用属性。顺便说一句,记录是一个函数,它可以定义一个没有类的具有元素属性的对象。
+
+## 应用程序,调用
+
+为子例程对象提供参数并获得结果。
+使用呼叫。这是因为Application有“应用软件”的用法。
+
+## 数组列表
+
+使用数组。 Erg 数组(通常)在内存中是连续的。
+List 是指所谓的链表,或者说列表作为 Python 数据类型。
+
+## lambda 函数、lambda 表达式、匿名函数
+
+与匿名函数统一。在英文中,可以使用 Lambda 来缩短字符数,但正式名称是 Anonymous function。
\ No newline at end of file
diff --git a/doc/zh_CN/faq_general.md b/doc/zh_CN/faq_general.md
new file mode 100644
index 00000000..92293ab9
--- /dev/null
+++ b/doc/zh_CN/faq_general.md
@@ -0,0 +1,39 @@
+# Erg常见问题
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_general.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
+This FAQ is intended for the general Erg beginner.
+For individual (common) technical issues, please refer to [here](./faq_technical.md) for individual (common) technical issues, and
+[Here](./dev_guide/faq_syntax.md) for more information.
+
+## Erg 是 Python 兼容语言是什么意思?
+
+~~A:Erg的可执行系统EVM(Erg VirtualMachine)执行Erg字节码,是Python字节码的扩展。它在 Python 字节码中引入了静态类型系统和其他特性(例如向不带参数的指令引入参数,以及在自由编号中实现唯一指令)。这让 Erg 可以无缝调用 Python 代码并快速执行。~~
+
+A: Erg 代码被转译成 Python 字节码。也就是说,它运行在与 Python 相同的解释器上。最初,我们计划开发一个兼容 Cpython 的解释器,并将其与编译器结合起来形成“Erg”。但是,由于处理系统的发展远远落后于编译器,我们决定提前只发布编译器(但解释器仍在开发中)。
+
+## 哪些语言影响了Erg?
+
+我们受到的语言多于我们双手所能指望的数量,但 Python、Rust、Nim 和 Haskell 的影响最大。
+我们从 Python 继承了许多语义,从 Rust 继承了面向表达式和 trait,从 Nim 继承了过程,从 Haskell 继承了函数式编程相关的特性。
+
+## 可以调用 Python 的语言包括 Julia。你为什么创建 Erg?
+
+答:Erg 设计的动机之一是拥有一种易于使用且具有强大类型系统的语言。即具有类型推断、种类、依赖类型等的语言。
+Julia 是可以有类型的,但它确实是一种动态类型语言,不具备静态类型语言的编译时错误检测优势。
+
+## Erg 支持多种编程风格,包括函数式和面向对象的编程。这不是与 Python 的“应该有一种——最好只有一种——明显的方法”相反吗?
+
+答:在 Erg 中,该术语是在更狭窄的上下文中使用的。例如,Erg API 中一般没有别名;在这种情况下,Erg是“唯一一种方式”。
+在更大的上下文中,例如 FP 或 OOP,只有一种做事方式并不一定很方便。
+例如,JavaScript 有几个库可以帮助创建不可变的程序,而 C 有几个用于垃圾收集的库。
+然而,即使是这样的基本功能也有多个库不仅需要时间来选择,而且在集成使用不同库的代码时也会产生很大的困难。
+即使在纯函数式语言 Haskell 中,也有支持 OOP 的库。
+如果程序员没有一些东西,他们会自己创造它们。因此,我们认为将它们作为标准提供会更好。
+这也符合 Python 的“含电池”概念。
+
+## Erg 这个名字的由来是什么?
+
+它以cgs单位系统中的能量单位erg命名。它具有双重含义:一种为程序员提供能量的符合人体工程学的语言。
+
+还有其他几个候选者,但之所以选择它是因为它最短(根据 Ruby 的开发者 Matz 的说法,语言名称越短越好)并且具有相当高的可搜索性。
\ No newline at end of file
diff --git a/doc/zh_CN/faq_technical.md b/doc/zh_CN/faq_technical.md
new file mode 100644
index 00000000..2af1fe74
--- /dev/null
+++ b/doc/zh_CN/faq_technical.md
@@ -0,0 +1,35 @@
+# 技术常见问题
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_technical.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e)
+
+本节回答有关使用 Erg 语言的技术问题。换句话说,它包含以 What 或 Which 开头的问题,以及可以用 Yes/No 回答的问题。
+
+有关如何确定语法的更多信息,请参阅 [此处](./dev_guide/faq_syntax.md) 了解基础语法决策,以及 [此处](./dev_guide/../faq_general.md)。
+
+## Erg 中有异常机制吗?
+
+答:不会。Erg 使用 `Result` 类型代替。请参阅 [此处](./dev_guide/faq_syntax.md) 了解 Erg 没有异常机制的原因。
+
+## Erg 是否有与 TypeScript 的 `Any` 等价的类型?
+
+答:不,没有。所有对象都至少属于 `Object` 类,但是这种类型只提供了一组最小的属性,所以你不能像使用 Any 那样对它做任何你想做的事情。
+`Object` 类通过`match` 等动态检查转换为所需的类型。它与Java 和其他语言中的`Object` 是同一种。
+在 Erg 世界中,没有像 TypeScript 那样的混乱和绝望,其中 API 定义是“Any”。
+
+## Never、{}、None、()、NotImplemented 和 Ellipsis 有什么区别?
+
+A:`Never` 是一种“不可能”的类型。产生运行时错误的子例程将“Never”(或“Never”的合并类型)作为其返回类型。该程序将在检测到这一点后立即停止。尽管 `Never` 类型在定义上也是所有类型的子类,但 `Never` 类型的对象永远不会出现在 Erg 代码中,也永远不会被创建。 `{}` 等价于 `Never`。
+`Ellipsis` 是一个表示省略号的对象,来自 Python。
+`NotImplemented` 也来自 Python。它被用作未实现的标记,但 Erg 更喜欢产生错误的 `todo` 函数。
+`None` 是 `NoneType` 的一个实例。它通常与 `Option` 类型一起使用。
+`()` 是一个单元类型和它自己的一个实例。当您想要返回“无意义的值”(例如过程的返回值)时使用它。
+
+## 为什么 `x = p!()` 有效但 `f() = p!()` 会导致 EffectError?
+
+`!` 不是副作用产品的标记,而是可能导致副作用的对象。
+过程 `p!` 和可变类型 `T!` 会引起副作用,但如果 `p!()` 的返回值是 `Int` 类型,它本身就不再引起副作用。
+
+## 当我尝试使用 Python API 时,对于在 Python 中有效的代码,我在 Erg 中收到类型错误。这是什么意思?
+
+A:Erg API 的类型尽可能接近 Python API 规范,但有些情况无法完全表达。
+此外,根据规范有效但被认为不合需要的输入(例如,在应该输入 int 时输入浮点数)可能会被 Erg 开发团队酌情视为类型错误。
\ No newline at end of file
diff --git a/doc/zh_CN/improved_points.md b/doc/zh_CN/improved_points.md
new file mode 100644
index 00000000..8bf32e6f
--- /dev/null
+++ b/doc/zh_CN/improved_points.md
@@ -0,0 +1,50 @@
+# Python 的改进
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/improved_points.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
+## 执行静态分析(静态类型检查、变量和属性检查)
+
+静态类型检查的好处现在怎么强调都不为过,但是检查变量和属性的存在也是相当重要的一部分。
+
+## 严格范围处理
+
+在 Python 中,语句没有范围。
+因此,在 `for` 或 `if` 中定义的变量具有外部影响。 不能随便命名变量。
+
+```python
+for i in range(10):
+ x = 1
+ print(i + x)
+print(x) # 1
+```
+
+在 Erg 中,所有块都有范围并且是完全隔离的。
+
+## 明确区分可变对象和不可变对象
+
+Python并不清楚可变和不可变/堆和值对象之间的区别,因此您必须记住元组是不可变的但列表是可变的......您需要记住元组是不可变的,但列表是可变的 ... 等等。
+另外,如果你想让你自己的类不可变,你必须经历一个乏味的过程。
+
+```python
+# 你能相信这段代码对过去的 Python 版本有效吗?
+i = 256
+assert i is 256
+i = 257
+assert i is not 257
+```
+
+## Traits
+
+就像 Java 的接口一样,你可以进行基于契约的编程。
+
+Python 也有 ABC(抽象基类),但这种结构最适合静态类型。
+
+## 静态解决依赖关系
+
+这可以防止长时间运行程序然后由于缺少模块而出现错误的烦人体验。
+
+## 内置包管理器
+
+具有标准化目录结构和构建文件的可重现构建。
+当然提供了锁定文件生成和版本控制。
+无需为每个项目选择或混合anaconda、pyenv、诗歌等。
diff --git a/doc/zh_CN/index.md b/doc/zh_CN/index.md
new file mode 100644
index 00000000..b331eef8
--- /dev/null
+++ b/doc/zh_CN/index.md
@@ -0,0 +1,27 @@
+# 索引
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/index.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
+## [API/](./API/index.md)
+
+ 本节介绍 Erg 的内置或标准库提供的子程序、类型、常量等的规范。
+
+## [compiler/](./compiler/index.md)
+
+ 描述 Erg 编译器的设计(厘米)
+
+## [dev_guide/](./dev_guide/index.md)
+
+ 它解释了项目的发展政策,如何做出贡献等。
+
+## [python/](./python/index.md)
+
+ 解释了开发 Erg 所需的 Python 知识。
+
+## [syntax/](./syntax/00_basic.md)
+
+ Erg 的语法进行了解释。
+
+## [tools/](./tools/index.md)
+
+ 解释如何使用 Erg 的外围工具和命令选项。
\ No newline at end of file
diff --git a/doc/zh_CN/migration_from_py.md b/doc/zh_CN/migration_from_py.md
new file mode 100644
index 00000000..aafb570c
--- /dev/null
+++ b/doc/zh_CN/migration_from_py.md
@@ -0,0 +1,27 @@
+# 从 Python 迁移到 Erg 的提示
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/migration_from_py.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 我想将字符串转换为 int 等。
+
+使用 `Str` 类的 `parse` 方法。 它返回一个 `Result` 类型。
+
+```python
+s: str
+i: int = int(s)
+```
+
+```python
+s: Str
+res: Result(Int, IntParseError) = s. parse Int
+i: Int = res.unwrap()
+f: Result(Float, FloatParseError) = s. parse Float
+```
+
+您还可以使用 `try_from` 方法。
+
+```python
+s: Str
+i: Int = Int.try_from(s).unwrap()
+f: Float = Float.try_from(s).unwrap()
+```
\ No newline at end of file
diff --git a/doc/zh_CN/python/bytecode_instructions.md b/doc/zh_CN/python/bytecode_instructions.md
new file mode 100644
index 00000000..5b43757b
--- /dev/null
+++ b/doc/zh_CN/python/bytecode_instructions.md
@@ -0,0 +1,118 @@
+# Python 字节码指令
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_instructions.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+Python 字节码变量操作命令通过 名称索引(名称索引)访问。 这是为了在 Python 中实现动态变量访问(可以使用 eval 等作为字符串访问)。
+一条指令为 2 个字节,指令和参数以 little endian 形式存储。
+不带参数的指令也使用 2 个字节(参数部分为 0)。
+
+## STORE_NAME(名称索引)
+
+```python
+globals[namei] = stack.pop()
+```
+
+## LOAD_NAME(名称索引)
+
+```python
+stack.push(globals[namei])
+```
+
+Only called at top level.
+
+## LOAD_GLOBAL(名称索引)
+
+```python
+stack.push(globals[namei])
+```
+
+用于加载内部作用域顶层的STORE_NAME,但顶层的`名称索引`不一定与某个作用域的代码对象中的名称索引相同(名称相同,名称索引不一定)
+
+## LOAD_CONST(名称索引)
+
+```python
+stack.push(consts[namei])
+```
+
+在常量表中加载常量。
+目前(Python 3.9),在 CPython 中,每个 lambda 函数都是 MAKE_FUNCTION,名称为“\”
+
+```console
+>>> dis.dis("[1,2,3].map(lambda x: x+1)")
+1 0 LOAD_CONST 0 (1)
+ 2 LOAD_CONST 1 (2)
+ 4 LOAD_CONST 2 (3)
+ 6 BUILD_LIST 3
+ 8 LOAD_ATTR 0 (map)
+ 10 LOAD_CONST 3 ( at 0x7f272897fc90, file "", line 1>)
+ 12 LOAD_CONST 4 ('')
+ 14 MAKE_FUNCTION 0
+ 16 CALL_FUNCTION 1
+ 18 RETURN_VALUE
+```
+
+## STORE_FAST(名称索引)
+
+fastlocals[namei] = stack.pop()
+可能对应于顶层的 STORE_NAME
+假定未引用(或单个)变量由此存储
+全局空间有自己的指令是为了优化吗?
+
+## LOAD_FAST(名称索引)
+
+```python
+stack.push(fastlocals[namei])
+```
+fastlocals 是变量名吗?
+
+## LOAD_CLOSURE(名称索引)
+
+```python
+cell = freevars[namei]
+stack. push(cell)
+```
+
+然后调用 BUILD_TUPLE
+它只在闭包内被调用,并且 cellvars 应该在闭包内存储引用。
+与 LOAD_DEREF 不同,每个单元格(填充有引用的容器)都被推入堆栈
+
+## STORE_DEREF(名称索引)
+
+```python
+cell = freevars[namei]
+cell.set(stack.pop())
+```
+
+在内部范围内没有引用的变量是 STORE_FAST,但引用的变量是 STORE_DEREF
+在 Python 中,引用计数在该指令内递增和递减
+
+## LOAD_DEREF(名称索引)
+
+```python
+cell = freevars[namei]
+stack.push(cell.get())
+```
+
+## 名称列表
+
+### 变量名
+
+fast_locals 对应的函数内部变量名称列表
+即使名称中有同名的变量,它们也基本不一样(新创建的和外部变量不能从那个范围访问)
+即没有在范围内定义的外部引用的变量进入 varnames
+
+### 名字
+
+与全局兼容
+范围内使用的外部常量(仅引用)的名称列表(在顶层,即使是普通变量也包含在名称中)
+即在范围之外定义的常量进入名称
+
+## 自由变量
+
+与免费变量兼容
+闭包捕获的变量。它在同一个函数实例中静态地运行。
+
+## 单元格变量
+
+对应于 cellvars
+在函数内捕获到内部闭包函数的变量。 由于制作了副本,因此原始变量保持原样。
\ No newline at end of file
diff --git a/doc/zh_CN/python/bytecode_specification.md b/doc/zh_CN/python/bytecode_specification.md
new file mode 100644
index 00000000..9f79f3fa
--- /dev/null
+++ b/doc/zh_CN/python/bytecode_specification.md
@@ -0,0 +1,145 @@
+# Python bytecode specification
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_specification.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)
+
+## Format
+
+* 0~3 byte(u32): magic number (see common/bytecode.rs for details)
+* 4~7 byte(u32): 0 padding
+* 8~12 byte(u32): timestamp
+* 13~ byte(PyCodeObject): code object
+
+## PyCodeObject
+
+* 0 byte(u8): '0xe3' (prefix, this means code's 'c')
+* 01~04 byte(u32): number of args (co_argcount)
+* 05~08 byte(u32): number of position-only args (co_posonlyargcount)
+* 09~12 byte(u32): number of keyword-only args (co_kwonlyargcount)
+* 13~16 byte(u32): number of locals (co_nlocals)
+* 17~20 byte(u32): stack size (co_stacksize)
+* 21~24 byte(u32): flags (co_flags) ()
+* ? byte: bytecode instructions, ends with '0x53', '0x0' (83, 0): RETURN_VALUE (co_code)
+* ? byte(PyTuple): constants used in the code (co_consts)
+* ? byte(PyTuple): names used in the code (co_names)
+* ? byte(PyTuple): variable names defined in the code, include params (PyTuple) (co_varnames)
+* ? byte(PyTuple): variables captured from the outer scope (co_freevars)
+* ? byte(PyTuple): variables used in the inner closure (co_cellvars)
+* ? byte(PyUnicode or PyShortAscii): file name, where it was loaded from (co_filename)
+* ? byte(PyUnicode or PyShortAscii): the name of code itself, default is \ (co_name)
+* ?~?+3 byte(u32): number of first line (co_firstlineno)
+* ? byte(bytes): line table, represented by PyStringObject? (co_lnotab)
+
+## PyTupleObject
+
+* 0 byte: 0x29 (means ')')
+* 01~04 byte(u32): number of tuple items
+* ? byte(PyObject): items
+
+## PyStringObject
+
+* If I use a character other than ascii, does it become PyUnicode?
+* "あ", "𠮷", and "α" are PyUnicode (no longer used?)
+
+* 0 byte: 0x73 (means 's')
+* 1~4 byte: length of string
+* 5~ byte: payload
+
+## PyUnicodeObject
+
+* 0 byte: 0x75 (means 'u')
+* 1~4 byte: length of string
+* 5~ byte: payload
+
+## PyShortAsciiObject
+
+* This is called short, but even if there are more than 100 characters, this will still short
+* or rather, there is no ascii that is not short (is short a data type?)
+
+* 0 byte: 0xFA (means 'z')
+* 1~4 byte: length of string
+* 5~ byte: payload
+
+## PyInternedObject
+
+* interned objects are registered in a dedicated map and can be compared with is
+* String, for example, can be compared in constant time regardless of its length
+
+* 0 byte: 0x74 (means 't')
+
+## PyShortAsciiInternedObject
+
+* 0 byte: 0xDA (means 'Z')
+* 1~4 byte: length of string
+* 5~ byte: payload
+
+# Python 字节码规范
+
+## 格式
+
+* 0~3 byte(u32):幻数(详见common/bytecode.rs)
+* 4~7 byte(u32): 0 padding
+* 8~12 byte(u32): 时间戳
+* 13~ byte(PyCodeObject): 代码对象
+
+## PyCode 对象
+
+* 0 byte(u8): '0xe3' (前缀,这意味着代码的'c')
+* 01~04 byte(u32): args个数(co_argcount)
+* 05~08 byte(u32): position-only args 的数量 (co_posonlyargcount)
+* 09~12 byte(u32):仅关键字参数的数量(co_kwonlyargcount)
+* 13~16 byte(u32): 本地数 (co_nlocals)
+* 17~20 byte(u32): 栈大小(co_stacksize)
+* 21~24 byte(u32):标志(co_flags)()
+* ? byte:字节码指令,以'0x53'、'0x0'结尾(83, 0):RETURN_VALUE(co_code)
+* ? byte(PyTuple):代码中使用的常量(co_consts)
+* ? byte(PyTuple):代码中使用的名称(co_names)
+* ? byte(PyTuple):代码中定义的变量名,包括params (PyTuple) (co_varnames)
+* ? byte(PyTuple):从外部范围捕获的变量(co_freevars)
+* ? byte(PyTuple):内部闭包中使用的变量(co_cellvars)
+* ? byte(PyUnicode 或 PyShortAscii):文件名,它是从哪里加载的(co_filename)
+* ? byte(PyUnicode or PyShortAscii): 代码本身的名字,默认是\ (co_name)
+* ?~?+3 byte(u32): 第一行数 (co_firstlineno)
+* ? byte(bytes):行表,用 PyStringObject? (co_lnotab)
+
+## PyTupleObject
+
+* 0 byte: 0x29 (意思是:')')
+* 01~04 byte(u32): 元组项数
+* ? byte(PyObject):项目
+
+## PyString 对象
+
+* 如果我使用 ascii 以外的字符,它会变成 PyUnicode 吗?
+* “あ”、“𠮷”和“α”是 PyUnicode(不再使用?)
+
+* 0 byte:0x73(表示's')
+* 1~4 byte:字符串长度
+* 5~ byte:有效载荷
+
+## PyUnicode 对象
+
+* 0 byte:0x75(表示“u”)
+* 1~4 byte:字符串长度
+* 5~ byte:有效载荷
+
+## PyShortAsciiObject
+
+* 这叫短,但是即使超过100个字符,仍然会保持在短的状态
+* 或者更确切地说,没有不短的 ascii(短数据类型吗?)
+
+* 0 byte:0xFA(表示“z”)
+* 1~4 byte:字符串长度
+* 5~ byte:有效载荷
+
+## PyInternedObject
+
+* 实习对象注册在专用地图中,可以与is进行比较
+* 例如字符串,无论其长度如何,都可以在恒定时间内进行比较
+
+* 0 byte:0x74(表示't')
+
+## PyShortAsciiInternedObject
+
+* 0 byte:0xDA(表示“Z”)
+* 1~4 byte:字符串长度
+* 5~ byte:有效载荷
\ No newline at end of file
diff --git a/doc/zh_CN/python/class_system.md b/doc/zh_CN/python/class_system.md
new file mode 100644
index 00000000..e7e2debc
--- /dev/null
+++ b/doc/zh_CN/python/class_system.md
@@ -0,0 +1,96 @@
+# Python 类系统(与 Erg 比较)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/class_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 方法
+
+方法可以被前向引用,但这不是一种特殊的技术。
+这是因为动态检查方法的存在。
+(在 Erg 中,方法存在是静态检查的。对于前向引用,函数必须是常量。)
+
+```python
+>>> class C:
+... def f(self, x):
+... if x == 0: return 0
+... else: return self.g(x)
+... def g(self, x): return self.f(x - 1)
+```
+
+## 继承,覆盖
+
+一些被覆盖的方法 m 被简单地覆盖,就像变量重新分配一样。
+在父类中引用 m 的方法将在子类中引用被覆盖的 m。
+
+```python
+>>> class C:
+... def f(self): return 1
+... def g(self): return self.f()
+...
+>>> class D(C):
+... def f(self): return 2
+...
+>>>> D().g()
+2
+```
+
+因此,即使它显然被错误地覆盖,直到运行时才会出错。
+
+```python
+>>>> class C:
+... def f(self): return 1
+... def g(self): return self.f() + 1
+...
+>>> class D(C):
+... def f(self): return "a"
+...
+>>> D().g()
+Traceback (most recent call last):
+ File "", line 1, in ", line 3, in g
+类型错误:只能将str(不是“int”)连接到str
+```
+
+Erg 静态检查与父类的一致性。
+重写时必须给出“Override”装饰器,并且重写函数的类型必须是被重写函数类型的子类型。
+
+```python
+>>> C = Class()
+... .f self = 1
+... .g self = self.f() + 1
+...
+>>> D = Inherit C
+... .f self = "a"
+...
+错误[#XX]:文件“”,第 5 行,在 D 中
+要覆盖 f,必须添加 `Override` 装饰器,其类型必须是 `Self.() -> Nat` 或其子类型
+f(self) 已在 C 中定义。要覆盖 f,必须添加 `Override` 装饰器,其类型必须为 `Self. 要覆盖,必须给它一个 `Override` 装饰器,并且它的类型必须是 `Self.() -> Nat` 或 that.f(self) 的子类型。
+```
+
+## 类型检查
+
+类型检查通常都是关于检查函数参数的类型。
+在 Python 中,大多数操作都是方法调用。 如果对象所属的类在调用时没有附加方法,就是这样。
+
+```python
+def f(x):
+ return x.m()
+
+class C:
+ def m(self): return None
+
+c = C()
+f(c)
+f(1) # 类型错误
+```
+
+```python
+# f: |T, X <: {.m = Self.() -> T}| X -> T
+f(x) = x.m()
+
+C = Class()
+C.m(self) = None
+
+c = C.new()
+f(c)
+f(1) # 类型错误:f 将具有方法 `.m` 的类型作为参数,但传递了 Nat
+```
diff --git a/doc/zh_CN/python/index.md b/doc/zh_CN/python/index.md
new file mode 100644
index 00000000..2168ad9d
--- /dev/null
+++ b/doc/zh_CN/python/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/index.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)
+
diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md
new file mode 100644
index 00000000..d7289f48
--- /dev/null
+++ b/doc/zh_CN/syntax/00_basic.md
@@ -0,0 +1,148 @@
+# 基本
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+> __Warning__:本文档不完整。 它未经校对(样式、正确链接、误译等)。 此外,Erg 的语法可能在版本 0.* 期间发生破坏性更改,并且文档可能没有相应更新。 请事先了解这一点。
+> 如果您在本文档中发现任何错误,请报告至 [此处的表单](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我们将不胜感激您的建议。
+
+本文档描述 Erg 的基本语法。 [标准 API](./API/index.md) 和 [Erg 贡献者的内部文档](./dev_guide/index.md) 位于另一个目录中。
+
+## 你好,世界!
+
+首先,让我们做“Hello World”。
+
+```python
+print!("Hello, World!")
+```
+
+这与 Python 和同一家族中的其他语言几乎相同。 最显着的特征是`!`,后面会解释它的含义。
+在 Erg 中,括号 `()` 可以省略,除非在解释上有一些混淆。
+括号的省略与 Ruby 类似,但不能省略可以以多种方式解释的括号。
+
+```python
+print! "Hello, World!" # OK
+print! "Hello,", "World!" # OK
+print!() # OK
+print! # OK, 但这并不意味着调用,只是将 `print!` 作为可调用对象
+
+print! f x # OK, 解释为 `print!(f(x))`
+print!(f(x, y)) # OK
+print! f(x, y) # OK
+print! f(x, g y) # OK
+print! f x, y # NG, 可以理解为 `print!(f(x), y)` 或 `print!(f(x, y))` print!
+print!(f x, y) # NG, 可以表示“print!(f(x),y)”或“print!(f(x,y))”
+print! f(x, g y, z) # NG, 可以表示“print!(x,g(y),z)”或“print!(x,g(y,z))”
+```
+
+## 脚本
+
+Erg 代码称为脚本。 脚本可以以文件格式 (.er) 保存和执行。
+
+## REPL/文件执行
+
+要启动 REPL,只需键入:
+
+```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!
+```
+
+## 注释
+
+`#` 之后的代码作为注释被忽略。 使用它来解释代码的意图或暂时禁用代码。
+
+```python
+# 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 `]#`
+]#
+```
+
+## 表达式,分隔符
+
+脚本是一系列表达式。 表达式是可以计算或评估的东西,在 Erg 中几乎所有东西都是表达式。
+每个表达式由分隔符分隔 - 新行或分号 `;`-。
+Erg 脚本基本上是从左到右、从上到下进行评估的。
+
+```python
+n = 1 # 赋值表达式
+f(1, 2) # 函数调用表达式
+1 + 1 # 运算符调用表达式
+f(1, 2); 1 + 1
+```
+
+如下所示,有一种称为 Instant block 的语法,它将块中评估的最后一个表达式作为变量的值。
+这与没有参数的函数不同,它不添加 `()`。 请注意,即时块仅在运行中评估一次
+
+```python
+i =
+ x = 1
+ x + 1
+assert i == 2
+```
+
+这不能用分号 (`;`) 完成。
+
+```python
+i = (x = 1; x + 1) # 语法错误:不能在括号中使用 `;`
+```
+
+## 缩进
+
+Erg 和 Python 一样,使用缩进来表示块。 有五个运算符(特殊形式)触发块的开始:`=`、`->`、`=>`、`do` 和 `do!`(此外,`:` 和 `|` ,虽然不是运算符,但也会产生缩进)。 每个的含义将在后面描述。
+
+```python
+f x, y =
+ x + y
+
+for! 0..9, i =>
+ print!
+
+for! 0..9, i =>
+ print! i; print! i
+
+ans = match x:
+ 0 -> "zero"
+ _: 0..9 -> "1 dight"
+ _: 10..99 -> "2 dights"
+ _ -> "unknown"
+```
+
+如果一行太长,可以使用 `\` 将其断开
+
+```python
+# 这不是表示 `x + y + z` 而是表示 `x; +y; +z`
+X
++ y
++ z
+
+# 这意味着`x + y + z`
+x \
++ y \
++ z
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/01_literal.md b/doc/zh_CN/syntax/01_literal.md
new file mode 100644
index 00000000..8988ca29
--- /dev/null
+++ b/doc/zh_CN/syntax/01_literal.md
@@ -0,0 +1,151 @@
+# 字面量
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/01_literal.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 基本字面量
+
+### 整数字面量
+
+```python
+0, -0, 1, -1, 2, -2, 3, -3, ...
+```
+
+### 比率文字
+
+```python
+0.00, -0.0, 0.1, 400.104, ...
+```
+
+如果“比率”文字的整数或小数部分为`0`,则可以省略`0`
+
+```python
+assert 1.0 == 1.
+assert 0.5 == .5
+```
+
+> __注意__:这个函数 `assert` 用于表明 `1.0` 和 `1.` 相等。
+后续文档可能会使用 `assert` 来表示结果是相等的。
+
+### 字符串字面量
+
+可以使用任何 Unicode 可表示的字符串。
+与 Python 不同,引号不能包含在 `'` 中。 如果要在字符串中使用 `"`,请使用 `\"`。
+
+```python
+"", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "السَّلَامُ عَلَيْكُمْ", ...
+```
+
+`{}` 允许您在字符串中嵌入表达式。 这称为字符串插值。
+如果要输出 `{`、`}` 本身,请使用 `\{`、`\}`。
+
+```python
+assert "1 + 1 is 2" == "{1} + {1} is {1+1}"
+s = "1+1"
+assert "\{1+1}\" == "\{{s}\}"
+```
+
+### 指数字面量
+
+这是学术计算中常用的表示指数符号的文字。 它是“比率”类型的一个实例。
+该符号与 Python 中的符号相同。
+
+```python
+1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ...
+```
+
+```python
+assert 1e-10 == 0.0000000001
+```
+
+## 复合字面量
+
+这些文字中的每一个都有自己的文档分别描述它们,因此请参阅该文档以获取详细信息。
+
+### [数组字面量](./10_array.md)
+
+```python
+[], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ...
+```
+
+### [字典字面量](./11_dict.md)
+
+```python
+{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
+```
+
+### [元组字面量](./12_tuple.md)
+
+```python
+(), (1, 2, 3), (1, "hello", True), ...
+```
+
+### [Record 字面量](./13_record.md)
+
+```python
+{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
+```
+
+### [Set 字面量](./14_set.md)
+
+```python
+{}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ...
+```
+
+与 `Array` 字面量不同的是,`Set` 中删除了重复元素
+
+```python
+assert {1, 2, 1} == {1, 2}
+```
+
+### 看起来像文字但不是
+
+## 布尔对象
+
+```python
+True, False
+```
+
+### None 对象
+
+```python
+None
+```
+
+## Range 对象
+
+```python
+assert 0..5 == {1, 2, 3, 4, 5}
+assert 0..10 in 5
+assert 0..<10 notin 10
+assert 0..9 == 0..<10
+```
+
+## Float 对象
+
+```python
+assert 0.0f64 == 0
+assert 0.0f32 == 0.0f64
+```
+
+浮点对象是通过将 `Ratio` 对象乘以 `f64` 构造的,后者是 `Float 64` 单位对象
+
+## Complex 对象
+
+```python
+1+2im, 0.4-1.2im, 0im, im
+```
+
+一个“复杂”对象只是一个虚数单位对象`im`的算术组合
+
+## *-less 乘法
+
+在 Erg 中,您可以省略 `*` 来表示乘法,只要解释上没有混淆即可。 但是,运算符的组合强度设置为强于 `*`。
+
+```python
+# same as `assert (1*m) / (1*s) == 1*(m/s)`
+assert 1m / 1s == 1 (m/s)
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/02_name.md b/doc/zh_CN/syntax/02_name.md
new file mode 100644
index 00000000..321b6fd3
--- /dev/null
+++ b/doc/zh_CN/syntax/02_name.md
@@ -0,0 +1,166 @@
+# 多变的
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+变量是一种代数; Erg 中的代数 - 如果没有混淆,有时简称为变量 - 指的是命名对象并使它们可从代码的其他地方引用的功能。
+
+变量定义如下。
+`n` 部分称为变量名(或标识符),`=` 是赋值运算符,`1` 部分是赋值。
+
+```python
+n = 1
+```
+
+以这种方式定义的“n”此后可以用作表示整数对象“1”的变量。 该系统称为分配(或绑定)。
+我们刚刚说过`1`是一个对象。 稍后我们将讨论对象是什么,但现在我们假设它是可以赋值的,即在赋值运算符的右侧(`=` 等)。
+
+如果要指定变量的“类型”,请执行以下操作。 类型大致是一个对象所属的集合,后面会解释。
+这里我们指定`n`是自然数(`Nat`)类型。
+
+```python
+n: Nat = 1
+```
+
+请注意,与其他语言不同,不允许多次分配
+
+```python
+# NG
+l1 = l2 = [1, 2, 3] # 语法错误:不允许多重赋值
+# OK
+l1 = [1, 2, 3]
+l2 = l1.clone()
+```
+
+也不能重新分配给变量。 稍后将描述可用于保存可变状态的语法
+
+```python
+i = 1
+i = i + 1 # 分配错误:不能分配两次
+```
+
+您可以在内部范围内定义具有相同名称的变量,但您只是覆盖它,而不是破坏性地重写它的值。 如果您返回外部范围,该值也会返回。
+请注意,这是与 Python “语句”范围不同的行为。
+这种功能通常称为阴影。 但是,与其他语言中的阴影不同,您不能在同一范围内进行阴影。
+
+```python
+x = 0
+# x = 1 # 赋值错误:不能赋值两次
+if x.is_zero(), do:
+ x = 1 # 与同名的外部 x 不同
+ assert x == 1
+assert x == 0
+```
+
+乍一看,以下内容似乎可行,但仍然不可能。 这是一个设计决定,而不是技术限制。
+
+```python
+x = 0
+if x.is_zero(), do:
+ x = x + 1 # 名称错误:无法定义变量引用同名变量
+ assert x == 1
+assert x == 0
+```
+
+## 常量
+
+常数也是一种代数。 如果标识符以大写字母开头,则将其视为常量。 它们被称为常量,因为一旦定义,它们就不会改变。
+`N` 部分称为常量名(或标识符)。 否则,它与变量相同。
+
+```python
+N = 0
+if True, do:
+ N = 1 # 赋值错误:常量不能被遮蔽
+ pass()
+```
+
+常量在定义的范围之外是不可变的。 他们不能被遮蔽。 由于这个属性,常量可以用于模式匹配。 模式匹配在后面解释。
+
+例如,常量用于数学常量、有关外部资源的信息和其他不可变值。
+
+除了 [types](./type/01_type_system.md) 之外的对象标识符使用全大写(所有字母大写的样式)是常见的做法。
+
+```python
+PI = 3.141592653589793
+URL = "https://example.com"
+CHOICES = ["a", "b", "c"]
+```
+
+```python
+PI = 3.141592653589793
+match! x:
+ PI => print! "π"
+ other => print! "other"
+```
+
+当 `x` 为 `3.141592653589793` 时,上面的代码会打印 `π`。 如果 `x` 更改为任何其他数字,它会打印 `other`。
+
+有些对象不能绑定为常量。 例如,可变对象。 可变对象是其状态可以改变的对象,后面会详细介绍。
+这是因为只有常量表达式才能分配给常量的规则。 常量表达式也将在后面讨论。
+
+```python
+X = 1 # OK
+X = !1 # 类型错误:无法定义 Int! 对象作为常量
+```
+
+## 删除变量
+
+您可以使用 `Del` 函数删除变量。 依赖于变量的所有其他变量(即直接引用变量值的变量)也将被删除。
+
+```python
+x = 1
+y = 2
+Z = 3
+f a = x + a
+
+assert f(2) == 3
+Del x
+Del y, Z
+
+f(2) # 名称错误:f 未定义(在第 6 行中删除)
+```
+
+注意 `Del` 只能删除用户自定义模块中定义的变量。 无法删除诸如“True”之类的内置常量。
+
+```python
+Del True # 类型错误:无法删除内置常量
+Del print! # TypeError: 无法删除内置变量
+```
+
+## 附录:赋值和等价
+
+请注意,当 `x = a` 时,`x == a` 不一定为真。 一个例子是`Float.NaN`。 这是 IEEE 754 定义的浮点数的正式规范。
+
+```python
+x = Float.NaN
+assert x ! = NaN
+assert x ! = x
+```
+
+还有其他对象首先没有定义等价关系。
+
+```python
+f = x -> x**2 + 2x + 1
+g = x -> (x + 1)**2
+f == g # 类型错误:无法比较函数对象
+
+C = Class {i: Int}
+D = Class {i: Int}
+C == D # 类型错误:无法比较类对象
+```
+
+严格来说,`=` 不会将右侧的值直接分配给左侧的标识符。
+在函数和类对象的情况下,执行“修改”,例如将变量名称信息赋予对象。 但是,结构类型并非如此。
+
+```python
+f x = x
+print! f # <函数 f>
+g x = x + 1
+print! g # <函数 g>
+
+C = Class {i: Int}
+print! C # <类 C>
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/03_declaration.md b/doc/zh_CN/syntax/03_declaration.md
new file mode 100644
index 00000000..06e0b5dc
--- /dev/null
+++ b/doc/zh_CN/syntax/03_declaration.md
@@ -0,0 +1,49 @@
+# 宣言(Declaration)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/03_declaration.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+声明是用于指定要使用的变量类型的语法。
+可以在代码中的任何地方进行声明,但单独的声明并不引用变量。 它们必须被初始化。
+分配后,可以检查声明以确保类型与分配它的对象兼容。
+
+```python
+i: Int
+# 可以与赋值同时声明,如 i: Int = 2
+i = 2
+i: Num
+i: Nat
+i: -2..2
+i: {2}
+```
+
+赋值后的声明类似于`assert`的类型检查,但具有在编译时检查的特点。
+在运行时通过`assert`进行类型检查可以检查“可能是Foo类型”,但是在编译时通过`:`进行类型检查是严格的:如果类型未确定为“类型Foo”,则不会通过 检查会出现错误。
+
+```python
+i = (-1..10).sample!
+assert i in Nat # 这可能会通过
+i: Int # 这会通过
+i: Nat # 这不会通过(-1 不是 Nat 的元素)
+```
+
+函数可以用两种不同的方式声明。
+
+```python
+f: (x: Int, y: Int) -> Int
+f: (Int, Int) -> Int
+```
+
+如果显式声明参数名称,如果在定义时名称不同,则会导致类型错误。 如果你想给参数名称任意命名,你可以用第二种方式声明它们。 在这种情况下,类型检查只会看到方法名称及其类型。
+
+```python
+T = Trait {
+ .f = (x: Int, y: Int): Int
+}
+
+C = Class(U, Impl := T)
+C.f(a: Int, b: Int): Int = ... # 类型错误:`.f` 必须是 `(x: Int, y: Int) -> Int` 的类型,而不是 `(a: Int, b: Int) -> Int`
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md
new file mode 100644
index 00000000..efc8ef08
--- /dev/null
+++ b/doc/zh_CN/syntax/04_function.md
@@ -0,0 +1,292 @@
+# 功能
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/04_function.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+函数是一个块,它接受一个“参数”,对其进行处理,并将其作为“返回值”返回。 定义如下。
+
+```python
+add x, y = x + y
+# 或者
+add(x, y) = x + y
+```
+
+在函数名之后指定的名称称为参数。
+相反,传递给函数的对象称为参数。
+函数 `add` 是一个以 `x` 和 `y` 作为参数并返回它们之和的函数,`x + y`。
+可以按如下方式调用(应用/调用)定义的函数。
+
+```python
+add 1, 2
+# or
+add(1, 2)
+```
+
+## 冒号应用风格
+
+函数像`f x, y, ...`一样被调用,但是如果单行参数太多,可以使用`:`(冒号)来应用它们。
+
+```python
+f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4
+```
+
+```python
+f some_long_name_variable_1 + some_long_name_variable_2:
+ some_long_name_variable_3 * some_long_name_variable_4
+```
+
+```python
+f:
+ some_long_name_variable_1 + some_long_name_variable_2
+ some_long_name_variable_3 * some_long_name_variable_4
+```
+
+以上三个代码的含义相同。 例如,这种风格在使用 `if` 函数时也很有用
+
+```python
+result = if Bool.sample!():
+ do:
+ log "True was chosen"
+ 1
+ do:
+ log "False was chosen"
+ 0
+```
+
+在 `:` 之后,除了注释之外,不得编写任何代码,并且必须始终在新行上
+
+## 关键字参数
+
+如果使用大量参数定义函数,则存在以错误顺序传递参数的危险。
+在这种情况下,使用关键字参数调用函数是安全的。
+
+```python
+f x, y, z, w, v, u: Int = ...
+```
+
+上面定义的函数有很多参数,并且排列顺序混乱。 您不应该创建这样的函数,但是在使用别人编写的代码时可能会遇到这样的代码。 因此,我们使用关键字参数。 如果使用关键字参数,则值会从名称传递到正确的参数,即使它们的顺序错误。
+
+```python
+f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3
+```
+
+请注意,紧跟在 `:` 之后的关键字参数和新行被视为冒号调用样式
+
+```python
+# 意思是 `f(x: y)`
+f x: y
+
+# 意思是 `f(x, y)`
+f x:
+ y
+```
+
+## 定义错误参数
+
+当某些参数大部分是固定的并且您希望能够省略它们时,使用默认参数。
+
+默认参数由`:=`(walrus运算符)指定。 如果未指定 `base`,则将 `math.E` 分配给 `base`。
+
+```python
+math_log x: Ratio, base := math.E = ...
+
+assert math_log(100, 10) == 2
+assert math_log(100) == math_log(100, math.E)
+```
+
+请注意,不指定参数和指定`None`是有区别的
+
+```python
+p! x := 0 = print!
+p!(2) # 2
+p!() # 0
+p!(None) # None
+```
+
+也可以与类型规范和模式一起使用
+
+```python
+math_log x, base: Ratio := math.E = ...
+f [x, y] := [1, 2] = ...
+```
+
+但是,在默认参数中,不能调用过程(稍后描述)或分配可变对象
+
+```python
+f x := p! 1 = ... # NG
+```
+
+此外,刚刚定义的参数不能用作传递给默认参数的值
+
+```python
+f x := 1, y := x = ... # NG
+```
+
+## 可变长度参数
+
+输出其参数的日志(记录)的 `log` 函数可以采用任意数量的参数。
+
+```python
+记录“你好”、“世界”、“!” # 你好世界 !
+```
+
+要定义这样的函数,请将 `...` 添加到参数中。 这样,函数将参数作为可变长度数组接收
+
+```python
+f ...x =
+ for x, i ->
+ log i
+
+# x == [1, 2, 3, 4, 5]
+f 1, 2, 3, 4, 5
+```
+
+## 具有多种模式的函数定义
+
+```python
+fib n: Nat =
+ match n:
+ 0 -> 0
+ 1 -> 1
+ n -> fib(n - 1) + fib(n - 2)
+```
+
+像上面这样的函数,其中 `match` 直接出现在定义下,可以重写如下
+
+```python
+fib 0 = 0
+fib 1 = 1
+fib(n: Nat): Nat = fib(n - 1) + fib(n - 2)
+```
+
+注意一个函数定义有多个模式不是所谓的重载(multiple definition); 一个函数只有一个定义。 在上面的示例中,“n”必须与“0”或“1”属于同一类型。 此外,与 `match` 一样,模式匹配是从上到下完成的。
+
+如果不同类的实例混合在一起,最后一个定义必须指定函数参数的类型为`Or`
+
+```python
+f "aa" = ...
+f 1 = ...
+# `f x = ... ` 无效
+f x: Int or Str = ...
+```
+
+此外,像 `match` 一样,它也必须是详尽的。
+
+```python
+fib 0 = 0
+fib 1 = 1
+# 模式错误:fib 参数的模式并不详尽
+```
+
+但是,可以通过使用稍后描述的 [refinement type](./type/12_refinement.md) 显式指定类型来使其详尽无遗。
+
+```python
+fib: 0..1 -> 0..1
+fib 0 = 0
+fib 1 = 1
+# OK
+```
+
+## 递归函数
+
+递归函数是在其定义中包含自身的函数。
+
+作为一个简单的例子,让我们定义一个执行阶乘计算的函数`factorial`。 阶乘是“将所有小于或等于的正数相乘”的计算。
+5 的阶乘是 `5*4*3*2*1 == 120`。
+
+```python
+factorial 0 = 1
+factorial 1 = 1
+factorial(n: Nat): Nat = n * factorial(n - 1)
+```
+
+首先,从阶乘的定义来看,0和1的阶乘都是1。
+反过来,2的阶乘是`2*1 == 2`,3的阶乘是`3*2*1 == 6`,4的阶乘是`4*3*2*1 == 24 `。
+如果我们仔细观察,我们可以看到一个数 n 的阶乘是前一个数 n-1 乘以 n 的阶乘。
+将其放入代码中,我们得到 `n * factorial(n - 1)`。
+由于 `factorial` 的定义包含自身,`factorial` 是一个递归函数。
+
+提醒一下,如果您不添加类型规范,则会这样推断。
+
+```python
+factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int
+factorial 0 = 1
+factorial 1 = 1
+factorial n = n * factorial(n - 1)
+```
+
+但是,即使您可以推理,您也应该明确指定递归函数的类型。 在上面的例子中,像“factorial(-1)”这样的代码可以工作,但是
+
+```python
+factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ...
+```
+
+并且这种计算不会停止。 递归函数必须仔细定义值的范围,否则您可能会陷入无限循环。
+所以类型规范也有助于避免接受意外的值。
+
+## 编译时函数
+
+函数名以大写字母开头,表示编译时函数。 用户定义的编译时函数必须将所有参数作为常量,并且必须指定它们的类型。
+编译时函数的功能有限。 在编译时函数中只能使用常量表达式,即只有一些运算符(例如求积、比较和类型构造操作)和编译时函数。 要传递的参数也必须是常量表达式。
+作为回报,优点是计算可以在编译时完成。
+
+```python
+Add(X, Y: Nat): Nat = X + Y
+assert Add(1, 2) == 3
+
+Factorial 0 = 1
+Factorial(X: Nat): Nat = X * Factorial(X - 1)
+assert Factorial(10) == 3628800
+
+math = import "math"
+Sin X = math.sin X # 常量错误:此函数在编译时不可计算
+```
+
+编译时函数也用于多态类型定义。
+
+```python
+Option T: Type = T or NoneType
+Option: Type -> Type
+```
+
+## 附录:功能对比
+
+Erg 没有为函数定义 `==`。 这是因为通常没有函数的结构等价算法。
+
+```python
+f = x: Int -> (x + 1)**2
+g = x: Int -> x**2 + 2x + 1
+
+assert f == g # 类型错误:无法比较函数
+```
+
+尽管 `f` 和 `g` 总是返回相同的结果,但要做出这样的决定是极其困难的。 我们必须向编译器教授代数。
+所以 Erg 完全放弃了函数比较,并且 `(x -> x) == (x -> x)` 也会导致编译错误。 这是与 Python 不同的规范,应该注意
+
+```python
+# Python,奇怪的例子
+f = lambda x: x
+assert f == f
+assert (lambda x: x) ! = (lambda x: x)
+```
+
+## Appendix2: ()-completion
+
+```python
+f x: Object = ...
+# 将完成到
+f(x: Object) = ...
+
+f a
+# 将完成到
+f(a)
+
+f a, b # 类型错误:f() 接受 1 个位置参数,但给出了 2 个
+f(a, b) # # 类型错误:f() 接受 1 个位置参数,但给出了 2 个
+f((a, b)) # OK
+```
+
+函数类型`T -> U`实际上是`(T,) -> U`的语法糖。
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/05_builtin_funcs.md b/doc/zh_CN/syntax/05_builtin_funcs.md
new file mode 100644
index 00000000..5eadce67
--- /dev/null
+++ b/doc/zh_CN/syntax/05_builtin_funcs.md
@@ -0,0 +1,51 @@
+# 内置函数
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/05_builtin_funcs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 如果
+
+`if` 是一个根据条件改变处理的函数。
+
+```python
+result: Option Int = if! Bool.sample!(), do:
+ log "True was chosen"
+ 1
+print! result # None (or 1)
+```
+
+`.sample!()` 返回一组随机值。 如果返回值为真,`print! “真”`被执行。
+如果条件为假,您还可以指定要执行的操作; 第二个 do 块称为 else 块。
+
+```python
+result: Nat = if Bool.sample!():
+ do:
+ log "True was chosen"
+ 1
+ do:
+ log "False was chosen"
+ 0
+print! result # 1 (or 0)
+```
+
+如果进程是单行,则可以省略缩进。
+
+```python
+result = if Bool.sample!():
+ do 1
+ do 0
+```
+
+## for
+
+你可以使用 `for` 来编写一个重复的过程。
+
+```python
+match_s(ss: Iterator(Str), pat: Pattern): Option Str =
+ for ss, s ->
+ if pat.match(s).is_some():
+ break s
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/06_operator.md b/doc/zh_CN/syntax/06_operator.md
new file mode 100644
index 00000000..f2f9b6cc
--- /dev/null
+++ b/doc/zh_CN/syntax/06_operator.md
@@ -0,0 +1,31 @@
+# 运算符
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/06_operator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+运算符是表示操作的符号。 操作数是运算符(左)右侧的东西。
+
+运算符是一种函数,因此它们本身就是可以绑定到变量的一流对象。 绑定时,需要用```括起来。
+对于`+`(和`-`),有一元和二元运算符,所以必须指定`_+_`(二元运算)/`+_`(一元运算)。
+
+```python
+add = `+` # 语法错误:指定 `_+_` 或 `+_`
+add=`_+_`
+assert f(1, 2) == 3
+assert f("a", "b") == "ab"
+
+g = `*` # OK, 这只是二进制
+assert g(1, 2) == 2
+```
+
+一些称为特殊形式的基本运算符不能被绑定。
+
+```python
+def = `=` # 语法错误:无法绑定 `=` 运算符,这是一种特殊形式
+# NG: def x, 1
+function = `->` # 语法错误:无法绑定 `->` 运算符,这是一种特殊形式
+# NG: function x, x + 1
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/07_side_effect.md b/doc/zh_CN/syntax/07_side_effect.md
new file mode 100644
index 00000000..2f53c78f
--- /dev/null
+++ b/doc/zh_CN/syntax/07_side_effect.md
@@ -0,0 +1,123 @@
+# 副作用和程序
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/07_side_effect.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+我们一直忽略了解释“!”的含义,但现在它的含义终于要揭晓了。 这个 `!` 表示这个对象是一个带有“副作用”的“过程”。 过程是具有副作用的函数。
+
+```python
+f x = print! x # EffectError: 不能为函数分配有副作用的对象
+# 提示:将名称更改为 'f!'
+```
+
+上面的代码会导致编译错误。 这是因为您在函数中使用了过程。 在这种情况下,您必须将其定义为过程。
+
+```python
+p! x = print! x
+```
+
+`p!`, `q!`, ... 是过程的典型变量名。
+以这种方式定义的过程也不能在函数中使用,因此副作用是完全隔离的。
+
+## 方法
+
+函数和过程中的每一个都可以是方法。 函数式方法只能对`self`进行不可变引用,而程序性方法可以对`self`进行可变引用。
+`self` 是一个特殊的参数,在方法的上下文中是指调用对象本身。 引用 `self` 不能分配给任何其他变量。
+
+```python
+C!.
+ method ref self =
+ x = self # 所有权错误:无法移出`self`
+ x
+```
+
+程序方法也可以采取 `self` 的 [ownership](./18_ownership.md)。 从方法定义中删除 `ref` 或 `ref!`
+
+```python
+n = 1
+s = n.into(Str) # '1'
+n # 值错误:n 被 .into 移动(第 2 行)
+```
+
+在任何给定时间,只有一种程序方法可以具有可变引用。 此外,在获取可变引用时,不能从原始对象获取更多可变引用。 从这个意义上说,`ref!` 会对`self` 产生副作用。
+
+但是请注意,可以从可变引用创建(不可变/可变)引用。 这允许在程序方法中递归和 `print!` 的`self`。
+
+```python
+T -> T # OK (move)
+T -> Ref T # OK (move)
+T => Ref! T # OK (only once)
+Ref T -> T # NG
+Ref T -> Ref T # OK
+Ref T => Ref!
+T -> Ref T # NG
+T -> Ref T # OK
+T => Ref!
+```
+
+## 附录:副作用的严格定义
+
+代码是否具有副作用的规则无法立即理解。
+直到你能理解它们,我们建议你暂时把它们定义为函数,如果出现错误,添加`!`将它们视为过程。
+但是,对于那些想了解该语言的确切规范的人,以下是对副作用的更详细说明。
+
+首先,必须声明返回值的等价与 Erg 中的副作用无关。
+有些过程对于任何给定的 `x` 都会导致 `p!(x) == p!(x)`(例如,总是返回 `None`),并且有些函数会导致 `f(x) ! = f(x)`。
+
+前者的一个例子是`print!`,后者的一个例子是下面的函数。
+
+```python
+nan _ = Float.NaN
+assert nan(1) ! = nan(1)
+```
+
+还有一些对象,例如类,等价确定本身是不可能的
+
+```python
+T = Structural {i = Int}
+U = Structural {i = Int}
+assert T == U
+
+C = Class {i = Int}
+D = Class {i = Int}
+assert C == D # 类型错误:无法比较类
+```
+
+言归正传:Erg 中“副作用”的准确定义是
+
+* 访问可变的外部信息。
+
+“外部”一般是指外部范围; Erg 无法触及的计算机资源和执行前/执行后的信息不包含在“外部”中。 “访问”包括阅读和写作。
+
+例如,考虑 `print!` 过程。 乍一看,`print!` 似乎没有重写任何变量。 但如果它是一个函数,它可以重写外部变量,例如,使用如下代码:
+
+```python
+camera = import "some_camera_module"
+ocr = import "some_ocr_module"
+
+n = 0
+_ =
+ f x = print x # 假设我们可以使用 print 作为函数
+ f(3.141592)
+cam = camera.new() # 摄像头面向 PC 显示器
+image = cam.shot!()
+n = ocr.read_num(image) # n = 3.141592
+```
+
+将“camera”模块视为为特定相机产品提供 API 的外部库,将“ocr”视为用于 OCR(光学字符识别)的库。
+直接的副作用是由 `cam.shot!()` 引起的,但显然这些信息是从 `f` 泄露的。 因此,`print!` 本质上不可能是一个函数。
+
+然而,在某些情况下,您可能希望临时检查函数中的值,而不想为此目的在相关函数中添加 `!`。 在这种情况下,可以使用 `log` 函数。
+`log` 打印整个代码执行后的值。 这样,副作用就不会传播。
+
+```python
+log "this will be printed after execution"
+print! "this will be printed immediately"
+# 这将立即打印
+# 这将在执行后打印
+```
+
+如果没有反馈给程序,或者换句话说,如果没有外部对象可以使用内部信息,那么信息的“泄漏”是可以允许的。 只需要不“传播”信息。
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/08_procedure.md b/doc/zh_CN/syntax/08_procedure.md
new file mode 100644
index 00000000..137b68d0
--- /dev/null
+++ b/doc/zh_CN/syntax/08_procedure.md
@@ -0,0 +1,14 @@
+# 程序
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/08_procedure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+处理可变对象时需要过程,但将可变对象作为参数并不一定使其成为过程。
+这是一个函数接受一个可变对象(不是过程)。
+
+```python
+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
new file mode 100644
index 00000000..837740fb
--- /dev/null
+++ b/doc/zh_CN/syntax/09_builtin_procs.md
@@ -0,0 +1,16 @@
+# 内置程序
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/09_builtin_procs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## id!
+
+返回对象的唯一标识号。
+尽管在纯 Erg 语义中,结构相同的对象之间没有区别,但实际上对象在内存中具有不同的位置。
+`id!` 返回一个代表这个位置的数字。
+
+```python
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/10_array.md b/doc/zh_CN/syntax/10_array.md
new file mode 100644
index 00000000..39602e97
--- /dev/null
+++ b/doc/zh_CN/syntax/10_array.md
@@ -0,0 +1,54 @@
+# Array
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/10_array.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+数组是最基本的__collection(聚合)__。
+集合是一个可以在其中包含多个对象的对象。
+
+```python
+a = [1, 2, 3]
+a: [Int; 3] # 类型说明:分号后的数字为元素个数
+# 如果元素个数未知,可以省略
+a: [Int]
+
+mut_a = [!1, !2, !3]
+mut_a[0].inc!()
+assert mut_a == [2, 2, 3]
+```
+
+通常,数组不能包含不同类型的对象。
+
+```python.
+[1, "a"] # 类型错误:第一个元素是 Int,但第二个元素是 Str
+```
+
+但是,您可以通过像这样显式指定类型来绕过限制。
+
+```python
+[1, "a"]: [Int or Str].
+```
+
+## 切片
+
+一个数组也可以同时取出多个值。 这称为切片。
+
+```python
+l = [1, 2, 3, 4]
+# 与 Python 中的 l[1:3] 相同
+assert l[1.. <3] == [2, 3]
+assert l[1..2] == [2, 3]
+# 与 l[1] 相同
+assert l[1..1] == [2]
+# 与 Python 中的 l[::2] 相同
+assert l[..].step(2) == [2, 4]
+```
+
+通过切片获得的对象是数组的(不可变的)副本
+
+```python
+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
new file mode 100644
index 00000000..ddf8ecad
--- /dev/null
+++ b/doc/zh_CN/syntax/11_tuple.md
@@ -0,0 +1,118 @@
+# 元组
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/11_tuple.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+元组类似于数组,但可以保存不同类型的对象。
+这样的集合称为不等集合。 相比之下,同构集合包括数组、集合等。
+
+```python
+t = (1, True, "a")
+(i, b, s) = t
+assert(i == 1 and b == True and s == "a")
+```
+
+元组`t`可以以`t.n`的形式检索第n个元素; 请注意,与 Python 不同,它不是 `t[n]`。
+这是因为访问元组元素更像是一个属性(在编译时检查元素的存在,并且类型可以根据 `n` 改变)而不是方法(数组的 `[]` 是一种方法)。
+
+```python
+assert t.0 == 1
+assert t.1 == True
+assert t.2 == "a"
+```
+
+括号 `()` 在不嵌套时是可选的。
+
+```python
+t = 1, True, "a"
+i, b, s = t
+```
+
+元组可以保存不同类型的对象,因此它们不能像数组一样被迭代。
+
+```python
+t: ({1}, {2}, {3}) = (1, 2, 3)
+(1, 2, 3).iter().map(x -> x + 1) # 类型错误:类型 ({1}, {2}, {3}) 没有方法 `.iter()`
+# 如果所有类型都相同,则可以像数组一样用`(T; n)`表示,但这仍然不允许迭代
+t: (Int; 3) = (1, 2, 3)
+assert (Int; 3) == (Int, Int, Int)
+```
+
+但是,非同质集合(如元组)可以通过向上转换、相交等方式转换为同质集合(如数组)。
+这称为均衡。
+
+```python
+(Int, Bool, Str) can be [T; 3] where T :> Int, T :> Bool, T :> Str
+```
+
+```python
+t: (Int, Bool, Str) = (1, True, "a") # 非同质
+a: [Int or Bool or Str; 3] = [1, True, "a"] # 同质的
+_a: [Show; 3] = [1, True, "a"] # 同质的
+_a.iter().map(x -> log x) # OK
+t.try_into([Show; 3])? .iter().map(x -> log x) # OK
+```
+
+## 单元
+
+零元素的元组称为 __unit__。 一个单元是一个值,但也指它自己的类型。
+
+```python
+unit = ()
+(): ()
+```
+
+Unit 是所有元素 0 元组的父类。
+
+```python
+() > (Int; 0)
+() > (Str; 0)
+```
+
+该对象的用途是用于没有参数和没有返回值的过程等。Erg 子例程必须有参数和返回值。 但是,在某些情况下,例如过程,可能没有有意义的参数或返回值,只有副作用。 在这种情况下,我们将单位用作“无意义的正式值”
+
+```python
+# ↓ Actually, this parenthesis is a unit
+p!() =.
+ # `print!` does not return a meaningful value
+ print! "Hello, world!"
+p!: () => ()
+```
+
+但是,在这种情况下,Python 倾向于使用“无”而不是单位。
+在 Erg 中,当您从一开始就确定操作不会返回有意义的值(例如在过程中)时,您应该使用 `()`,并且当操作可能失败并且您可能会返回 `None` 将一无所获,例如在检索元素时。
+
+## 参数和元组
+
+实际上,Erg 的所有 `Callable` 对象都是一个参数和一个返回值; 一个接受 N 个参数的子例程只是接收“一个具有 N 个元素的元组”作为参数。
+
+```python
+# f x = ... 被隐式假设为 f(x) = ... 被认为是
+f x = x
+assert f(1) == 1
+f(1, 2, 3) # 参数错误:f 接受 1 个位置参数,但给出了 3 个
+g x: Int, . . y: Int = y
+assert (2, 3) == g 1, 2, 3
+```
+
+这也解释了函数类型。
+
+```python
+assert f in T: {(T,) -> T | T}
+assert g in {(Int, ... (Int; N)) -> (Int; N) | N: Nat}
+```
+
+准确地说,函数的输入不是元组,而是“具有默认属性的命名元组”。 这是一个特殊的元组,只能在函数参数中使用,可以像记录一样命名,并且可以有默认值。
+
+```python
+f(x: Int, y=0) = x + y
+f: (Int, y=Int) -> Int
+
+f(x=0, y=1)
+f(y=1, x=0)
+f(x=0)
+f(0)
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/12_dict.md b/doc/zh_CN/syntax/12_dict.md
new file mode 100644
index 00000000..ac3cae2f
--- /dev/null
+++ b/doc/zh_CN/syntax/12_dict.md
@@ -0,0 +1,69 @@
+# 字典
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/12_dict.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Dict 是键/值对的集合。
+
+```python
+ids = {"Alice": 145, "Bob": 214, "Charlie": 301}
+assert ids["Alice"] == 145
+```
+
+如果键是“哈希”对象,则键不必是字符串。
+
+```python
+# 不推荐使用范围对象作为键(与切片混淆)
+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 与 Set 类似。
+您可以说 Dict 是具有值的 Set。
+
+```python
+{"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214}
+```
+
+从 dict 文字生成 dict 时,会检查重复键。
+任何重复都会导致编译错误。
+
+```python
+{"Alice": 145, "Alice": 1} # Key错误:重复键`Alice`
+```
+
+空字典是用 `{:}` 创建的。 请注意,`{}` 表示一个空集。
+
+```python
+mut_dict = !{:}
+mut_dict.insert! "Alice", 145
+mut_dict.insert! "Bob", 214
+assert mut_dict["Alice"] == 145
+```
+
+## 异构字典
+
+不需要有单一的键/值类型。 这样的字典称为 __heterogenous dict_。
+
+```python
+d: {Str: Int, Int: Str} = {"a": 1, 1: "a"}
+assert d["a"] == 1
+assert d[1] == "a"
+```
+
+但是,不能将相同类型的值分配给不同类型的键,或者将不同类型的值分配给相同类型的键。
+在这种情况下,请改用 Or 类型。
+
+```python
+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}
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/13_record.md b/doc/zh_CN/syntax/13_record.md
new file mode 100644
index 00000000..f82431ac
--- /dev/null
+++ b/doc/zh_CN/syntax/13_record.md
@@ -0,0 +1,201 @@
+# 记录(Record)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/13_record.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+记录是一个集合,它结合了通过键访问的 Dict 和在编译时检查其访问的元组的属性。
+如果您了解 JavaScript,请将其视为一种(更增强的)对象字面量表示法。
+
+```python
+john = {.name = "John"; .age = 21}
+
+assert john.name == "John"
+assert john.age == 21
+assert john in {.name = Str; .age = Nat}
+john["name"] # 错误:john 不可订阅
+```
+
+`.name` 和 `.age` 部分称为属性,而 `"John"` 和 `21` 部分称为属性值。
+
+与 JavaScript 对象字面量的区别在于它们不能作为字符串访问。 也就是说,属性不仅仅是字符串。
+这是因为对值的访问是在编译时确定的,而且字典和记录是不同的东西。 换句话说,`{"name": "John"}` 是一个字典,`{name = "John"}` 是一个记录。
+那么我们应该如何使用字典和记录呢?
+一般来说,我们建议使用记录。 记录具有在编译时检查元素是否存在以及能够指定 __visibility_ 的优点。
+指定可见性等同于在 Java 和其他语言中指定公共/私有。 有关详细信息,请参阅 [可见性](./15_visibility.md) 了解详细信息。
+
+```python
+a = {x = 1; .y = x + 1}
+a.x # 属性错误:x 是私有的
+# 提示:声明为 `.x`。
+assert a.y == 2
+```
+
+对于熟悉 JavaScript 的人来说,上面的示例可能看起来很奇怪,但简单地声明 `x` 会使其无法从外部访问
+
+您还可以显式指定属性的类型
+
+```python
+anonymous = {
+ .name: Option! Str = !
+ .age = 20
+}
+anonymous.name.set! "John"
+```
+
+一个记录也可以有方法。
+
+```python
+o = {
+ .i = !0
+ .inc! ref! self = self.i.inc!()
+}
+
+assert o.i == 0
+o.inc!()
+assert o.i == 1
+```
+
+关于记录有一个值得注意的语法。 当记录的所有属性值都是类(不是结构类型)时,记录本身表现为一个类型,其自身的属性作为必需属性。
+这种类型称为记录类型。 有关详细信息,请参阅 [记录] 部分。
+
+```python
+# 记录
+john = {.name = "John"}
+# 记录 type
+john: {.name = Str}
+Named = {.name = Str}
+john: Named
+
+greet! n: Named =
+ print! "Hello, I am {n.name}"
+john # “你好,我是约翰 print!
+
+Named.name # Str
+```
+
+## 解构记录
+
+记录可以按如下方式解构。
+
+```python
+record = {x = 1; y = 2}
+{x = a; y = b} = record
+assert a == 1
+assert b == 2
+
+point = {x = 2; y = 3; z = 4}
+match point:
+ {x = 0; y = 0; z = 0} -> "origin"
+ {x = _; y = 0; z = 0} -> "on the x axis"
+ {x = 0; ...} -> "x = 0"
+ {x = x; y = y; z = z} -> "({x}, {y}, {z})"
+```
+
+当存在与属性同名的变量时,`x = ...`也可以缩写为`x`,例如`x = x`或`x = .x`到`x`,和` .x = .x` 或 `.x = x` 到 `.x`。
+但是,当只有一个属性时,必须在其后加上`;`以与集合区分开来。
+
+```python
+x = 1
+y = 2
+xy = {x; y}
+a = 1
+b = 2
+ab = {.a; .b}
+assert ab.a == 1
+assert ab.b == 2
+
+record = {x;}
+tuple = {x}
+assert tuple.1 == 1
+```
+
+此语法可用于解构记录并将其分配给变量
+
+```python
+# 一样 `{x = x; y = y} = xy`
+{x; y} = xy
+assert x == 1
+assert y == 2
+# 一样 `{.a = a; .b = b} = ab`
+{a; b} = ab
+assert a == 1
+assert b == 2
+```
+
+## 空记录
+
+空记录由`{=}`表示。 空记录也是它自己的类,如 Unit
+
+```python
+empty_record = {=}
+empty_record: {=}
+# Object: Type = {=}
+empty_record: Object
+empty_record: Structural {=}
+{x = 3; y = 5}: Structural {=}
+```
+
+空记录不同于空 Dict `{:}` 或空集 `{}`。 特别要注意的是,它与 `{}` 的含义相反(在 Python 中,`{}` 是一个空字典,而在 Erg 中它是 Erg 中的 `!{:}`)。
+作为枚举类型,`{}` 是一个空类型,其元素中不包含任何内容。 `Never` 类型是这种类型的一个分类。
+相反,记录类 `{=}` 没有必需的实例属性,因此所有对象都是它的元素。 `Object` 是 this 的别名。
+一个`Object`(`Object`的一个补丁)是`的一个元素。 __sizeof__` 和其他非常基本的提供方法。
+
+```python
+AnyPatch = Patch Structural {=}
+ . __sizeof__ self = ...
+ .clone self = ...
+ ...
+Never = Class {}
+```
+
+请注意,没有其他类型或类在结构上与 `{}`、`Never` 类型等效,如果用户在右侧使用 `{}`、`Class {}` 定义类型,则会出错。
+这意味着,例如,`1..10 或 -10。 -1`,但 `1..10 和 -10... -1`。 例如,当它应该是 1..10 或 -10...-1 时是 `-1`。
+此外,如果您定义的类型(例如 `Int 和 Str`)会导致组合 `Object`,则会警告您只需将其设置为 `Object`。
+
+## 即时封锁
+
+Erg 有另一种语法 Instant 块,它只返回最后评估的值。 不能保留属性。
+
+```python
+x =
+ x = 1
+ y = x + 1
+ y ** 3
+assert x == 8
+
+y =
+ .x = 1 # 语法错误:无法在实体块中定义属性
+```
+
+## 数据类
+
+如果您尝试自己实现方法,则必须直接在实例中定义裸记录(由记录文字生成的记录)。
+这是低效的,并且随着属性数量的增加,错误消息等变得难以查看和使用。
+
+```python
+john = {
+ name = "John Smith"
+ age = !20
+ .greet! ref self = print! "Hello, my name is {self::name} and I am {self::age} years old."
+ .inc_age! ref! self = self::age.update! x -> x + 1
+}
+john + 1
+# 类型错误:{name = Str; 没有实现 + 年龄=诠释; 。迎接! =参考(自我)。 () => 无; inc_age! =参考! () => 无}, 整数
+```
+
+因此,在这种情况下,您可以继承一个记录类。 这样的类称为数据类。
+这在 [class](./type/04_class.md) 中有描述。
+
+```python
+Person = Inherit {name = Str; age = Nat}
+Person.
+ greet! ref self = print! "Hello, my name is {self::name} and I am {self::age} years old."
+ inc_age! ref! self = self::age.update! x -> x + 1
+
+john = Person.new {name = "John Smith"; age = 20}
+john + 1
+# 类型错误:Person、Int 没有实现 +
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/14_set.md b/doc/zh_CN/syntax/14_set.md
new file mode 100644
index 00000000..d405043c
--- /dev/null
+++ b/doc/zh_CN/syntax/14_set.md
@@ -0,0 +1,47 @@
+# Set
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/14_set.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+一个Set代表一个集合,它在结构上是一个重复的无序数组。
+
+```python
+assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3}
+assert {1, 2} == {1, 1, 2} # 重复的被自动删除
+assert {1, 2} == {2, 1}
+```
+
+Set可以执行集合操作。
+
+```python
+assert 1 in {1, 2, 3}
+assert not 1 in {}
+assert {1} or {2} == {1, 2}
+assert {1, 2} and {2, 3} == {2}
+assert {1, 2} not {2} == {1}
+```
+
+Set是同质集合。 为了使不同类的对象共存,它们必须同质化
+
+```python
+s: {Int or Str} = {"a", 1, "b", -1}
+```
+
+## Sets为类型
+Sets也可以被视为类型。 这种类型称为 _枚举类型_。
+
+```python
+i: {1, 2, 3} = 1
+assert i in {1, 2, 3}
+```
+
+Set的元素直接是类型的元素。
+请注意,这些Set本身是不同的。
+
+```python
+mut_set = {1, 2, 3}.into {Int; !3}
+mut_set.insert!(4)
+```
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/15_type.md b/doc/zh_CN/syntax/15_type.md
new file mode 100644
index 00000000..06d8b48b
--- /dev/null
+++ b/doc/zh_CN/syntax/15_type.md
@@ -0,0 +1,9 @@
+# 类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/15_type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+类型是 Erg 中一个非常重要的特性,所以我们有一个 [dedicated section](./type/01_type_system.md)。 请看那里。
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/16_iterator.md b/doc/zh_CN/syntax/16_iterator.md
new file mode 100644
index 00000000..06a05bba
--- /dev/null
+++ b/doc/zh_CN/syntax/16_iterator.md
@@ -0,0 +1,91 @@
+# 迭代器
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/16_iterator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+迭代器是用于检索容器元素的对象。
+
+```python
+for! 0..9, i =>
+ print! i
+```
+
+此代码打印数字 0 到 9。
+每个数字(=Int 对象)都分配给`i`,并执行以下操作(=`print!i`)。 这种重复执行称为__iteration__。
+
+现在让我们看看 `for!` 过程的类型签名。
+
+```python
+for!: |T: Type, I <: Iterable T| (I, T => None) => None
+```
+
+第一个参数似乎接受“Iterable”类型的对象。
+
+`Iterable` 是一个具有`.Iterator` 属性的类型,`.iter` 方法在request 方法中。
+
+```python
+Iterable T = Trait {
+ .Iterator = {Iterator}
+ .iter = Self(T). () -> Self.Iterator T
+}
+```
+
+`.Iterator` 属性的类型 `{Iterator}` 是所谓的 set-kind(kind 在 [here](./type/advanced/kind.md) 中描述)
+
+```python
+assert [1, 2, 3] in Iterable(Int)
+assert 1..3 in Iterable(Int)
+assert [1, 2, 3].Iterator == ArrayIterator
+assert (1..3).Iterator == RangeIterator
+
+log [1, 2, 3].iter() # <数组迭代器对象>
+log (1..3).iter() #
+```
+
+`ArrayIterator` 和 `RangeIterator` 都是实现 `Iterator` 的类,它们的存在只是为了提供 `Array` 和 `Range` 迭代函数。
+这种设计模式称为伴生类 [1 ](#1)。
+而“IteratorImpl”补丁是迭代功能的核心。 `Iterator` 只需要一个`.next` 方法,`IteratorImpl` 确实提供了几十种方法。 `ArrayIterator`和`RangeIterator`只需实现`.next`方法就可以使用`IteratorImpl`的实现方法。 为了方便起见,标准库实现了许多迭代器。
+
+```mermaid
+classDiagram
+ class Array~T~ {
+ ...
+ iter() ArrayIterator~T~
+ }
+ class Range~T~ {
+ ...
+ iter() RangeIterator~T~
+ }
+ class Iterable~T~ {
+ <>
+ iter() Iterator~T~
+ }
+ Iterable~T~ <|.. Array~T~: Impl
+ Iterable~T~ <|.. Range~T~: Impl
+ class ArrayIterator~T~ {
+ array: Array~T~
+ next() T
+ }
+ class RangeIterator~T~ {
+ range: Range~T~
+ next() T
+ }
+ class Iterator~T~ {
+ <>
+ next() T
+ }
+ Iterator~T~ <|.. ArrayIterator~T~: Impl
+ Iterator~T~ <|.. RangeIterator~T~: Impl
+
+ Array <-- ArrayIterator
+ Range <-- RangeIterator
+```
+
+诸如 `Iterable` 之类的以静态分派但统一的方式提供用于处理特征(在本例中为 `Iterator`)的接口的类型称为伴生类适配器。
+
+---
+
+1 这个模式似乎没有统一的名称,但是在 Rust 中,有 [companion struct 模式]( https://gist.github.com/qnighy/be99c2ece6f3f4b1248608a04e104b38#:~:text=%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82 %8B%E3%80%82-,companion%20struct,-%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A8%E3%80% 81%E3 %81%9D%E3%81%AE),并以此命名。 [↩](#f1)
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/17_mutability.md b/doc/zh_CN/syntax/17_mutability.md
new file mode 100644
index 00000000..8c646504
--- /dev/null
+++ b/doc/zh_CN/syntax/17_mutability.md
@@ -0,0 +1,105 @@
+# 可变性
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/17_mutability.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+正如我们已经看到的,所有 Erg 变量都是不可变的。 但是,Erg 对象具有可变性的概念。
+以下面的代码为例。
+
+```python
+a = [1, 2, 3]
+a = a + [4, 5, 6]
+print! a # [1, 2, 3, 4, 5, 6]
+```
+
+上面的代码实际上不能被 Erg 执行。 这是因为它不可重新分配。
+
+可以执行此代码。
+
+```python
+b = ![1, 2, 3]
+b.concat! [4, 5, 6]
+print! b # [1, 2, 3, 4, 5, 6]
+```
+
+`a, b` 的最终结果看起来一样,但它们的含义却大不相同。
+虽然 `a` 是表示 `Nat` 数组的变量,但第一行和第二行指向的对象是不同的。 名称`a`相同,但内容不同。
+
+```python
+a = [1, 2, 3]
+print! id! a # 0x000002A798DFE940
+_a = a + [4, 5, 6]
+print! id! _a # 0x000002A798DFE980
+```
+
+`id!` 过程返回对象驻留的内存地址。
+
+`b` 是一个 `Nat` “动态” 数组。 对象的内容发生了变化,但变量指向的是同一个东西
+
+```python
+b = ![1, 2, 3]
+print! id! b # 0x000002A798DFE220
+b.concat! [4, 5, 6]
+print! id! b # 0x000002A798DFE220
+```
+
+```python
+i = !0
+if! True. do!
+ do! i.inc!() # or i.add!(1)
+ do pass
+print! i # 1
+```
+
+`!` 是一个特殊的运算符,称为 __mutation 运算符__。 它使不可变对象可变。
+标有“!”的对象的行为可以自定义。
+
+```python
+Point = Class {.x = Int; .y = Int}
+
+# 在这种情况下 .x 是可变的,而 .y 保持不变
+Point! = Class {.x = Int!; .y = Int}
+Point!.
+ inc_x! ref!(self) = self.x.update! x -> x + 1
+
+p = Point!.new {.x = !0; .y = 0}
+p.inc_x!()
+print! p.x # 1
+```
+
+## 常量
+
+与变量不同,常量在所有范围内都指向同一事物。
+常量使用 `=` 运算符声明。
+
+```python
+PI = 3.141592653589
+match! x:
+ PI => print! "this is pi"
+```
+
+常量在全局以下的所有范围内都是相同的,并且不能被覆盖。因此,它们不能被 ``=`` 重新定义。此限制允许它用于模式匹配。
+`True` 和 `False` 可以用于模式匹配的原因是因为它们是常量。
+此外,常量总是指向不可变对象。诸如 `Str!` 之类的类型不能是常量。
+所有内置类型都是常量,因为它们应该在编译时确定。可以生成非常量的类型,但不能用于指定类型,只能像简单记录一样使用。相反,类型是其内容在编译时确定的记录。
+
+## 变量、名称、标识符、符号
+
+让我们理清一些与 Erg 中的变量相关的术语。
+
+变量是一种为对象赋予名称以便可以重用(或指向该名称)的机制。
+标识符是指定变量的语法元素。
+符号是表示名称的语法元素、记号。
+
+只有非符号字符是符号,符号不称为符号,尽管它们可以作为运算符的标识符。
+例如,`x` 是一个标识符和一个符号。 `x.y` 也是一个标识符,但它不是一个符号。 `x` 和 `y` 是符号。
+即使 `x` 没有绑定到任何对象,`x` 仍然是一个符号和一个标识符,但它不会被称为变量。
+`x.y` 形式的标识符称为字段访问器。
+`x[y]` 形式的标识符称为下标访问器。
+
+变量和标识符之间的区别在于,如果我们在 Erg 的语法理论意义上谈论变量,则两者实际上是相同的。
+在 C 中,类型和函数不能分配给变量; int 和 main 是标识符,而不是变量(严格来说可以赋值,但有限制)。
+然而,在Erg语中,“一切都是对象”。不仅函数和类型,甚至运算符都可以分配给变量。
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/18_ownership.md b/doc/zh_CN/syntax/18_ownership.md
new file mode 100644
index 00000000..890b627e
--- /dev/null
+++ b/doc/zh_CN/syntax/18_ownership.md
@@ -0,0 +1,112 @@
+#所有权制度
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/18_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+由于 Erg 是一种使用 Python 作为宿主语言的语言,因此内存管理的方法取决于 Python 的实现。
+但语义上 Erg 的内存管理与 Python 的不同。 一个显着的区别在于所有权制度和禁止循环引用。
+
+## 所有权
+
+Erg 有一个受 Rust 启发的所有权系统。
+Rust 的所有权系统通常被认为是深奥的,但 Erg 的所有权系统被简化为直观。
+在 Erg 中,__mutable objects__ 是拥有的,并且在所有权丢失后无法引用。
+
+```python
+v = [1, 2, 3].into [Int; !3]
+
+push! vec, x =
+ vec.push!(x)
+ vec
+
+# v ([1, 2, 3])的内容归w所有
+w = push! v, 4
+print! v # 错误:v 被移动了
+print!w # [1, 2, 3, 4]
+```
+
+例如,当一个对象被传递给一个子程序时,就会发生所有权转移。
+如果您想在赠送后仍然拥有所有权,则需要克隆、冻结或借用。
+但是,如后所述,可以借用的情况有限。
+
+## 复制
+
+复制一个对象并转移其所有权。 它通过将 `.clone` 方法应用于实际参数来做到这一点。
+复制的对象与原始对象完全相同,但相互独立,不受更改影响。
+
+复制相当于 Python 的深拷贝,由于它完全重新创建相同的对象,因此计算和内存成本通常高于冻结和借用。
+需要复制对象的子例程被称为“参数消耗”子例程。
+
+```python
+capitalize s: Str!=
+ s. capitalize!()
+ s
+
+s1 = !"hello"
+s2 = capitalize s1.clone()
+log s2, s1 # !"HELLO hello"
+```
+
+## 冻结
+
+我们利用了不可变对象可以从多个位置引用的事实,并将可变对象转换为不可变对象。
+这称为冻结。 例如,在从可变数组创建迭代器时会使用冻结。
+由于您不能直接从可变数组创建迭代器,请将其转换为不可变数组。
+如果您不想破坏数组,请使用 [`.freeze_map` 方法](./type/mut.md)。
+
+```python
+# 计算迭代器产生的值的总和
+sum|T <: Add + HasUnit| i: Iterator T = ...
+
+x = [1, 2, 3].into [Int; !3]
+x.push!(4)
+i = x.iter() # 类型错误:[Int; !4] 没有方法 `iter`
+y = x.freeze()
+i = y.iter()
+assert sum(i) == 10
+y # y 仍然可以被触摸
+```
+
+## 借
+
+借用比复制或冻结便宜。
+可以在以下简单情况下进行借款:
+
+```python
+peek_str ref(s: Str!) =
+ log s
+
+s = !"hello"
+peek_str s
+```
+
+借来的值称为原始对象的 __reference__。
+您可以“转租”对另一个子例程的引用,但您不能使用它,因为您只是借用它。
+
+```python
+steal_str ref(s: Str!) =
+ # 由于日志函数只借用参数,所以可以转租
+ log s
+ # 错误,因为丢弃函数消耗了参数
+ discard s # OwnershipError: 不能消费借来的值
+ # 提示:使用 `clone` 方法
+```
+
+```python
+steal_str ref(s: Str!) =
+ # 这也不好(=消耗右边)
+ x = s # OwnershipError: 不能消费借来的值
+ x
+```
+
+Erg 的引用比 Rust 的更严格。 引用是语言中的一等对象,但不能显式创建,它们只能指定为通过 `ref`/`ref!` 传递的参数。
+这意味着您不能将引用填充到数组中或创建将引用作为属性的类。
+
+但是,这样的限制是语言中的自然规范,一开始就没有引用,而且它们并没有那么不方便。
+
+## 循环引用
+
+Erg 旨在防止无意的内存泄漏,如果内存检查器检测到循环引用,则会发出错误。 在大多数情况下,这个错误可以通过弱引用 `Weak` 来解决。 但是,由于无法生成循环图等具有循环结构的对象,因此我们计划实现一个 API,可以将循环引用作为不安全操作生成。
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/19_visibility.md b/doc/zh_CN/syntax/19_visibility.md
new file mode 100644
index 00000000..a11d9879
--- /dev/null
+++ b/doc/zh_CN/syntax/19_visibility.md
@@ -0,0 +1,193 @@
+# 可见性
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/19_visibility.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg 变量具有 __visibility__ 的概念。
+到目前为止,我们看到的所有变量都称为 __private variables__。 这是一个外部不可见的变量。
+例如,`foo` 模块中定义的私有变量不能被另一个模块引用。
+
+```python
+# foo.er
+x = "this is an invisible variable"
+```
+
+```python
+#bar.er
+foo = import "foo"
+foo.x # AttributeError: 模块 'foo' 没有属性 'x' ('x' 是私有的)
+```
+
+另一方面,也有__public variables__,可以从外部引用。
+公共变量用`.`定义。
+
+```python
+# foo.er
+.x = "this is a visible variable"
+```
+
+```python
+#bar.er
+foo = import "foo"
+assert foo.x == "this is a visible variable"
+```
+
+您不需要向私有变量添加任何内容,但您也可以添加 `::` 或 `self::`(用于类型等的`Self::`)以表明它们是私有的。 增加。 如果它是一个模块,它也可以是 `module::`
+
+```python
+::x = "this is an invisible variable"
+assert ::x == x
+assert self ::x == ::x
+assert module::x == ::x
+```
+
+In the context of purely sequential execution, private variables are almost synonymous with local variables. It can be referenced from the inner scope.
+
+```python
+::x = "this is a private variable"
+y =
+ x + 1 # 完全是 module::x
+```
+
+通过使用`::`,可以区分作用域内同名的变量。
+在左侧指定要引用的变量的范围。 为顶层指定 `module`。
+如果未指定,则照常引用最里面的变量。
+
+```python
+::x = 0
+assert x == 0
+y =
+ ::x = 1
+ assert x == 1
+ z =
+ ::x = 2
+ assert ::x == 2
+ assert z::x == 2
+ assert y::x == 1
+ assert module::x == 0
+```
+
+在匿名子程序作用域中,`self` 指定了它自己的作用域
+
+```python
+x = 0
+f = x ->
+ log module::x, self::x
+f1# 0 1
+```
+
+`::` 还负责访问私有实例属性。
+
+```python
+x = 0
+C = Class {x = Int}
+C.
+ # 顶级 x 被引用(警告使用 module::x)
+ f1 self = x
+ # 实例属性 x 被引用
+ f2 self = self::x
+```
+
+## 外部模块中的可见性
+
+在一个模块中定义的类实际上可以定义来自外部模块的方法。
+
+```python
+# foo.er
+.Foo = Class()
+```
+
+```python
+#bar.er
+{Foo; ...} = import "foo"
+
+Foo::
+ private self = pass
+Foo.
+ public self = self::private()
+
+.f() =
+ foo = Foo.new()
+ foo.public()
+ foo::private() # 属性错误
+```
+
+但是,这两种方法都只在该模块中可用。
+外部定义的私有方法对 Foo 类的方法仅在定义模块内可见。
+公共方法暴露在类之外,但不在模块之外。
+
+```python
+# baz.er
+{Foo; ...} = import "foo"
+
+foo = Foo.new()
+foo.public() # 属性错误:“Foo”没有属性“public”(“public”在模块“bar”中定义)
+```
+
+此外,方法不能在要重新导出的类型中定义。
+这是为了避免混淆方法是否找到,具体取决于导入方法的模块。
+
+```python
+#bar.er
+{.Foo; ...} = import "foo"
+
+.Foo::
+ private self = pass # 错误
+Foo.
+ public self = self::private() # 错误
+```
+
+如果你想做这样的事情,定义一个 [patch](./type/07_patch.md)。
+
+```python
+#bar.er
+{Foo; ...} = import "foo"
+
+FooImpl = Patch Foo
+FooImpl :=:
+ private self = pass
+Foo Impl.
+ public self = self::private()
+```
+
+```python
+# baz.er
+{Foo; ...} = import "foo"
+{FooImpl; ...} = import "bar"
+
+foo = Foo.new()
+foo.public()
+```
+
+## 受限公共变量
+
+可变可见性不限于完全公共/私有。
+您也可以有限制地发布。
+
+```python
+# foo.er
+.record = {
+ .a = {
+ .(.record)x = 0
+ .(module)y = 0
+ .z = 0
+ }
+ _ = .a.x # OK
+ _ = .a.y # OK
+ _ = .a.z # OK
+}
+
+_ = .record.a.x # 可见性错误
+_ = .record.a.y # OK
+_ = .record.a.z # OK
+```
+
+```python
+foo = import "foo"
+_ = foo.record.a.x # 可见性错误
+_ = foo.record.a.y # 可见性错误
+_ = foo.record.a.z # OK
+```
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/20_naming_rule.md b/doc/zh_CN/syntax/20_naming_rule.md
new file mode 100644
index 00000000..7794a217
--- /dev/null
+++ b/doc/zh_CN/syntax/20_naming_rule.md
@@ -0,0 +1,52 @@
+# 命名约定
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/20_naming_rule.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+如果要将变量用作常量表达式,请确保它以大写字母开头。 两个或多个字母可能是小写的。
+
+```python
+i: Option Type = Int
+match i:
+ t: Type -> log "type"
+ None -> log "None"
+```
+
+具有副作用的对象总是以 `!` 结尾。 程序和程序方法,以及可变类型。
+然而,`Proc` 类型本身是不可变的。
+
+```python
+# Callable == Func or Proc
+c: Callable = print!
+match c:
+ p! -> log "proc" # `: Proc` 可以省略,因为它是不言自明的
+ f -> log "func"
+```
+
+如果您想向外界公开一个属性,请在开头使用 `.` 定义它。 如果你不把`.`放在开头,它将是私有的。 为避免混淆,它们不能在同一范围内共存。
+
+```python
+o = {x = 1; .x = 2} # 语法错误:同名的私有变量和公共变量不能共存
+```
+
+## 文字标识符
+
+可以通过将字符串括在单引号 ('') 中来规避上述规则。 也就是说,程序对象也可以在没有 `!` 的情况下分配。 但是,在这种情况下,即使该值是常量表达式,也不会被视为常量。
+像这样用单引号括起来的字符串称为文字标识符。
+这在调用Python等其他语言的API(FFI)时使用。
+
+```python
+bar! = pyimport("foo").'bar'
+```
+
+在 Erg 中也有效的标识符不需要用 '' 括起来。
+
+此外,文字标识符可以包含符号和空格,因此通常不能用作标识符的字符串可以用作标识符。
+
+```python
+'∂/∂t' y
+'test 1: pass x to y'()
+```
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/21_lambda.md b/doc/zh_CN/syntax/21_lambda.md
new file mode 100644
index 00000000..e97ca473
--- /dev/null
+++ b/doc/zh_CN/syntax/21_lambda.md
@@ -0,0 +1,97 @@
+# 匿名函数
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/21_lambda.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+匿名函数是一种无需命名即可动态创建函数对象的语法。
+
+```python
+# `->` 是匿名函数操作符
+# 同 `f x, y = x + y`
+f = (x, y) -> x + y
+# same as `g(x, y: Int): Int = x + y`
+g = (x, y: Int): Int -> x + y
+```
+
+如果只有一个参数,您可以省略 `()`。
+
+```python
+assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4]
+assert ((i, j) -> [i, j])(1, 2) == [1, 2]
+```
+
+在下面的情况下,它是 `0..9, (i -> ...)` 而不是 `(0..9, i) -> ...`
+`->` 在左侧只接受一个参数。 多个参数作为单个元组接收
+
+```python
+for 0..9, i: Int ->
+ ...
+```
+
+在匿名函数中,由于空格,解析存在差异
+
+```python
+# 在这种情况下,解释为 `T(() -> Int)`
+i: T() -> Int
+# 在这种情况下,它被解释为 (U()) -> Int
+k: U() -> Int
+```
+
+匿名函数可以不带参数使用。
+
+```python
+# `=>` 是一个匿名过程操作符
+p! = () => print! # `p!` 被调用
+# `() ->`, `() =>` 有语法糖 `do`, `do!`
+# p! = do! print! "`p!` 被调用
+p!() # `p!` 被调用
+```
+
+无参数函数可用于延迟初始化
+
+```python
+time = import "time"
+date = import "datetime"
+now = if! True:
+ do!:
+ time. sleep! 1000
+ date.now!()
+ do date.new("1970", "1", "1", "00", "00")
+```
+
+您还可以键入和模式匹配。 正因为如此,`match` 函数大多是借助匿名函数的力量来实现的。
+作为 `match` 函数的参数给出的匿名函数从顶部开始按顺序尝试。 因此,您应该在顶部描述特殊情况,在底部描述更一般的情况。 如果你弄错了顺序,编译器会发出警告(如果可能的话)
+
+```python
+n = (Complex or Ratio or Int).sample!()
+i = matchn:
+ PI -> PI # 如果等于常数 PI
+ For (i: 1..10) -> i # 整数从 1 到 10
+ (i: Int) -> i # Int
+ (c: Complex) -> c.real() # 对于复杂。 Int < Complex,但可以回退
+ _ -> panic "cannot convert to Int" # 如果以上都不适用。 match 必须涵盖所有模式
+```
+
+错误处理通常也使用 `?` 或 `match` 完成。
+
+```python
+res: ParseResult Int
+matchres:
+ i: Int -> i
+ err: Error -> panic err.msg
+
+res2: Result Int, Error
+match res2:
+ ok: Not Error -> log Type of ok
+ err: Error -> panic err.msg
+```
+
+## 匿名多相关系数
+
+```python
+# 与此相同 id|T|x:T = x
+id = |T| x: T -> x
+```
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/22_subroutine.md b/doc/zh_CN/syntax/22_subroutine.md
new file mode 100644
index 00000000..c4f34957
--- /dev/null
+++ b/doc/zh_CN/syntax/22_subroutine.md
@@ -0,0 +1,64 @@
+# 子程序签名
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/22_subroutine.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 函数
+
+```python
+some_func(x: T, y: U) -> V
+some_func: (T, U) -> V
+```
+
+## 过程
+
+```python
+some_proc!(x: T, y: U) => V
+some_proc!: (T, U) => V
+```
+
+## 函数方法
+
+方法类型不能用`Self`在外部指定
+
+```python
+.some_method(self, x: T, y: U) => ()
+# Self.(T, U) => () 拥有 self 的所有权
+.some_method: Ref(Self). (T, U) => ()
+```
+
+## 过程方法(依赖)
+
+在下文中,假设类型 `T!` 采用类型参数 `N: Nat`。 要在外部指定它,请使用类型变量
+
+```python
+T!: Nat -> Type
+# ~> 表示应用前后类型参数的状态(此时self必须是变量引用)
+T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => ()
+```
+
+注意,`.some_method` 的类型是 `Ref!(T(N ~> N+X))。 ({X}) => () | N,X:Nat`。
+对于没有 `ref!` 的方法,即在应用后被剥夺所有权,不能使用类型参数转换(`~>`)。
+
+如果取得所有权,则如下所示。
+
+```python
+# 如果不使用N,可以用_省略。
+# .some_method!: |N, X: Nat| T!(N).({X}) => T!(N+X)
+.some_method!|N, X: Nat|(self(N), X: Nat) => T!(N+X)
+```
+
+## 运算符
+
+可以通过用 ` 括起来将其定义为普通函数。
+
+中性字母运算符,例如 `and` 和 `or` 可以通过用 ` 括起来定义为中性运算符。
+
+```python
+and(x, y, z) = x and y and z
+`_+_`(x: Foo, y: Foo) = x.a + y.a
+`-_`(x: Foo) = Foo.new(-x.a)
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/23_closure.md b/doc/zh_CN/syntax/23_closure.md
new file mode 100644
index 00000000..221214ed
--- /dev/null
+++ b/doc/zh_CN/syntax/23_closure.md
@@ -0,0 +1,98 @@
+# 关闭
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/23_closure.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg 子例程有一个称为“闭包”的功能,可以捕获外部变量。
+
+```python
+outer = 1
+f x = outer + x
+assert f(1) == 2
+```
+
+与不可变对象一样,可变对象也可以被捕获。
+
+```python
+sum = !0
+for! 1..10, i =>
+ sum.add!i
+assert sum == 45
+
+p!x=
+ sum.add!x
+p!(1)
+assert sum == 46
+```
+
+但是请注意,函数不能捕获可变对象。
+如果可以在函数中引用可变对象,则可以编写如下代码。
+
+```python
+# !!! 这段代码实际上给出了一个错误!!!
+i = !0
+f x = i + x
+assert f 1 == 1
+i.add! 1
+assert f 1 == 2
+```
+
+该函数应该为相同的参数返回相同的值,但假设被打破了。
+请注意,`i` 仅在调用时进行评估。
+
+如果您想在定义函数时获取可变对象的内容,请调用`.clone`
+
+```python
+i = !0
+immut_i = i.clone().freeze()
+fx = immut_i + x
+assert f 1 == 1
+i.add! 1
+assert f 1 == 1
+```
+
+## avoid mutable state, functional programming
+
+```python
+# Erg
+sum = !0
+for! 1..10, i =>
+ sum.add!i
+assert sum == 45
+```
+
+上面的等效程序可以用 Python 编写如下:
+
+```python
+# Python
+sum = 0
+for i in range(1, 10):
+ sum += i
+assert sum == 45
+```
+
+但是,Erg 建议使用更简单的表示法。
+与其使用子例程和可变对象来传递状态,不如使用一种使用函数来定位状态的风格。这称为函数式编程
+
+```python
+# 功能风格
+sum = (1..10).sum()
+assert sum == 45
+```
+
+上面的代码给出了与之前完全相同的结果,但是您可以看到这个代码要简单得多。
+
+`fold` 函数可以用来做比 sum 更多的事情。
+`fold` 是一个迭代器方法,它为每次迭代执行参数 `f`。
+累加结果的计数器的初始值在 `init` 中指定,并在 `acc` 中累加。
+
+```python
+# 从0开始,结果会
+sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i)
+assert sum == 45
+```
+
+Erg 被设计为对使用不可变对象进行编程的自然简洁描述。
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/24_module.md b/doc/zh_CN/syntax/24_module.md
new file mode 100644
index 00000000..f518c1dc
--- /dev/null
+++ b/doc/zh_CN/syntax/24_module.md
@@ -0,0 +1,44 @@
+# module
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/24_module.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg allows you to think of the file itself as a single record. This is called a module.
+
+```python: foo.er
+# foo.er
+.i = 1
+```
+
+```python
+# 定义 foo 模块与定义这条记录几乎相同
+foo = {.i = 1}
+```
+
+```python: bar.er
+#bar.er
+foo = import "foo"
+print! foo #
+assert foo.i == 1
+```
+
+由于模块类型也是记录类型,因此可以进行解构赋值
+
+```python
+{sin; cos; ...} = import "math"
+```
+
+## 模块可见性
+
+```console
+└─┬ ./src
+ ├─ lib.er
+ ├─ foo.er
+ ├─bar.er
+ └─┬ bar
+ ├─ baz.er
+ └─ qux.er
+```
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/25_object_system.md b/doc/zh_CN/syntax/25_object_system.md
new file mode 100644
index 00000000..5272ca56
--- /dev/null
+++ b/doc/zh_CN/syntax/25_object_system.md
@@ -0,0 +1,84 @@
+# 目的
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/25_object_system.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+可以分配给变量的所有数据。 `Object` 类的属性如下。
+
+* `.__repr__`:返回对象的(非丰富)字符串表示
+* `.__sizeof__`:返回对象的大小(包括堆分配)
+* `.__dir__`: 返回对象属性列表
+* `.__hash__`:返回对象的哈希值
+* `.__getattribute__`: 获取并返回对象的属性
+* `.clone`:创建并返回一个对象的克隆(在内存中有一个独立的实体)
+* `.copy`:返回对象的副本(指向内存中的同一事物)
+
+## 记录
+
+由记录文字(`{attr = value; ...}`)生成的对象。
+这个对象有基本的方法,比如`.clone`和`.__sizeof__`。
+
+```python
+obj = {.x = 1}
+assert obj.x == 1
+
+obj2 = {...x; .y = 2}
+assert obj2.x == 1 and obj2.y == 2
+```
+
+## 属性
+
+与对象关联的对象。 特别是,将 self (`self`) 作为其隐式第一个参数的子例程属性称为方法。
+
+```python
+# 请注意,private_attr 中没有`.`
+record = {.public_attr = j; private_attr = 2; .method = self -> self.i + 1}
+record. public_attr == 2
+record.private_attr # AttributeError: private_attr 是私有的
+assert record.method() == 3
+```
+
+## 元素
+
+属于特定类型的对象(例如,“1”是“Int”类型的元素)。所有对象至少是`{=}`类型的元素。
+类的元素有时称为实例。
+
+## 子程序
+
+表示作为函数或过程(包括方法)实例的对象。代表子程序的类是“子程序”。
+实现 `.__call__` 的对象通常称为 `Callable`。
+
+## 可调用
+
+一个实现`.__call__`的对象。它也是 `Subroutine` 的超类。
+
+## 类型
+
+定义需求属性并使对象通用化的对象。
+主要有两种类型:多态类型和单态类型。典型的单态类型有`Int`、`Str`等,多态类型有`Option Int`、`[Int; 3]`等
+此外,定义改变对象状态的方法的类型称为 Mutable 类型,需要在变量属性中添加 `!`(例如动态数组:`[T; !_]`)。
+
+## 班级
+
+具有 `.__new__`、`.__init__` 方法等的类型。实现基于类的面向对象。
+
+## 功能
+
+对外部变量(不包括静态变量)有读权限但对外部变量没有读/写权限的子程序。换句话说,它没有外部副作用。
+Erg 函数的定义与 Python 的不同,因为它们不允许副作用。
+
+## 程序
+
+它对外部变量具有读取和“自我”权限,对静态变量具有读/写权限,并允许使用所有子例程。它可能有外部副作用。
+
+## 方法
+
+隐式将“self”作为第一个参数的子例程。它与简单的函数/过程是不同的类型。
+
+## 实体
+
+不是子例程和类型的对象。
+单态实体(`1`、`"a"` 等)也称为值对象,多态实体(`[1, 2, 3], {"a": 1}`)也称为容器对象。
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/26_pattern_matching.md b/doc/zh_CN/syntax/26_pattern_matching.md
new file mode 100644
index 00000000..54aa9c25
--- /dev/null
+++ b/doc/zh_CN/syntax/26_pattern_matching.md
@@ -0,0 +1,195 @@
+# 模式匹配,可反驳
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/26_pattern_matching.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## Erg 中可用的模式
+
+### 变量模式
+
+```python
+# 基本任务
+i = 1
+# 有类型
+i: Int = 1
+# 匿名类型
+i: {1, 2, 3} = 2
+
+# 功能
+fn x = x + 1
+# 等于
+fn x: Add(Int) = x + 1
+# (匿名)函数
+fn = x -> x + 1
+fn: Int -> Int = x -> x + 1
+
+# 高阶类型
+a: [Int; 4] = [0, 1, 2, 3]
+# or
+a: Array Int, 4 = [0, 1, 2, 3]
+```
+
+### 文字字面量
+
+```python
+# 如果在编译时无法确定 `i` 为 1,则引发 TypeError。
+# 省略 `_: {1} = i`
+1 = i
+
+# 简单的模式匹配
+match x:
+ 1 -> "1"
+ 2 -> "2"
+ _ -> "other"
+
+# 斐波那契函数
+fib0 = 0
+fib1 = 1
+fibn: Nat = fibn-1 + fibn-2
+```
+
+### 常量模式
+
+```python
+cond=False
+match! cond:
+ True => print! "cond is True"
+ _ => print! "cond is False"
+
+PI = 3.141592653589793
+E = 2.718281828459045
+num = PI
+name = match num:
+ PI -> "pi"
+ E -> "e"
+ _ -> "unnamed"
+```
+
+### 筛子图案
+
+```python
+# 这两个是一样的
+Array(T, N: {N | N >= 3})
+Array(T, N | N >= 3)
+
+f M, N | M >= 0, N >= 1 = ...
+f(1, 0) # 类型错误:N(第二个参数)必须为 1 或更多
+```
+
+### 丢弃(通配符)模式
+
+```python
+_ = 1
+_: Int = 1
+zero_ = 0
+right(_, r) = r
+```
+
+### 可变长度模式
+
+它与稍后描述的元组/数组/记录模式结合使用。
+
+```python
+[i,...j] = [1, 2, 3, 4]
+assert j == [2, 3, 4]
+first|T|(fst: T, ...rest: T) = fst
+assert first(1, 2, 3) == 1
+```
+
+### 元组模式
+
+```python
+(i, j) = (1, 2)
+((k, l), _) = ((1, 2), (3, 4))
+# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2))
+m, n = 1, 2
+
+f(x, y) = ...
+```
+
+### 数组模式
+
+```python
+[i, j] = [1, 2]
+[[k, l], _] = [[1, 2], [3, 4]]
+
+length[] = 0
+length[_, ...rest] = 1 + lengthrest
+```
+
+#### record 模式
+
+```python
+record = {i = 1; j = 2; k = 3}
+{j; ...} = record # i, k 将被释放
+
+{sin; cos; tan; ...} = import "math"
+{*} = import "math" # import all
+
+person = {name = "John Smith"; age = 20}
+age = match person:
+ {name = "Alice"; _} -> 7
+ {_; age} -> age
+
+f {x: Int; y: Int} = ...
+```
+
+### 数据类模式
+
+```python
+Point = Inherit {x = Int; y = Int}
+p = Point::{x = 1; y = 2}
+Point::{x; y} = p
+
+Nil T = Class Impl := Phantom T
+Cons T = Inherit {head = T; rest = List T}
+List T = Enum Nil(T), Cons(T)
+List T.
+ first self =
+ match self:
+ Cons::{head; ...} -> x
+ _ -> ...
+ second self =
+ match self:
+ Cons::{rest=Cons::{head; ...}; ...} -> head
+ _ -> ...
+```
+
+### 枚举模式
+
+* 其实只是枚举类型
+
+```python
+match x:
+ i: {1, 2} -> "one or two: {i}"
+ _ -> "other"
+```
+
+### Range 模式
+
+* 实际上,它只是一个区间类型。
+
+```python
+# 0 < i < 1
+i: 0<..<1 = 0.5
+# 1 < j <= 2
+_: {[I, J] | I, J: 1<..2} = [1, 2]
+# 1 <= i <= 5
+match i
+ i: 1..5 -> ...
+```
+
+### 不是模式的东西,不能被模式化的东西
+
+模式是可以唯一指定的东西。 在这方面,模式匹配不同于普通的条件分支。
+
+条件规格不是唯一的。 例如,要检查数字 `n` 是否为偶数,正统是 `n % 2 == 0`,但也可以写成 `(n / 2).round() == n / 2`。
+非唯一形式无论是正常工作还是等效于另一个条件都不是微不足道的。
+
+#### Set
+
+没有固定的模式。 因为集合没有办法唯一地检索元素。
+您可以通过迭代器检索它们,但不能保证顺序。
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/27_comprehension.md b/doc/zh_CN/syntax/27_comprehension.md
new file mode 100644
index 00000000..3883de17
--- /dev/null
+++ b/doc/zh_CN/syntax/27_comprehension.md
@@ -0,0 +1,67 @@
+# Comprehension
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/27_comprehension.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Array 和 `[expr | (name <- iterable)+ (predicate)*]`,
+set 和 `{expr | (name <- iterable)+ (predicate)*}`,
+你可以创建一个字典 `{key: value | (name <- iterable)+ (predicate)*}`.
+
+由`|`分隔的子句的第一部分称为布局子句(位置子句),第二部分称为绑定子句(绑定子句),第三部分称为保护子句(条件子句)。
+保护子句可以省略,但绑定子句不能省略,保护子句不能在绑定子句之前。
+
+理解示例
+
+```python
+# 布局子句是 i
+# 绑定子句是 i <- [0, 1, 2]
+assert [i | i <- [0, 1, 2]] == [0, 1, 2]
+
+# 布局子句是 i / 2
+# 绑定子句是 i <- 0..2
+assert [i/2 | i <- 0..2] == [0.0, 0.5, 1.0]
+
+# 布局子句是 (i, j)
+# 绑定子句 i <- 0..2, j <- 0..2
+# 保护子句是 (i + j) % 2 == 0
+assert [(i, j) | i <- 0..2; j <- 0..2; (i + j) % 2 == 0] == [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)]
+
+assert {i % 2 | i <- 0..9} == {0, 1}
+assert {k: v | k <- ["a", "b"]; v <- [1, 2]} == {"a": 1, "b": 2}
+```
+
+Erg推导式受到 Haskell 的启发,但有一些不同。
+对于 Haskell 列表推导,变量的顺序会对结果产生影响,但在 Erg 中这并不重要。
+
+``` haskell
+-- Haskell
+[(i, j) | i <- [1..3], j <- [3..5]] == [(1,3),(1,4),(1,5),(2 ,3),(2,4),(2,5),(3,3),(3,4),(3,5)]
+[(i, j) | j <- [3..5], i <- [1..3]] == [(1,3),(2,3),(3,3),(1 ,4),(2,4),(3,4),(1,5),(2,5),(3,5)]
+```
+
+```python
+# Erg
+assert [(i, j) | i <- 1..<3; j <- 3..<5] == [(i, j) | j <- 3..<5; i <- 1.. <3]
+```
+
+该规范与 Python 的规范相同。
+
+```python
+# Python
+assert [(i, j) for i in range(1, 3) for j in range(3, 5)] == [(i, j) for j in range(3, 5) for i in range(1, 3)]
+```
+
+## 筛子类型
+
+与推导类似的是筛类型。 筛子类型是以`{Name: Type | Predicate}`创建的(枚举类型)
+sieve类型的情况下,只能指定一个Name,不能指定布局(但是如果是tuple类型可以处理多个值),Predicate可以在编译时计算,即 ,只能指定一个常量表达式。
+
+```python
+Nat = {I: Int | I >= 0}
+# 如果谓词表达式只有and,可以替换为:
+# Nat2D = {(I, J): (Int, Int) | I >= 0; J >= 0}
+Nat2D = {(I, J): (Int, Int) | I >= 0 and J >= 0}
+```
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/28_spread_syntax.md b/doc/zh_CN/syntax/28_spread_syntax.md
new file mode 100644
index 00000000..4251afb9
--- /dev/null
+++ b/doc/zh_CN/syntax/28_spread_syntax.md
@@ -0,0 +1,44 @@
+# 传播赋值
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/28_spread_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+在分解赋值中,将 `...` 放在变量前面会将所有剩余元素展开到该变量中。 这称为扩展赋值。
+
+```python
+[x,...y] = [1, 2, 3]
+assert x == 1
+assert y == [2, 3]
+x, ...y = (1, 2, 3)
+assert x == 1
+assert y == (2, 3)
+```
+
+## 提取赋值
+
+如果在 `...` 之后没有写入任何内容,则忽略并分配剩余的元素。 这种类型的扩展赋值具体称为抽取赋值。
+提取分配是一种方便的语法,用于本地化模块或记录中的特定属性。
+
+```python
+{sin; cos; tan; ..} = import "math"
+```
+
+After that, you can use `sin, cos, tan` locally.
+
+You can do the same with records.
+
+```python
+record = {x = 1; y = 2}
+{x; y; ...} = record
+```
+
+If you want to expand all, use `{*} = record`. It is `open` in OCaml.
+
+```python
+record = {x = 1; y = 2}
+{*} = records
+assert x == 1 and y == 2
+```
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/29_decorator.md b/doc/zh_CN/syntax/29_decorator.md
new file mode 100644
index 00000000..823a1d58
--- /dev/null
+++ b/doc/zh_CN/syntax/29_decorator.md
@@ -0,0 +1,122 @@
+# 装饰器(修饰符)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/29_decorator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+装饰器用于向类型或函数添加或演示特定状态或行为。
+装饰器的语法如下。
+
+```python
+@deco
+X=...
+```
+
+你可以有多个装饰器,只要它们不冲突。
+
+装饰器不是一个特殊的对象,它只是一个单参数函数。 装饰器等价于下面的伪代码。
+
+```python
+X=...
+X = deco(X)
+```
+
+Erg 不允许重新分配变量,因此上面的代码不起作用。
+对于简单的变量,它与`X = deco(...)` 相同,但对于即时块和子例程,你不能这样做,所以你需要一个装饰器。
+
+```python
+@deco
+f x =
+ y = ...
+ x + y
+
+# 还可以防止代码变成水平的
+@LongNameDeco1
+@LongNameDeco2
+C = Class...
+```
+
+下面是一些常用的内置装饰器。
+
+## 可继承
+
+指示定义类型是可继承的类。 如果为参数 `scope` 指定 `"public"`,甚至可以继承外部模块的类。 默认情况下它是`"private"`,不能被外部继承。
+
+## 最后
+
+使该方法不可覆盖。 将它添加到类中使其成为不可继承的类,但由于它是默认值,因此没有意义。
+
+## 覆盖
+
+覆盖属性时使用。 默认情况下,如果您尝试定义与基类相同的属性,Erg 将抛出错误。
+
+## 实现
+
+表示参数 trait 已实现。
+
+```python
+Add = Trait {
+ .`_+_` = Self.(Self) -> Self
+}
+Sub = Trait {
+ .`_-_` = Self.(Self) -> Self
+}
+
+C = Class({i = Int}, Impl := Add and Sub)
+C.
+ @Impl Add
+ `_+_` self, other = C.new {i = self::i + other::i}
+ @Impl Sub
+ `_-_` self, other = C.new {i = self::i - other::}
+```
+
+## 附
+
+指定默认情况下随 trait 附带的附件补丁。
+这允许您重现与 Rust 特征相同的行为。
+
+```python
+# foo.er
+Add R = Trait {
+ .AddO = Type
+ .`_+_` = Self.(R) -> Self.AddO
+}
+@Attach AddForInt, AddForOdd
+ClosedAdd = Subsume Add(Self)
+
+AddForInt = Patch(Int, Impl := ClosedAdd)
+AddForInt.AddO = Int
+AddForOdd = Patch(Odd, Impl := ClosedAdd)
+AddForOdd.AddO = Even
+```
+
+当从其他模块导入特征时,这将自动应用附件补丁。
+
+```Python
+# 本来应该同时导入IntIsBinAdd和OddIsBinAdd,但是如果是附件补丁可以省略
+{BinAdd; ...} = import "foo"
+
+assert Int. AddO == Int
+assert Odd.AddO == Even
+```
+
+在内部,它只是使用 trait 的 .attach 方法附加的。 可以使用 trait 的 `.detach` 方法消除冲突。
+
+```python
+@Attach X
+T = Trait...
+assert X in T. attaches
+U = T.detach(X).attach(Y)
+assert X not in U. attaches
+assert Y in U. attaches
+```
+
+## 已弃用
+
+指示变量规范已过时且不推荐使用。
+
+## 测试
+
+表示这是一个测试子例程。 测试子程序使用 `erg test` 命令运行。
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/30_error_handling.md b/doc/zh_CN/syntax/30_error_handling.md
new file mode 100644
index 00000000..770493c8
--- /dev/null
+++ b/doc/zh_CN/syntax/30_error_handling.md
@@ -0,0 +1,110 @@
+# 错误处理系统
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/30_error_handling.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+主要使用Result类型。
+在 Erg 中,如果您丢弃 Error 类型的对象(顶层不支持),则会发生错误。
+
+## 异常,与 Python 互操作
+
+Erg 没有异常机制(Exception)。 导入 Python 函数时
+
+* 将返回值设置为 `T 或 Error` 类型
+* `T or Panic` 类型(可能导致运行时错误)
+
+有两个选项,`pyimport` 默认为后者。 如果要作为前者导入,请使用
+在 `pyimport` `exception_type` 中指定 `Error` (`exception_type: {Error, Panic}`)。
+
+## 异常和结果类型
+
+`Result` 类型表示可能是错误的值。 `Result` 的错误处理在几个方面优于异常机制。
+首先,从类型定义中可以看出子程序可能会报错,实际使用时也很明显。
+
+```python
+# Python
+try:
+ x = foo().bar()
+ y = baz()
+ qux()
+except e:
+ print(e)
+```
+
+在上面的示例中,仅凭此代码无法判断哪个函数引发了异常。 即使回到函数定义,也很难判断函数是否抛出异常。
+
+```python
+# Erg
+try!:
+ do!:
+ x = foo!()?.bar()
+ y = baz!()
+ qux!()?
+ e =>
+ print! e
+```
+
+另一方面,在这个例子中,我们可以看到 `foo!` 和 `qux!` 会引发错误。
+确切地说,`y` 也可能是 `Result` 类型,但您最终必须处理它才能使用里面的值。
+
+使用 `Result` 类型的好处不止于此。 `Result` 类型也是线程安全的。 这意味着错误信息可以(轻松)在并行执行之间传递。
+
+## 语境
+
+由于 `Error`/`Result` 类型本身不会产生副作用,不像异常,它不能有发送位置(Context)等信息,但是如果使用 `.context` 方法,可以将信息放在 `错误`对象。 可以添加。 `.context` 方法是一种使用 `Error` 对象本身并创建新的 `Error` 对象的方法。 它们是可链接的,并且可以包含多个上下文。
+```python
+f() =
+ todo() \
+ .context "to be implemented in ver 1.2" \
+ .context "and more hints ..."
+
+f()
+# Error: not implemented yet
+# hint: to be implemented in ver 1.2
+# hint: and more hints ...
+```
+
+请注意,诸如 `.msg` 和 `.kind` 之类的 `Error` 属性不是次要的,因此它们不是上下文,并且不能像最初创建时那样被覆盖。
+
+## 堆栈跟踪
+
+`Result` 类型由于其方便性在其他语言中经常使用,但与异常机制相比,它的缺点是难以理解错误的来源。
+因此,在 Erg 中,`Error` 对象具有名为 `.stack` 的属性,并再现了类似伪异常机制的堆栈跟踪。
+`.stack` 是调用者对象的数组。 每次 Error 对象被`return`(包括通过`?`)时,它都会将它的调用子例程推送到`.stack`。
+如果它是 `?`ed 或 `.unwrap`ed 在一个不可能 `return` 的上下文中,它会因为回溯而恐慌。
+
+```python
+f x =
+ ...
+ y = foo.try_some(x)?
+ ...
+
+g x =
+ y = f(x)?
+ ...
+
+i = g(1)?
+# Traceback (most recent call first):
+# ...
+# Foo.try_some, line 10, file "foo.er"
+# 10 | y = foo.try_some(x)?
+# module::f, line 23, file "foo.er"
+# 23 | y = f(x)?
+# module::g, line 40, file "foo.er"
+# 40 | i = g(1)?
+# Error: ...
+```
+
+## 恐慌
+
+Erg 还有一种处理不可恢复错误的机制,称为 __panicing__。
+不可恢复的错误是由外部因素引起的错误,例如软件/硬件故障、严重到无法继续执行代码的错误或程序员未预料到的错误。 等如果发生这种情况,程序将立即终止,因为程序员的努力无法恢复正常运行。 这被称为“恐慌”。
+
+恐慌是通过 `panic` 功能完成的。
+
+```python
+panic "something went wrong!"
+```
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/31_pipeline.md b/doc/zh_CN/syntax/31_pipeline.md
new file mode 100644
index 00000000..aa2f8c03
--- /dev/null
+++ b/doc/zh_CN/syntax/31_pipeline.md
@@ -0,0 +1,34 @@
+# 管道运算符
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/31_pipeline.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+管道运算符的使用方式如下:
+
+```python
+assert f(g(x)) == (x |> g |> f)
+assert f(g(x, y)) == ((x, y) |> g |> f)
+```
+
+换句话说,`Callable(object)` 的顺序可以更改为 `object |> Callable`。
+管道运算符也可用于方法。 对于方法,`object.method(args)` 更改为 `object |>.method(args)`。
+它看起来只是更多的`|>`,但由于粘合强度较低,您可以减少`()`的数量。
+
+```python
+rand = -1.0..1.0 |>.sample!()
+log rand # 0.2597...
+
+1+1*2 |>.times do log("a", end := "") # aaa
+
+evens = 1..100 |>.iter |>.filter i -> i % 2 == 0 |>.collect Array
+# 在没有管道操作符的情况下实现,
+_evens = (1..100).iter().filter(i -> i % 2 == 0).collect(Array)
+# or
+__evens = 1..100 \
+ .iter() \
+ .filter i -> i % 2 == 0 \
+ .collect Array
+```
+
+
+ 上一页 | 下一页
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/32_integration_with_Python.md b/doc/zh_CN/syntax/32_integration_with_Python.md
new file mode 100644
index 00000000..0b716866
--- /dev/null
+++ b/doc/zh_CN/syntax/32_integration_with_Python.md
@@ -0,0 +1,84 @@
+# 与 Python 集成
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/32_integration_with_Python.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 导出到 Python
+
+编译 Erg 脚本时,会生成一个 .pyc 文件,可以简单地将其作为 Python 模块导入。
+但是,无法从 Python 访问在 Erg 端设置为私有的变量。
+
+```python
+# foo.er
+.public = "this is a public variable"
+private = "this is a private variable"
+```
+
+```console
+erg --compile foo.er
+```
+
+```python
+import foo
+
+print(foo.public)
+print(foo.private) # 属性错误:
+```
+
+## 从 Python 导入
+
+默认情况下,从 Python 导入的所有对象都是“Object”类型。 由于此时无法进行比较,因此有必要细化类型。
+
+## 标准库中的类型规范
+
+Python 标准库中的所有 API 都是由 Erg 开发团队指定的类型。
+
+```python
+time = pyimport "time"
+time.sleep! 1
+```
+
+## 用户脚本的类型规范
+
+创建一个类型为 Python `foo` 模块的 `foo.d.er` 文件。
+Python 端的类型提示被忽略,因为它们不是 100% 保证的。
+
+```python
+# foo.py
+X = ...
+def bar(x):
+ ...
+def baz():
+ ...
+...
+```
+
+```python
+# foo.d.er
+foo = pyimport "foo"
+.X = declare foo.'X', Int
+.bar = declare foo.'bar', Int -> Int
+.baz! = declare foo.'baz', () => Int
+```
+
+```python
+foo = pyimport "foo"
+assert foo.bar(1) in Int
+```
+
+这通过在运行时执行类型检查来确保类型安全。 ``declare`` 函数大致如下工作
+
+```python
+declare|S: Subroutine| sub!: S, T =
+ # 实际上,=> 可以强制转换为没有块副作用的函数
+ x =>
+ assert x in T.Input
+ y = sub!(x)
+ assert y in T.Output
+ y
+```
+
+由于这是运行时开销,因此计划使用 Erg 的类型系统对 Python 脚本进行静态类型分析
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/33_package_system.md b/doc/zh_CN/syntax/33_package_system.md
new file mode 100644
index 00000000..6a2b5e3d
--- /dev/null
+++ b/doc/zh_CN/syntax/33_package_system.md
@@ -0,0 +1,85 @@
+# 打包系统
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/33_package_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Erg包大致可以分为app包,即应用程序,以及lib包,即库。
+应用包的入口点是`src/app.er`。 `app.er` 中定义的`main` 函数被执行。
+lib 包的入口点是`src/lib.er`。导入包相当于导入 `lib.er`。
+
+一个包有一个称为模块的子结构,在 Erg 中是一个 Erg 文件或由 Erg 文件组成的目录。外部 Erg 文件/目录是作为模块对象的可操作对象。
+
+为了将目录识别为模块,有必要在目录中放置一个“(目录名称).er”文件。
+这类似于 Python 的 `__init__.py`,但与 `__init__.py` 不同的是,它放在目录之外。
+
+例如,考虑以下目录结构。
+
+```console
+└─┬ ./src
+ ├─ app.er
+ ├─ foo.er
+ ├─ bar.er
+ └─┬ bar
+ ├─ baz.er
+ └─ qux.er
+```
+
+您可以在 `app.er` 中导入 `foo` 和 `bar` 模块。由于 `bar.er` 文件,`bar` 目录可以被识别为一个模块。
+`foo` 模块是由文件组成的模块,`bar` 模块是由目录组成的模块。 `bar` 模块还包含 `baz` 和 `qux` 模块。
+该模块只是 `bar` 模块的一个属性,可以从 `app.er` 访问,如下所示。
+
+```python
+# app.er
+foo = import "foo"
+bar = import "bar"
+baz = bar.baz
+# or `baz = import "bar/baz"`
+
+main args =
+ ...
+```
+
+请注意用于访问子模块的 `/` 分隔符。 这是因为可以有诸如 `bar.baz.er` 之类的文件名。
+不鼓励使用此类文件名,因为 `.er` 前缀在 Erg 中是有意义的。
+例如,用于测试的模块。 以 `.test.er` 结尾的文件是一个(白盒)测试模块,它在运行测试时执行一个用 `@Test` 修饰的子例程。
+
+```console
+└─┬ ./src
+ ├─ app.er
+ ├─ foo.er
+ └─ foo.test.er
+./src
+
+```python
+# app.er
+foo = import "foo"
+
+main args =
+ ...
+```
+
+此外,以 .private.er 结尾的文件是私有模块,只能由同一目录中的模块访问。
+
+```console
+└─┬
+ ├─ foo.er
+ ├─ bar.er
+ └─┬ bar
+ ├─ baz.private.er
+ └─ qux.er
+```
+
+```python
+# foo.er
+bar = import "bar"
+bar.qux
+bar.baz # AttributeError: module 'baz' is private
+```
+
+```python
+# qux.er
+baz = import "baz"
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/34_generator.md b/doc/zh_CN/syntax/34_generator.md
new file mode 100644
index 00000000..903ca254
--- /dev/null
+++ b/doc/zh_CN/syntax/34_generator.md
@@ -0,0 +1,37 @@
+# 生成器
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/34_generator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+生成器是在块中使用 `yield!` 过程的特殊过程。
+
+```python
+g!() =
+ yield! 1
+ yield! 2
+ yield! 3
+```
+
+`yield!` 是在调用`self!.yield!` 的子程序块中定义的过程。 和`return`一样,它把传递给它的值作为返回值返回,但它具有保存block当前执行状态,再次调用时从头开始执行的特性。
+生成器既是过程又是迭代器; Python 生成器是一个创建迭代器的函数,而 Erg 直接迭代。 过程本身通常不是可变对象(没有`!`),但生成器是可变对象,因为它自己的内容可以随着每次执行而改变。
+
+```python
+# Generator!
+g!: Generator!((), Int)
+assert g!() == 1
+assert g!() == 2
+assert g!() == 3
+```
+
+Python 风格的生成器可以定义如下。
+
+```python
+make_g() = () =>
+ yield! 1
+ yield! 2
+ yield! 3
+make_g: () => Generator!
+```
+
+
+ 上一页 | Next
+
diff --git a/doc/zh_CN/syntax/SUMMARY.md b/doc/zh_CN/syntax/SUMMARY.md
new file mode 100644
index 00000000..3715a451
--- /dev/null
+++ b/doc/zh_CN/syntax/SUMMARY.md
@@ -0,0 +1,71 @@
+# 概括
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/SUMMARY.md&commit_hash=2ce482b1c8407332b3b74f4c3e5596f373f9a657)
+
+- [基础](./00_basic.md)
+- [文字](./01_literal.md)
+- [名称](02_name.md)
+- [声明](./03_declaration.md)
+- [函数](./04_function.md)
+- [内置函数](./05_builtin_funcs.md)
+- [操作员](./06_operator.md)
+- [副作用](./07_side_effect.md)
+- [程序](./08_procedure.md)
+- [内置程序](./09_builtin_procs.md)
+- [数组](./10_array.md)
+- [元组](./11_tuple.md)
+- [字典](./12_dict.md)
+- [记录](./13_record.md)
+- [设置](./14_set.md)
+- [类型](./15_type.md)
+ - [类型系统](./type/01_type_system.md)
+ - [基础](./type/02_basic.md)
+ - [特质](./type/03_trait.md)
+ - [类](./type/04_class.md)
+ - [继承](./type/05_inheritance.md)
+ - [NST 与 SST](./type/06_nst_vs_sst.md)
+ - [补丁](./type/07_patch.md)
+ - [值类型](./type/08_value.md)
+ - [属性类型](./type/09_attributive.md)
+ - [间隔类型](./type/10_interval.md)
+ - [枚举类型](./type/11_enum.md)
+ - [细化类型](./type/12_refinement.md)
+ - [代数类型](./type/13_algebraic.md)
+ - [依赖类型](./type/14_dependent.md)
+ - [量化类型](./type/15_quantified.md)
+ - [子类型](./type/16_subtyping.md)
+ - [类型转换](./type/17_type_casting.md)
+ - [可变类型](./type/18_mut.md)
+ - [高级](./type/advanced.md)
+ - [默认参数](./type/advanced/default_param.md)
+ - [类型擦除](./type/advanced/erasure.md)
+ - [存在](./type/advanced/existential.md)
+ - [GADTs](./type/advanced/GADTs.md)
+ - [关键字参数](./type/advanced/keyword_param.md)
+ - [种类](./type/advanced/kind.md)
+ - [标记特征](./type/advanced/marker_trait.md)
+ - [可变结构](./type/advanced/mut_struct.md)
+ - [幻象类型](./type/advanced/phantom.md)
+ - [投影类型](./type/advanced/projection.md)
+ - [量化依赖类型](./type/advanced/quantified_dependent.md)
+ - [共享](./type/advanced/shared.md)
+- [迭代器](./16_iterator.md)
+- [可变性](./17_mutability.md)
+- [所有权](./18_ownership.md)
+- [可见性](./19_visibility.md)
+- [命名规则](20_naming_rule.md)
+- [Lambda](./21_lambda.md)
+- [子程序](./22_subroutine.md)
+- [关闭](./23_closure.md)
+- [模块](./24_module.md)
+- [对象系统](./25_object_system.md)
+- [模式匹配](./26_pattern_matching.md)
+- [理解](./27_comprehension.md)
+- [扩展语法](./28_spread_syntax.md)
+- [装饰器](./29_decorator.md)
+- [错误处理](./30_error_handling.md)
+- [管道](./31_pipeline.md)
+- [与 Python 集成](./32_integration_with_python.md)
+- [包系统](./33_package_system.md)
+- [发电机](./34_generator.md)
+- [索引](./indexes.md)
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/container_ownership.md b/doc/zh_CN/syntax/container_ownership.md
new file mode 100644
index 00000000..2e786beb
--- /dev/null
+++ b/doc/zh_CN/syntax/container_ownership.md
@@ -0,0 +1,44 @@
+# 下标(索引访问)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/container_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`[]` 不同于普通的方法。
+
+```python
+a = [!1, !2]
+a[0].inc!()
+assert a == [2, 2]
+```
+
+回想一下,子例程的返回值不能是引用。
+这里的 `a[0]` 的类型显然应该是 `Ref!(Int!)`(`a[0]` 的类型取决于上下文)。
+所以 `[]` 实际上是特殊语法的一部分,就像 `.` 一样。 与 Python 不同,它不能被重载。
+也无法在方法中重现 `[]` 的行为。
+
+```python
+C = Class {i = Int!}
+C. get(ref self) =
+ self::i # 类型错误:`self::i` 是 `Int!`(需要所有权)但 `get` 不拥有 `self`
+C.steal(self) =
+ self::i
+#NG
+C.new({i = 1}).steal().inc!() # 所有权警告:`C.new({i = 1}).steal()` 不属于任何人
+# 提示:分配给变量或使用 `uwn_do!`
+# OK (分配)
+c = C.new({i = 1})
+i = c.steal()
+i.inc!()
+assert i == 2
+# or (own_do!)
+own_do! C.new({i = 1}).steal(), i => i.inc!()
+```
+
+此外,`[]` 可以不承认,但元素不会移动
+
+```python
+a = [!1, !2]
+i = a[0]
+i.inc!()
+assert a[1] == 2
+a[0] # 所有权错误:`a[0]` 被移动到 `i`
+```
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/grammar.md b/doc/zh_CN/syntax/grammar.md
new file mode 100644
index 00000000..8e4e8a06
--- /dev/null
+++ b/doc/zh_CN/syntax/grammar.md
@@ -0,0 +1,90 @@
+# Erg 的语法(版本 0.1.0, 临时)
+```
+special_op ::= '=' | '->' | '=>' | '.' | ',' | ':' | '::' | '|>' | '&'
+separator ::= ';' | '\n'
+escape ::= '\'
+comment_marker ::= '#'
+reserved_symbol ::= special_op | separator | comment_marker
+number ::= [0-9]
+first_last_dight ::= number
+dight ::= number | '_'
+bin_dight ::= [0-1]
+oct_dight ::= [0-8]
+hex_dight ::= [0-9]
+ | [a-f]
+ | [A-F]
+int ::= first_last_dight
+ | first_last_dight dight* first_last_dight
+ | '0' ('b' | 'B') binary_dight+
+ | '0' ('o' | 'O') octa_dight+
+ | '0' ('x' | 'X') hex_dight+
+ratio ::= '.' dight* first_last_dight
+ | first_last_dight dight* '.' dight* first_last_dight
+bool ::= 'True' | 'False'
+none ::= 'None'
+ellipsis ::= 'Ellipsis'
+not_implemented ::= 'NotImplemented'
+parenthesis ::= '(' | ')'
+bracket ::= '{' | '}'
+square_bracket ::= '[' | ']'
+enclosure ::= parenthesis | bracket | square_bracket
+infix_op ::= '+' | '-' | '*' | '/' | '//' | '**'
+ | '%' | '&&' | '||' | '^^' | '<' | '<=' | '>' | '>='
+ | 'and' | 'or' | 'is' | 'as' | 'isnot' | 'in' | 'notin' | 'dot' | 'cross'
+prefix_op ::= '+' | '-' | '*' | '**' | '..' | '..<' | '~' | '&' | '!'
+postfix_op ::= '?' | '..' | '<..'
+operator ::= infix_op | prefix_op | postfix_op
+char ::= /* ... */
+str ::= '\"' char* '\"
+symbol_head ::= /* char except dight */
+symbol ::= symbol_head /* char except (reserved_symbol | operator | escape | ' ') */
+subscript ::= accessor '[' expr ']'
+attr ::= accessor '.' symbol
+accessor ::= symbol | attr | subscript
+literal ::= int | ratio | str | bool | none | ellipsis | not_implemented
+pos_arg ::= expr
+kw_arg ::= symbol ':' expr
+arg ::= pos_arg | kw_arg
+enc_args ::= pos_arg (',' pos_arg)* ','?
+args ::= '()' | '(' arg (',' arg)* ','? ')' | arg (',' arg)*
+var_pattern ::= accessor | `...` accessor | '[' single_patterns ']'
+var_decl_opt_t = var_pattern (':' type)?
+var_decl = var_pattern ':' type
+param_pattern ::= symbol | `...` symbol | literal | '[' param_patterns ']'
+param_decl_opt_t = param_pattern (':' type)?
+param_decl = param_pattern ':' type
+params_opt_t ::= '()' (':' type)?
+ | '(' param_decl_opt_t (',' param_decl_opt_t)* ','? ')' (':' type)?
+ | param_decl_opt_t (',' param_decl_opt_t)*
+params ::= '()' ':' type
+ | '(' param_decl (',' param_decl)* ','? ')' ':' type
+subr_decl ::= accessor params
+subr_decl_opt_t ::= accessor params_opt_t
+decl ::= var_decl | subr_decl
+decl_opt_t = var_decl_opt_t | subr_decl_opt_t
+body ::= expr | indent line+ dedent
+def ::= ('@' decorator '\n')* decl_opt_t '=' body
+call ::= accessor args | accessor call
+decorator ::= call
+lambda_func ::= params_opt_t '->' body
+lambda_proc ::= params_opt_t '=>' body
+lambda ::= lambda_func | lambda_proc
+normal_array ::= '[' enc_args ']'
+array_comprehension ::= '[' expr | (generator)+ ']'
+array ::= normal_array | array_comprehension
+record ::= '{' '=' '}'
+ | '{' def (';' def)* ';'? '}'
+set ::= '{' '}'
+ | '{' expr (',' expr)* ','? '}'
+dict ::= '{' ':' '}'
+ | '{' expr ':' expr (',' expr ':' expr)* ','? '}'
+tuple ::= '(' ')'
+ | '(' expr (',' expr)* ','? ')'
+indent ::= /* ... */
+expr ::= accessor | literal
+ | prefix | infix | postfix
+ | array | record | set | dict | tuple
+ | call | def | lambda
+line ::= expr separator+
+program ::= expr? | (line | comment)*
+```
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/indexes.md b/doc/zh_CN/syntax/indexes.md
new file mode 100644
index 00000000..100d1c15
--- /dev/null
+++ b/doc/zh_CN/syntax/indexes.md
@@ -0,0 +1,178 @@
+# 指数
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/indexes.md&commit_hash=438bcb89ea692f219b30f3a3ba107888b23eae98)
+
+有关不在此索引中的 API,请参阅 [此处](../API/index.md)。
+有关术语,请参见 [此处](../dev_guide/terms.md)。
+
+## 符号
+
+* !
+ * !-type → [可变性](./type/mut.md)
+* [#](./00_basic.md/#comment)
+* $
+* %
+* &
+ * &&
+* ′ (single quote)
+* ()
+* *
+ * [*-less multiplication](./01_literal.md/#less-multiplication)
+* + (前置)
+ * +_ → + (前置)
+* + (中置)
+* ,
+* − (前置)
+ * −_ → − (前置)
+* − (中置)
+ * −>
+* . → [可见性]
+* /
+* :
+ * :: → [可见性]
+* ;
+* <
+ * <:
+ * <<
+ * <=
+* =
+ * ==
+ * =>
+* >
+ * >>
+ * >=
+* ?
+* @
+* []
+* \
+* ^
+ * ^^
+* _
+ * _+_ → + (infix)
+ * _-_ → − (infix)
+*``
+* {}
+ * {} type
+* {:}
+* {=}
+ * {=} type
+* |
+ * ||
+* ~
+
+## 字母
+
+### A
+
+* algebraic type
+* And
+* and
+* assert
+* attribute
+
+### B
+
+* Base
+* Bool
+
+### C
+
+* Class
+
+### D
+
+* Deprecated
+* distinct
+
+### E
+
+* enum type
+* Eq
+* Erg
+
+### F
+
+* for
+
+### G
+
+### H
+
+### I
+
+* if
+* import
+* in
+* Int
+
+### J
+
+### K
+
+### L
+
+* let-polymorphism → [rank 1 polymorphism]
+* log
+
+### M
+
+* match
+
+### N
+
+* Nat
+* Never
+* None
+* None
+* Not
+* not
+
+### O
+
+* Option
+* Or
+* or
+* Ord
+
+### P
+
+* panic
+* [print!](./../API/procs.md#print)
+* Python
+
+### Q
+
+### R
+
+* ref
+* ref!
+* Result
+* rootobj
+
+### S
+
+* self
+* [Self](./type/special.md)
+* [side-effect](./07_side_effect.md)
+* Str
+
+### T
+
+* Traits
+* True
+* Type
+* type
+
+### U
+
+### V
+
+### W
+
+* while!
+
+### X
+
+### Y
+
+### Z
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/quick_tour.md b/doc/zh_CN/syntax/quick_tour.md
new file mode 100644
index 00000000..10124e7b
--- /dev/null
+++ b/doc/zh_CN/syntax/quick_tour.md
@@ -0,0 +1,269 @@
+# 快速浏览
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/quick_tour.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`syntax` 下面的文档是为了让编程初学者也能理解而编写的。
+对于已经掌握 Python、Rust、Haskell 等语言的人来说,可能有点啰嗦。
+
+所以,这里是 Erg 语法的概述。
+请认为未提及的部分与 Python 相同。
+
+## 变量,常量
+
+变量用 `=` 定义。 与 Haskell 一样,变量一旦定义就不能更改。 但是,它可以在另一个范围内被遮蔽。
+
+```python
+i = 0
+if True:
+ i = 1
+assert i == 0
+```
+
+任何以大写字母开头的都是常数。 只有可以在编译时计算的东西才能是常量。
+此外,自定义以来,常量在所有范围内都是相同的。
+
+```python
+PI = 3.141592653589793
+match random.random!(0..10):
+ PIs:
+ log "You get PI, it's a miracle!"
+```
+
+## 类型声明
+
+与 Python 不同的是,只能先声明变量类型。
+当然,声明的类型和实际分配的对象的类型必须兼容。
+
+```python
+i: Int
+i = 10
+```
+
+## 函数
+
+你可以像在 Haskell 中一样定义它。
+
+```python
+fib0 = 0
+fib1 = 1
+fibn = fib(n - 1) + fib(n - 2)
+```
+
+匿名函数可以这样定义:
+
+```python
+i -> i + 1
+assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4]
+```
+
+## 运算符
+
+特定于 Erg 的运算符是:
+
+### 变异运算符 (!)
+
+这就像 Ocaml 中的`ref`。
+
+```python
+i = !0
+i.update! x -> x + 1
+assert i == 1
+```
+
+## 程序
+
+具有副作用的子例程称为过程,并标有`!`。
+
+```python
+print! 1 # 1
+```
+
+## 泛型函数(多相关)
+
+```python
+id|T|(x: T): T = x
+id(1): Int
+id("a"): Str
+```
+
+## 记录
+
+您可以使用类似 ML 的语言中的记录等价物(或 JS 中的对象字面量)。
+
+```python
+p = {x = 1; y = 2}
+```
+
+## 所有权
+
+Ergs 由可变对象(使用 `!` 运算符突变的对象)拥有,并且不能从多个位置重写。
+
+```python
+i = !0
+j = i
+assert j == 0
+i#移动错误
+```
+
+另一方面,不可变对象可以从多个位置引用。
+
+## 可见性
+
+使用 `.` 前缀变量使其成为公共变量并允许从外部模块引用它。
+
+```python
+# foo.er
+.x = 1
+y = 1
+```
+
+```python
+foo = import "foo"
+assert foo.x == 1
+foo.y # 可见性错误
+```
+
+## 模式匹配
+
+### 变量模式
+
+```python
+# 基本任务
+i = 1
+# with 类型
+i: Int = 1
+# 函数
+fn x = x + 1
+fn: Int -> Int = x -> x + 1
+```
+
+### 文字模式
+
+```python
+# 如果 `i` 在编译时无法确定为 1,则发生 类型错误
+# 简写:`_ {1} = i`
+1 = i
+# 简单的模式匹配
+match x:
+ 1 -> "1"
+ 2 -> "2"
+ _ -> "other"
+# 斐波那契函数
+fib0 = 0
+fib1 = 1
+fibn: Nat = fibn-1 + fibn-2
+```
+
+### 常量模式
+
+```python
+PI = 3.141592653589793
+E = 2.718281828459045
+num = PI
+name = match num:
+ PI -> "pi"
+ E -> "e"
+ _ -> "unnamed"
+```
+
+### 丢弃(通配符)模式
+
+```python
+_ = 1
+_: Int = 1
+right(_, r) = r
+```
+
+### 可变长度模式
+
+与稍后描述的元组/数组/记录模式结合使用。
+
+```python
+[i,...j] = [1, 2, 3, 4]
+assert j == [2, 3, 4]
+first|T|(fst: T, ...rest: T) = fst
+assert first(1, 2, 3) == 1
+```
+
+### 元组模式
+
+```python
+(i, j) = (1, 2)
+((k, l), _) = ((1, 2), (3, 4))
+# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2))
+m, n = 1, 2
+```
+
+### 数组模式
+
+```python
+length[] = 0
+length[_, ...rest] = 1 + lengthrest
+```
+
+#### 记录模式
+
+```python
+{sin; cos; tan; ...} = import "math"
+{*} = import "math" # 全部导入
+
+person = {name = "John Smith"; age = 20}
+age = match person:
+ {name = "Alice"; _} -> 7
+ {_; age} -> age
+```
+
+### 数据类模式
+
+```python
+Point = Inherit {x = Int; y = Int}
+p = Point::{x = 1; y = 2}
+Point::{x; y} = p
+```
+
+## 理解(Comprehensions)
+
+```python
+odds = [i | i <- 1..100; i % 2 == 0]
+```
+
+## 班级
+
+Erg 不支持多级/多级继承。
+
+## 特质
+
+它们类似于 Rust 特征,但在更字面意义上,允许组合和解耦,并将属性和方法视为平等。
+此外,它不涉及实施。
+
+```python
+XY = Trait {x = Int; y = Int}
+Z = Trait {z = Int}
+XYZ = XY and Z
+Show = Trait {show: Self.() -> Str}
+
+@Impl XYZ, Show
+Point = Class {x = Int; y = Int; z = Int}
+Point.
+ ...
+```
+
+## 修补
+
+您可以为类和特征提供实现。
+
+## 筛子类型
+
+谓词表达式可以是类型限制的。
+
+```python
+Nat = {I: Int | I >= 0}
+```
+
+## 带值的参数类型(依赖类型)
+
+```python
+a: [Int; 3]
+b: [Int; 4]
+a + b: [Int; 7]
+```
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/01_type_system.md b/doc/zh_CN/syntax/type/01_type_system.md
new file mode 100644
index 00000000..79d58268
--- /dev/null
+++ b/doc/zh_CN/syntax/type/01_type_system.md
@@ -0,0 +1,230 @@
+# Erg 的类型系统
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/01_type_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+下面简单介绍一下 Erg 的类型系统。 详细信息在其他部分进行说明。
+
+## 如何定义
+
+Erg 的独特功能之一是(普通)变量、函数(子例程)和类型(Kind)定义之间的语法没有太大区别。 所有都是根据普通变量和函数定义的语法定义的。
+
+```python
+f i: Int = i + 1
+f # <函数 f>
+f(1) # 2
+f.method self = ... # 语法错误:无法为子例程定义方法
+
+T I: Int = {...}
+T #
+T(1) # 类型 T(1)
+T.method self = ...
+D = Class {private = Int; .public = Int}
+D # <类 'D'>
+o1 = {private = 1; .public = 2} # o1 是一个不属于任何类的对象
+o2 = D.new {private = 1; .public = 2} # o2 是 D 的一个实例
+o2 = D.new {.public = 2} # 初始化错误:类 'D' 需要属性 'private'(: Int) 但未定义
+```
+
+## Classification
+
+Erg 中的所有对象都是强类型的。
+顶层类型是`{=}`,实现了`__repr__`、`__hash__`、`clone`等(不是必须的方法,这些属性不能被覆盖)。
+Erg 的类型系统包含结构子类型 (SST)。 该系统类型化的类型称为结构类型。
+结构类型主要分为三种:Attributive(属性类型)、Refinement(细化类型)和Algebraic(代数类型)。
+
+| | Record | Enum | Interval | Union | Intersection | Diff |
+| --------- | ----------- | ---------- | -------------- | ----------- | ------------ | ------------ |
+| kind | Attributive | Refinement | Refinement | Algebraic | Algebraic | Algebraic |
+| generator | record | set | range operator | or operator | and operator | not operator |
+
+也可以使用名义子类型(NST),将 SST 类型转换为 NST 类型称为类型的名义化。 结果类型称为名义类型。
+在 Erg 中,名义类型是类和特征。 当我们简单地说类/特征时,我们通常指的是记录类/特征。
+
+| | Type | Abstraction | Subtyping procedure |
+| --- | -------------- | ---------------- | ------------------- |
+| NST | NominalType | Trait | Inheritance |
+| SST | StructuralType | Structural Trait | (Implicit) |
+
+整个名义类型的类型(`NominalType`)和整个结构类型的类型(`StructuralType`)是整个类型(`Type`)的类型的子类型。
+
+Erg 可以将参数(类型参数)传递给类型定义。带有类型参数的 `Option`、`Array` 等称为多项式类型。这些本身不是类型,但它们通过应用参数成为类型。诸如 `Int`、`Str` 等没有参数的类型称为简单类型(标量类型)。
+
+一个类型可以看成一个集合,并且存在包含关系。例如,“Num”包含“Add”、“Sub”等,“Int”包含“Nat”。
+所有类的上类是`Object == Class {:}`,所有类型的下类是`Never == Class {}`。这在下面描述。
+
+## 类型
+
+像 `Array T` 这样的类型可以看作是 `Type -> Type` 类型的函数,它以 `T` 类型为参数并返回 `Array T` 类型(在类型论中也称为 Kind)。像 `Array T` 这样的类型专门称为多态类型,而 `Array` 本身称为一元 Kind。
+
+已知参数和返回类型的函数的类型表示为`(T, U) -> V`。如果要指定同一类型的整个双参数函数,可以使用 `|T| (T, T) -> T`,如果要指定整个 N 参数函数,可以使用 `Func N`。但是,`Func N` 类型没有关于参数数量或其类型的信息,因此所有返回值在调用时都是`Obj` 类型。
+
+`Proc` 类型表示为 `() => Int` 等等。此外,`Proc` 类型实例的名称必须以 `!` 结尾。
+
+`Method` 类型是一个函数/过程,其第一个参数是它所属的对象 `self`(通过引用)。对于依赖类型,也可以在应用方法后指定自己的类型。这是 `T!(!N)` 类型和 `T!(N ~> N-1)。 () => Int` 等等。
+
+Erg 的数组(Array)就是 Python 所说的列表。 `[诠释; 3]`是一个数组类,包含三个`Int`类型的对象。
+
+> __Note__: `(Type; N)` 既是类型又是值,所以可以这样使用。
+>
+> ```python.
+> Types = (Int, Str, Bool)
+>
+> for! Types, T =>
+> print! T
+> # Int Str Bool
+> a: Types = (1, "aaa", True)
+> ```
+
+```python
+pop|T, N|(l: [T; N]): ([T; N-1], T) =
+ [...l, last] = l
+ (l, last)
+
+lpop|T, N|(l: [T; N]): (T, [T; N-1]) =
+ [first, ...l] = l
+ (first, l)
+```
+
+以 `!` 结尾的类型可以重写内部结构。 例如,`[T; !N]` 类是一个动态数组。
+要从“T”类型的对象创建“T!”类型的对象,请使用一元运算符“!”。
+
+```python
+i: Int! = !1
+i.update! i -> i + 1
+assert i == 2
+arr = [1, 2, 3]
+arr.push! 4 # 导入错误
+mut_arr = [1, 2, 3].into [Int; !3]
+mut_arr.push4
+assert mut_arr == [1, 2, 3, 4].
+```
+
+## 类型定义
+
+类型定义如下。
+
+```python
+Point2D = {.x = Int; .y = Int}
+```
+
+请注意,如果从变量中省略 `.`,它将成为类型中使用的私有变量。 但是,这也是必需的属性。
+由于类型也是对象,因此类型本身也有属性。 这样的属性称为类型属性。 在类的情况下,它们也称为类属性。
+
+## 数据类型
+
+如前所述,Erg 中的“类型”大致表示一组对象。
+
+下面是 `Add` 类型的定义,需要 `+`(中间运算符)。 `R, O` 是所谓的类型参数,可以是真正的类型(类),例如 `Int` 或 `Str`。 在其他语言中,类型参数被赋予特殊的符号(泛型、模板等),但在 Erg 中,它们可以像普通参数一样定义。
+类型参数也可以用于类型对象以外的类型。 例如数组类型`[Int; 3]` 是 `Array Int, 3` 的语法糖。 如果类型实现重叠,用户必须明确选择一个。
+
+```python
+Add R = Trait {
+ .AddO = Type
+ . `_+_` = Self.(R) -> Self.AddO
+}
+```
+
+.`_+_`是Add.`_+_`的缩写。 前缀运算符 .`+_` 是 `Num` 类型的方法。
+
+```python
+Num = Add and Sub and Mul and Eq
+NumImpl = Patch Num
+NumImpl.
+ `+_`(self): Self = self
+ ...
+```
+
+多态类型可以像函数一样对待。 通过将它们指定为 `Mul Int、Str` 等,它们可以是单态的(在许多情况下,它们是用实际参数推断出来的,而没有指定它们)。
+
+```python
+1 + 1
+`_+_` 1, 1
+Nat.`_+_` 1, 1
+Int.`_+_` 1, 1
+```
+
+前四行返回相同的结果(准确地说,底部的返回 `Int`),但通常使用顶部的。
+`Ratio.`_+_`(1, 1)` 将返回 `2.0` 而不会出错。
+这是因为 `Int <: Ratio`,所以 `1` 向下转换为 `Ratio`。
+但这不是演员。
+
+```python
+i = 1
+if i: # 类型错误:i:Int 不能转换为 Bool,请改用 Int.is_zero()。
+ log "a"
+ log "b"
+```
+
+这是因为 `Bool <: Int` (`True == 1`, `False == 0`)。转换为子类型通常需要验证。
+
+## 类型推理系统
+
+Erg 使用静态鸭子类型,因此几乎不需要显式指定类型。
+
+```python
+f x, y = x + y
+```
+
+在上面的代码中,带有 `+` 的类型,即 `Add` 是自动推断的; Erg 首先推断出最小的类型。如果`f 0, 1`,它将推断`f x:{0},y:{1}`,如果`n:Nat; f n, 1`,它会推断`f x: Nat, y: {1}`。最小化之后,增加类型直到找到实现。在 `{0}, {1}` 的情况下,`Nat` 与 `Nat` 是单态的,因为 `Nat` 是具有 `+` 实现的最小类型。
+如果是 `{0}, {-1}`,它与 `Int` 是单态的,因为它不匹配 `Nat`。如果子类型和超类型之间没有关系,则首先尝试具有最低浓度(实例数)(或者在多态类型的情况下参数更少)的那个。
+`{0}` 和 `{1}` 是枚举类型,它们是部分类型,例如 `Int` 和 `Nat`。
+例如,可以为枚举类型指定名称和请求/实现方法。在有权访问该类型的命名空间中,满足请求的对象可以使用实现方法。
+
+```python
+Binary = Patch {0, 1}
+Binary.
+ # self 包含一个实例。 在此示例中,为 0 或 1。
+ # 如果你想重写self,你必须追加! 必须添加到类型名称和方法名称。
+ is_zero(self) = match self:
+ 0 -> True
+ 1 -> False # 你也可以使用 _ -> False
+ is_one(self) = not self.is_zero()
+ to_bool(self) = match self:
+ 0 -> False
+ 1 -> True
+```
+
+此后,代码“0.to_bool()”是可能的(尽管“0 as Bool == False”是内置定义的)。
+这是一个实际上可以重写 `self` 的类型的示例,如代码所示。
+
+```python
+Binary! = Patch {0, 1}!
+Binary!
+ switch! ref! self = match! self:
+ 0 => self = 1
+ 1 => self = 0
+
+b = !1
+b.switch!()
+print! b # => 0
+```
+
+## 结构类型(匿名类型)
+
+```python
+Binary = {0, 1}
+```
+
+上面代码中的 `Binary` 是一个类型,其元素是 `0` 和 `1`。 它也是 `Int` 类型的子类型,它同时具有 `0` 和 `1`。
+像 `{}` 这样的对象本身就是一种类型,可以在分配或不分配给上述变量的情况下使用。
+这样的类型称为结构类型。 当我们想强调它作为后者而不是类(命名类型)的用途时,它也被称为未命名类型。 `{0, 1}`这样的结构类型称为枚举类型,还有区间类型、记录类型等。
+
+### 类型标识
+
+无法指定以下内容。 例如,您不能指定 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int`。
+例如,`Int`和`Str`都是`Add`,但是`Int`和`Str`不能相加。
+
+```python
+add l: Add, r: Add =
+ l + r # 类型错误: `_+_` 没有实现: |T, U <: Add| (T, U) -> <失败>
+```
+
+此外,下面的类型 `A` 和 `B` 不被认为是同一类型。 但是,类型“O”被认为是匹配的
+
+```python
+... |R1; R2; O; A <: Add(R1, O); B <: Add(R2, O)|
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/type/02_basic.md b/doc/zh_CN/syntax/type/02_basic.md
new file mode 100644
index 00000000..e892dea7
--- /dev/null
+++ b/doc/zh_CN/syntax/type/02_basic.md
@@ -0,0 +1,163 @@
+# 类型的基本语法
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/02_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 类型规范
+
+在 Erg 中,可以在 `:` 之后指定变量的类型,如下所示。这可以与作业同时完成。
+
+```python
+i: Int # 将变量 i 声明为 Int 类型
+i: Int = 1
+j = 1 # 类型说明可以省略
+```
+
+您还可以指定普通表达式的类型。
+
+```python
+i = 1: Int
+f([1, "a"]: [Int or Str])
+```
+
+对于简单的变量赋值,大多数类型说明可以省略。
+在定义子例程和类型时,类型规范更有用。
+
+```python
+# 参数的类型规范
+f x, y: Array Int = ...
+T X, Y: Array Int = ...
+```
+
+请注意,在上述情况下,`x, y` 都是 `Array Int`。
+
+```python
+# 大写变量的值必须是常量表达式
+f X: Int = X
+```
+
+或者,如果你不需要关于类型参数的完整信息,你可以用 `_` 省略它
+
+```python
+g v: [T; _] = ...
+```
+
+但是请注意,类型规范中的 `_` 意味着 `Object`。
+
+```python
+f x: _, y: Int = x + y # 类型错误:Object 和 Int 之间没有实现 +
+```
+
+## 子类型规范
+
+除了 `:`(类型声明运算符),Erg 还允许您使用 `<:`(部分类型声明运算符)来指定类型之间的关系。
+`<:` 的左边只能指定一个类。 使用 `Subtypeof` 或类似的运算符来比较结构类型。
+
+这也经常在定义子例程或类型时使用,而不是简单地指定变量。
+
+```python
+# 参数的子类型规范
+f X <: T = ...
+
+# 所需属性的子类型规范(.Iterator 属性必须是 Iterator 类型的子类型)
+Iterable T = Trait {
+ .Iterator = {Iterator} # {Iterator} == {I: Type | I <: Iterator}
+ .iter = Self.() -> Self.Iterator T
+ ...
+}
+```
+
+也可以在定义类时使用子类型规范来静态检查该类是否是指定类型的子类型。
+
+```python
+# C 类是 Show 的子类型
+C = Class Object, Impl := Show
+C.show self = ... # 显示所需的属性。
+```
+
+您也可以仅在特定情况下指定子类型
+
+```python
+K T: Eq
+K Int <: Show and Eq
+K T = Class Object
+K(T).
+ `==` self, other = ...
+K(Int).
+ show self = ...
+```
+
+实现结构类型时建议使用子类型规范。
+这是因为,由于结构子类型的性质,拼写错误或类型规范错误在实现所需属性时不会导致错误
+
+```python
+C = Class Object
+C.shoe self = ... # Show 由于 Typo 没有实现(它被认为只是一种独特的方法)
+```
+
+## 属性定义
+
+只能在模块中为特征和类定义属性
+
+```python
+C = Class()
+C.pub_attr = "this is public"
+C::private_attr = "this is private"
+
+c = C.new()
+assert c.pub_attr == "this is public"
+```
+
+定义批处理定义的语法称为批处理定义,其中在 `C.` 或 `C::` 之后添加换行符,并且定义在缩进下方组合在一起
+
+```python
+C = Class()
+C.pub1 = ...
+C.pub2 = ...
+C::priv1 = ...
+C::priv2 = ...
+# 相当于
+C = Class()
+C.
+ pub1 = ...
+ C. pub2 = ...
+C::
+ priv1 = ...
+ priv2 = ...
+```
+
+## 别名
+
+类型可以有别名。 这允许缩短长类型,例如记录类型
+
+```python
+Id = Int
+Point3D = {x = Int; y = Int; z = Int}
+IorS = Int or Str
+Vector = Array Int
+```
+
+此外,当显示错误时,如果定义了复合类型(在上面的示例中,右侧类型不是第一个类型),编译器将为它们使用别名。
+
+但是,每个模块只允许一个相同类型的别名,多个别名将导致警告。
+这意味着应将具有不同用途的类型定义为单独的类型。
+目的还在于防止在已经具有别名的类型之上添加别名。
+
+```python
+Id = Int
+UserId = Int # 类型警告:重复别名:Id 和 UserId
+
+Ids = Array Id
+Ints = Array Int # 类型警告:重复别名:Isd 和 Ints
+
+IorS = Int or Str
+IorSorB = IorS or Bool
+IorSorB_ = Int or Str or Bool # 类型警告:重复别名:IorSorB 和 IorSorB_
+
+Point2D = {x = Int; y = Int}
+Point3D = {.... Point2D; z = Int}
+Point = {x = Int; y = Int; z = Int} # 类型警告:重复别名:Point3D 和 Point
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/type/03_trait.md b/doc/zh_CN/syntax/type/03_trait.md
new file mode 100644
index 00000000..98bfc4ac
--- /dev/null
+++ b/doc/zh_CN/syntax/type/03_trait.md
@@ -0,0 +1,189 @@
+# 特质
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/03_trait.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Trait 是一种名义类型,它将类型属性要求添加到记录类型。
+它类似于 Python 中的抽象基类 (ABC),但区别在于能够执行代数运算。
+
+```python
+Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int}
+```
+
+特质不区分属性和方法。
+
+注意,trait 只能声明,不能实现(实现是通过一个叫做 patching 的特性来实现的,后面会讨论)。
+可以通过指定部分类型来检查特征在类中的实现。
+
+```python
+Point2D <: Norm
+Point2D = Class {.x = Int; .y = Int}
+Point2D.norm self = self.x**2 + self.y**2
+```
+
+Error if the required attributes are not implemented.
+
+```python
+Point2D <: Norm # 类型错误:Point2D 不是 Norm 的子类型
+Point2D = Class {.x = Int; .y = Int}
+```
+
+特征与结构类型一样,可以应用组合、替换和消除等操作(例如“T 和 U”)。 由此产生的特征称为即时特征。
+
+```python
+T = Trait {.x = Int}
+U = Trait {.y = Int}
+V = Trait {.x = Int; y: Int}
+assert Structural(T and U) == Structural V
+assert Structural(V not U) == Structural T
+W = Trait {.x = Ratio}
+assert Structural(W) ! = Structural(T)
+assert Structural(W) == Structural(T.replace {.x = Ratio})
+```
+
+Trait 也是一种类型,因此可以用于普通类型规范
+
+```python
+points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)]
+assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25].
+```
+
+## 特征包含
+
+扩展运算符 `...` 允许您将包含某个特征的特征定义为超类型。 这称为特征的 __subsumption__。
+在下面的示例中,`BinAddSub` 包含 `BinAdd` 和 `BinSub`。
+这对应于类中的继承,但与继承不同的是,可以使用“和”组合多个基类型。 也允许被 `not` 部分排除的特征。
+
+```python
+Add R = Trait {
+ .AddO = Type
+ . `_+_` = Self.(R) -> Self.AddO
+}
+
+Sub R = Trait {
+ .SubO = Type
+ . `_-_` = Self.(R) -> Self.SubO
+}
+
+BinAddSub = Subsume Add(Self) and Sub(Self)
+```
+
+## 结构特征
+
+特征可以结构化
+
+```python
+SAdd = Structural Trait {
+ . `_+_` = Self.(Self) -> Self
+}
+# |A <: SAdd| 不能省略
+add|A <: SAdd| x, y: A = x.`_+_` y
+
+C = Class {i = Int}
+C.
+ new i = Self.__new__ {i;}
+ `_+_` self, other: Self = Self.new {i = self::i + other::i}
+
+assert add(C.new(1), C.new(2)) == C.new(3)
+```
+
+名义特征不能简单地通过实现请求方法来使用,而必须明确声明已实现。
+在以下示例中,`add`不能与`C`类型的参数一起使用,因为没有明确的实现声明。 它必须是`C = Class {i = Int}, Impl := Add`。
+
+```python
+Add = Trait {
+ .`_+_` = Self.(Self) -> Self
+}
+# |A <: 添加| 可以省略
+add|A <: Add| x, y: A = x.`_+_` y
+
+C = Class {i = Int}
+C.
+ new i = Self.__new__ {i;}
+ `_+_` self, other: Self = Self.new {i = self::i + other::i}
+
+add C.new(1), C.new(2) # 类型错误:C 不是 Add 的子类
+# 提示:继承或修补“添加”
+```
+
+不需要为此实现声明结构特征,但类型推断不起作用。 使用时需要指定类型。
+
+## 多态特征
+
+特征可以带参数。 这与多态类型相同。
+
+```python
+Mapper T: Type = Trait {
+ .mapIter = {Iterator}
+ .map = Self(T). (T -> U) -> Self.MapIter U
+}
+
+# ArrayIterator <: Mapper
+# ArrayIterator.MapIter == ArrayMapper
+# [1, 2, 3].iter(): ArrayIterator Int
+# [1, 2, 3].iter().map(x -> "{x}"): ArrayMapper Str
+assert [1, 2, 3].iter().map(x -> "{x}").collect(Array) == ["1", "2", "3"].
+```
+
+## Override特征
+
+派生特征可以Override基本特征的类型定义。
+在这种情况下,Override方法的类型必须是基方法类型的子类型。
+
+```python
+# `Self.(R) -> O` is a subtype of ``Self.(R) -> O or Panic
+Div R, O: Type = Trait {
+ . `/` = Self.(R) -> O or Panic
+}
+SafeDiv R, O = Subsume Div, {
+ @Override
+ . `/` = Self.(R) -> O
+}
+```
+
+## 在 API 中实现和解决重复的特征
+
+`Add`、`Sub` 和 `Mul` 的实际定义如下所示。
+
+```python
+Add R = Trait {
+ .Output = Type
+ . `_+_` = Self.(R) -> .Output
+}
+Sub R = Trait {
+ .Output = Type
+ . `_-_` = Self.(R) -> .Output
+}
+Mul R = Trait {
+ .Output = Type
+ . `*` = Self.(R) -> .Output
+}
+```
+
+`.Output` 重复。 如果要同时实现这些多个特征,请指定以下内容
+
+```python
+P = Class {.x = Int; .y = Int}
+# P|Self <: Add(P)|可简写为 P|<: Add(P)|
+P|Self <: Add(P)|.
+ Output = P
+ `_+_` self, other = P.new {.x = self.x + other.x; .y = self.y + other.y}
+P|Self <: Mul(Int)|.
+ Output = P
+ `*` self, other = P.new {.x = self.x * other; .y = self.y * other}
+```
+
+以这种方式实现的重复 API 在使用时几乎总是类型推断,但也可以通过使用 `||` 显式指定类型来解决。
+
+```python
+print! P.Output # 类型错误:不明确的类型
+print! P|<: Mul(Int)|.Output #
+```
+
+## 附录:与 Rust 特征的区别
+
+Erg 的特征忠实于 [Schärli 等人] (https://www.ptidej.net/courses/ift6251/fall06/presentations/061122/061122.doc.pdf) 提出的特征。
+为了允许代数运算,特征被设计为不能有方法实现目录,但可以在必要时进行修补。
+
+
+ 上一页 | 下一步
+
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/04_class.md b/doc/zh_CN/syntax/type/04_class.md
new file mode 100644
index 00000000..1dc74c05
--- /dev/null
+++ b/doc/zh_CN/syntax/type/04_class.md
@@ -0,0 +1,289 @@
+# Class
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/04_class.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Erg 中的类大致是一种可以创建自己的元素(实例)的类型。
+这是一个简单类的示例。
+
+```python
+Person = Class {.name = Str; .age = Nat}
+# 如果 `.new` 没有定义,那么 Erg 将创建 `Person.new = Person::__new__`
+Person.
+ new name, age = Self::__new__ {.name = name; .age = age}
+
+john = Person.new "John Smith", 25
+print! john #
+print! classof(john) # Person
+```
+
+赋予“Class”的类型(通常是记录类型)称为需求类型(在本例中为“{.name = Str; .age = Nat}”)。
+可以使用 `::__new__ { = ; 创建实例 ...}` 可以创建。
+`{.name = "约翰·史密斯"; .age = 25}` 只是一条记录,但它通过传递 `Person.new` 转换为 `Person` 实例。
+创建此类实例的子例程称为构造函数。
+在上面的类中,`.new` 方法被定义为可以省略字段名等。
+
+请注意,以下不带换行符的定义将导致语法错误。
+
+```python
+Person.new name, age = ... # 语法错误:不能直接在对象上定义属性
+```
+
+> __Warning__:这是最近添加的规范,后续文档中可能不会遵循。 如果你发现它,请报告它。
+
+## 实例和类属性
+
+在 Python 和其他语言中,实例属性通常在块侧定义如下,但请注意,这样的写法在 Erg 中具有不同的含义。
+
+```python
+# Python
+class Person:
+ name: str
+ age: int
+```
+
+```python
+# 在Erg中,这个符号意味着类属性的声明(不是实例属性)
+Person = Class()
+Person.
+ name: Str
+ age: Int
+```
+
+```python
+# 以上 Python 代码的 Erg 代码
+Person = Class {
+ .name = Str
+ .age = Nat
+}
+```
+
+元素属性(在记录中定义的属性)和类型属性(也称为实例/类属性,尤其是在类的情况下)是完全不同的东西。 类型属性是类型本身的属性。 当一个类型的元素本身没有所需的属性时,它指的是一个类型属性。 元素属性是元素直接拥有的唯一属性。
+为什么要进行这种区分? 如果所有属性都是元素属性,那么在创建对象时复制和初始化所有属性将是低效的。
+此外,以这种方式划分属性明确了诸如“该属性是共享的”和“该属性是分开持有的”之类的角色。
+
+下面的例子说明了这一点。 `species` 属性对所有实例都是通用的,因此将其用作类属性更自然。 但是,属性 `name` 应该是实例属性,因为每个实例都应该单独拥有它。
+
+```python
+Person = Class {name = Str}
+Person::
+ species = "human"
+Person.
+ describe() =
+ log "species: {species}"
+ greet self =
+ log "Hello, My name is {self::name}."
+
+Person.describe() # 类型:Person
+Person.greet() # 类型错误: 未绑定的方法 Person.greet 需要一个参数
+
+john = Person.new {name = "John"}
+john.describe() # 类型: human
+john.greet() # 你好,我是约翰
+
+alice = Person.new {name = "Alice"}
+alice.describe() # 类型: human
+alice.greet() # 你好,我是爱丽丝
+```
+
+顺便说一下,如果实例属性和类型属性具有相同的名称和相同的类型,则会发生编译错误。 这是为了避免混淆。
+
+```python
+C = Class {.i = Int}
+C.i = 1 # 属性错误:`.i` 已在实例字段中定义
+```
+
+## 类(Class), 类型(Type)
+
+请注意,`1` 的类和类型是不同的。
+只有一个类 `Int` 是 `1` 的生成器。 可以通过`classof(obj)`或`obj.__class__`获取对象所属的类。
+相比之下,`1`有无数种。 例如,`{1}, {0, 1}, 0..12, Nat, Int, Num`。
+但是,可以将最小类型定义为单一类型,在本例中为“{1}”。 可以通过`Typeof(obj)`获取对象所属的类型。 这是一个编译时函数。
+对象可以使用补丁方法以及类方法。
+Erg 不允许您添加类方法,但您可以使用 [patch](./07_patch.md) 来扩展类。
+
+您还可以从现有类([Inheritable](./../27_decorator.md/#inheritable) 类)继承。
+您可以使用 `Inherit` 创建一个继承类。 左侧的类型称为派生类,右侧的“继承”的参数类型称为基类(继承类)。
+
+```python
+MyStr = Inherit Str
+# other: 如果你设置 ``other: Str'',你可以使用 MyStr。
+MyStr.
+ `-` self, other: Str = self.replace other, ""
+
+abc = MyStr.new("abc")
+# 这里的比较是向上的
+assert abc - "b" == "ac"
+```
+
+与 Python 不同,默认情况下,定义的 Erg 类是 `final`(不可继承的)。
+要使类可继承,必须将 `Inheritable` 装饰器附加到该类。
+Str` 是可继承的类之一。
+
+```python
+MyStr = Inherit Str # OK
+MyStr2 = Inherit MyStr # NG
+
+@Inheritable
+InheritableMyStr = Inherit Str
+MyStr3 = Inherit InheritableMyStr # OK
+```
+
+`Inherit Object` 和 `Class()` 在实践中几乎是等价的。 一般使用后者。
+
+类具有与类型不同的等价检查机制。
+类型基于其结构进行等效性测试。
+
+```python
+Person = {.name = Str; .age = Nat}
+Human = {.name = Str; .age = Nat}
+
+assert Person == Human
+```
+
+class has no equivalence relation defined.
+
+```python
+Person = Class {.name = Str; .age = Nat}
+Human = Class {.name = Str; .age = Nat}
+
+Person == Human # 类型错误:无法比较类
+```
+
+## 与结构类型的区别
+
+我们说过类是一种可以生成自己的元素的类型,但这并不是严格的描述。 事实上,一个记录类型+补丁可以做同样的事情。
+
+```python
+Person = {.name = Str; .age = Nat}
+PersonImpl = Patch Person
+PersonImpl.
+ new name, age = {.name; .age}
+
+john = Person.new("John Smith", 25)
+```
+
+使用类有四个优点。
+第一个是构造函数经过有效性检查,第二个是它的性能更高,第三个是您可以使用符号子类型(NST),第四个是您可以继承和覆盖。
+
+我们之前看到记录类型 + 补丁也可以定义一个构造函数(某种意义上),但这当然不是一个合法的构造函数。 这当然不是一个合法的构造函数,因为它可以返回一个完全不相关的对象,即使它调用自己`.new`。 在类的情况下,`.new` 被静态检查以查看它是否生成满足要求的对象。
+
+~
+
+类的类型检查只是检查对象的`。 __class__` 对象的属性。 因此可以快速检查一个对象是否属于一个类型。
+
+~
+
+Erg 在课堂上启用 NST; NST 的优点包括健壮性。
+在编写大型程序时,经常会出现对象的结构巧合匹配的情况。
+
+```python
+Dog = {.name = Str; .age = Nat}
+DogImpl = Patch Dog
+DogImpl.
+ bark = log "Yelp!"
+...
+Person = {.name = Str; .age = Nat}
+PersonImpl = Patch Person
+PersonImpl.
+ greet self = log "Hello, my name is {self.name}."
+
+john = {.name = "John Smith"; .age = 20}
+john.bark() # "Yelp!"
+```
+
+`Dog` 和 `Person` 的结构完全一样,但让动物打招呼,让人类吠叫显然是无稽之谈。
+前者是不可能的,所以让它不适用更安全。 在这种情况下,最好使用类。
+
+```python
+Dog = Class {.name = Str; .age = Nat}
+Dog.bark = log "Yelp!"
+...
+Person = Class {.name = Str; .age = Nat}
+Person.greet self = log "Hello, my name is {self.name}."
+
+john = Person.new {.name = "John Smith"; .age = 20}
+john.bark() # 类型错误: `Person` 对象没有方法 `.bark`。
+```
+
+另一个特点是补丁添加的类型属性是虚拟的,实现类不作为实体保存。
+也就是说,`T.x`、`T.bar` 是可以通过与 `{i = Int}` 兼容的类型访问(编译时绑定)的对象,并且未在 `{i = Int}` 或 ` C`。
+相反,类属性由类本身持有。 因此,它们不能被不处于继承关系的类访问,即使它们具有相同的结构。
+
+```python
+C = Class {i = Int}
+C.
+ foo self = ...
+print! dir(C) # ["foo", ...].
+
+T = Patch {i = Int}
+T.
+ x = 1
+ bar self = ...
+print! dir(T) # ["bar", "x", ...].
+assert T.x == 1
+assert {i = 1}.x == 1
+print! T.bar # <函数 bar>
+{i = Int}.bar # 类型错误:Record({i = Int}) 没有方法 `.bar`。
+C.bar # 类型错误:C 没有方法 `.bar` 打印!
+print! {i = 1}.bar # <方法 bar>
+C.new({i = 1}).bar # <方法 bar>
+```
+
+## 与数据类的区别
+
+有两种类型的类:常规类,通过`Class`成为记录类,以及从记录类继承(`Inherit`)的数据类。
+数据类继承了记录类的功能,具有分解赋值、默认实现的`==`和`hash`等特性。另一方面,数据类有自己的等价关系和格式展示。
+另一方面,如果要定义自己的等价关系或格式显示,则应使用普通类。
+
+```python
+C = Class {i = Int}
+c = C.new {i = 1}
+d = C.new {i = 2}
+print! c #
+c == d # 类型错误:`==` 没有为 `C` 实现
+
+D = Inherit {i = Int}
+e = D.new {i = 1}
+f = D.new {i = 2}
+print! e # D{i = 1}
+assert e ! = f
+```
+
+## 枚举类
+
+为了便于定义“Or”类型的类,提供了一个“Enum”。
+
+```python
+X = Class()
+Y = Class()
+XorY = Enum X, Y
+```
+
+每种类型都可以通过`XorY.X`、`XorY.Y`来访问,构造函数可以通过`XorY.cons(X)`获得。
+`.cons` 是一个接受类并返回其构造函数的方法。
+
+```python
+x1 = XorY.new X.new()
+x2 = XorY.cons(X)()
+assert x1 == x2
+```
+
+## 类关系
+
+类是需求类型的子类型。 类中可以使用需求类型的方法(包括补丁方法)。
+
+```python
+T = Trait {.foo = Foo}
+C = Class(... , impl: T)
+C.
+ foo = foo
+ bar x = ...
+assert C < T
+assert C.foo == foo
+assert not T < C
+assert T.foo == Foo
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/type/05_inheritance.md b/doc/zh_CN/syntax/type/05_inheritance.md
new file mode 100644
index 00000000..92e2e712
--- /dev/null
+++ b/doc/zh_CN/syntax/type/05_inheritance.md
@@ -0,0 +1,255 @@
+# 继承
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/05_inheritance.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+继承允许您定义一个新类,为现有类添加功能或专业化。
+继承类似于包含在特征中。 继承的类成为原始类的子类型。
+
+```python
+NewInt = Inherit Int
+NewInt.
+ plus1 self = self + 1
+
+assert NewInt.new(1).plus1() == 2
+assert NewInt.new(1) + NewInt.new(1) == 2
+```
+
+如果你希望新定义的类是可继承的,你必须给它一个 `Inheritable` 装饰器。
+
+您可以指定一个可选参数 `additional` 以允许该类具有其他实例属性,但前提是该类是一个值类。 但是,如果类是值类,则不能添加实例属性。
+
+```python
+@Inheritable
+Person = Class {name = Str}
+Student = Inherit Person, additional: {id = Int}
+
+john = Person.new {name = "John"}
+alice = Student.new {name = "Alice", id = 123}
+
+MailAddress = Inherit Str, additional: {owner = Str} # 类型错误:实例变量不能添加到值类中
+```
+
+Erg 的特殊设计不允许继承“Never”类型。 Erg 的特殊设计不允许继承 `Never` 类型,因为 `Never` 是一个永远无法实例化的独特类。
+
+## 枚举类的继承
+
+[Or 类型](./13_algebraic.md) 也可以被继承。 在这种情况下,您可以通过指定可选参数 `Excluding` 来删除任何选项(可以使用 `or` 进行多项选择)。
+不能添加其他选项。 添加选项的类不是原始类的子类型。
+
+```python
+Number = Class Int or Float or Complex
+Number.abs(self): Float =
+ match self:
+ i: Int -> i.abs().into Float
+ f: Float -> f.abs()
+ c: Complex -> c.abs().into Float
+
+# c: 复杂不能出现在匹配选项中
+RealNumber = Inherit Number, Excluding: Complex
+```
+
+同样,也可以指定[细化类型](./12_refinement.md)。
+
+```python
+Months = Class 0..12
+MonthsNot31Days = Inherit Months, Excluding: {1, 3, 5, 7, 8, 10, 12}
+
+StrMoreThan3 = Class StrWithLen N | N >= 3
+StrMoreThan4 = Inherit StrMoreThan3, Excluding: StrWithLen N | N == 3
+```
+
+## 覆盖
+
+该类与补丁相同,可以将新方法添加到原始类型,但可以进一步“覆盖”该类。
+这种覆盖称为覆盖。要覆盖,必须满足三个条件。
+首先,覆盖必须有一个 `Override` 装饰器,因为默认情况下它会导致错误。
+另外,覆盖不能改变方法的类型。它必须是原始类型的子类型。
+如果你重写了一个被另一个方法引用的方法,你也必须重写所有被引用的方法。
+
+为什么这个条件是必要的?这是因为重写不仅会改变一种方法的行为,而且可能会影响另一种方法的行为。
+
+让我们从第一个条件开始。此条件是为了防止“意外覆盖”。
+换句话说,必须使用 `Override` 装饰器来防止派生类中新定义的方法的名称与基类的名称冲突。
+
+接下来,考虑第二个条件。这是为了类型一致性。由于派生类是基类的子类型,因此它的行为也必须与基类的行为兼容。
+
+最后,考虑第三个条件。这种情况是 Erg 独有的,在其他面向对象语言中并不常见,同样是为了安全。让我们看看如果不是这种情况会出现什么问题。
+
+```python
+# 反面示例
+@Inheritable
+Base! = Class {x = Int!}
+Base!
+ f! ref! self =
+ print! self::x
+ self.g!()
+ g! ref! self = self::x.update! x -> x + 1
+
+Inherited! = Inherit Base!
+Inherited!
+ @Override
+ g! ref! self = self.f!() # 无限递归警告:此代码陷入无限循环
+ # 覆盖错误:方法 `.g` 被 `.f` 引用但未被覆盖
+```
+
+在继承类 `Inherited!` 中,`.g!` 方法被重写以将处理转移到 `.f!`。 但是,基类中的 `.f!` 方法会将其处理转移到 `.g!`,从而导致无限循环。 `.f` 是 `Base!` 类中的一个没有问题的方法,但它被覆盖以一种意想不到的方式使用,并且被破坏了。
+
+Erg 已将此规则构建到规范中。
+
+```python
+# OK.
+@Inheritable
+Base! = Class {x = Int!}
+Base!
+ f! ref! self =
+ print! self::x
+ self.g!()
+ g! ref! self = self::x.update! x -> x + 1
+
+Inherited! = Inherit Base!
+Inherited!
+ @Override
+ f! ref! self =
+ print! self::x
+ self::x.update! x -> x + 1
+ @Override
+ g! ref! self = self.f!()
+```
+
+然而,这个规范并没有完全解决覆盖问题。 然而,这个规范并没有完全解决覆盖问题,因为编译器无法检测覆盖是否解决了问题。
+创建派生类的程序员有责任纠正覆盖的影响。 只要有可能,尝试定义一个别名方法。
+
+### 替换特征(或看起来像什么)
+
+尽管无法在继承时替换特征,但有一些示例似乎可以这样做。
+
+例如,`Int`,`Real` 的子类型(实现了 `Add()`),似乎重新实现了 `Add()`。
+
+```python
+Int = Class ... , Impl := Add() and ...
+```
+
+但实际上 `Real` 中的 `Add()` 代表 `Add(Real, Real)`,而在 `Int` 中它只是被 `Add(Int, Int)` 覆盖。
+它们是两个不同的特征(`Add` 是一个 [covariate](./advanced/variance.md),所以`Add(Real, Real) :> Add(Int, Int)`)。
+
+## 多重继承
+
+Erg 不允许普通类之间的交集、差异和互补。
+```python
+Int and Str # 类型错误:无法合并类
+```
+
+该规则防止从多个类继承,即多重继承。
+
+```python
+IntAndStr = Inherit Int and Str # 语法错误:不允许类的多重继承
+```
+
+但是,可以使用多个继承的 Python 类。
+
+## 多层(多级)继承
+
+Erg 继承也禁止多层继承。 也就是说,您不能定义从另一个类继承的类。
+从“Object”继承的可继承类可能会异常继承。
+
+同样在这种情况下,可以使用 Python 的多层继承类。
+
+## 重写继承的属性
+
+Erg 不允许重写从基类继承的属性。 这有两个含义。
+
+第一个是对继承的源类属性的更新操作。 例如,它不能重新分配,也不能通过 `.update!` 方法更新。
+
+覆盖与重写不同,因为它是一种用更专业的方法覆盖的操作。 覆盖也必须替换为兼容的类型。
+
+```python
+@Inheritable
+Base! = Class {.pub = !Int; pri = !Int}
+Base!
+ var = !1
+ inc_pub! ref! self = self.pub.update! p -> p + 1
+
+Inherited! = Inherit Base!
+Inherited!
+ var.update! v -> v + 1
+ # 类型错误:不能更新基类变量
+ @Override
+ inc_pub! ref! self = self.pub + 1
+ # 覆盖错误:`.inc_pub!` 必须是 `Self! 的子类型! () => ()`
+```
+
+第二个是对继承源的(变量)实例属性的更新操作。 这也是被禁止的。 基类的实例属性只能从基类提供的方法中更新。
+无论属性的可见性如何,都无法直接更新。 但是,它们可以被读取。
+
+```python
+@Inheritable
+Base! = Class {.pub = !Int; pri = !Int}
+Base!
+ inc_pub! ref! self = self.pub.update! p -> p + 1
+ inc_pri! ref! self = self::pri.update! p -> p + 1
+
+self = self.pub.update!
+Inherited!
+ # OK
+ add2_pub! ref! self =
+ self.inc_pub!()
+ self.inc_pub!()
+ # NG, `Child` 不能触摸 `self.pub` 和 `self::pri`。
+ add2_pub! ref! self =
+ self.pub.update! p -> p + 2
+```
+
+毕竟 Erg 继承只能添加新的属性和覆盖基类的方法。
+
+## 使用继承
+
+虽然继承在正确使用时是一项强大的功能,但它也有一个缺点,即它往往会使类依赖关系复杂化,尤其是在使用多层或多层继承时。复杂的依赖关系会降低代码的可维护性。
+Erg 禁止多重和多层继承的原因是为了降低这种风险,并且引入了类补丁功能以降低依赖关系的复杂性,同时保留继承的“添加功能”方面。
+
+那么,反过来说,应该在哪里使用继承呢?一个指标是何时需要“基类的语义子类型”。
+Erg 允许类型系统自动进行部分子类型确定(例如,Nat,其中 Int 大于或等于 0)。
+但是,例如,仅依靠 Erg 的类型系统很难创建“表示有效电子邮件地址的字符串类型”。您可能应该对普通字符串执行验证。然后,我们想为已通过验证的字符串对象添加某种“保证”。这相当于向下转换为继承的类。将 `Str object` 向下转换为 `ValidMailAddressStr` 与验证字符串是否采用正确的电子邮件地址格式是一一对应的。
+
+```python
+ValidMailAddressStr = Inherit Str
+ValidMailAddressStr.
+ init s: Str =
+ validate s # 邮件地址验证
+ Self.new s
+
+s1 = "invalid mail address"
+s2 = "foo@gmail.com"
+_ = ValidMailAddressStr.init s1 # 恐慌:无效的邮件地址
+valid = ValidMailAddressStr.init s2
+valid: ValidMailAddressStr # 确保电子邮件地址格式正确
+```
+
+另一个指标是您何时想要实现名义多态性。
+例如,下面定义的 `greet!` 过程将接受任何类型为 `Named` 的对象。
+但显然应用 `Dog` 类型的对象是错误的。 所以我们将使用 `Person` 类作为参数类型。
+这样,只有 `Person` 对象、从它们继承的类和 `Student` 对象将被接受为参数。
+这是比较保守的,避免不必要地承担过多的责任。
+
+```python
+Named = {name = Str; ...}
+Dog = Class {name = Str; breed = Str}
+Person = Class {name = Str}
+Student = Inherit Person, additional: {id = Int}
+structural_greet! person: Named =
+ print! "Hello, my name is {person::name}."
+greet! person: Person =
+ print! "Hello, my name is {person::name}."
+
+max = Dog.new {name = "Max", breed = "Labrador"}
+john = Person.new {name = "John"}
+alice = Student.new {name = "Alice", id = 123}
+
+structural_greet! max # 你好,我是马克斯
+structural_greet! john # 你好,我是约翰
+greet! alice # 你好,我是爱丽丝
+greet! max # 类型错误:
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/type/06_nst_vs_sst.md b/doc/zh_CN/syntax/type/06_nst_vs_sst.md
new file mode 100644
index 00000000..496ab445
--- /dev/null
+++ b/doc/zh_CN/syntax/type/06_nst_vs_sst.md
@@ -0,0 +1,45 @@
+# 名义子类型与结构子类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/06_nst_vs_sst.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+```python
+Months = 0..12
+
+# NST
+MonthsClass = Class Months
+MonthsClass.
+ name self =
+ match self:
+ 1 -> "january"
+ 2 -> "february"
+ 3 -> "march"
+ ...
+
+# SST
+MonthsImpl = Patch Months
+MonthsImpl.
+ name self =
+ match self:
+ 1 -> "January"
+ 2 -> "February"
+ 3 -> "March"
+ ...
+
+assert 12 in Months
+assert 2.name() == "February"
+assert not 12 in MonthsClass
+assert MonthsClass.new(12) in MonthsClass
+# 它可以使用结构类型,即使包装在一个类中。
+assert MonthsClass.new(12) in Months
+# 如果两者都存在,则类方法优先
+assert MonthsClass.new(2).name() == "february"
+```
+
+## 最后,我应该使用哪个,NST 还是 SST?
+
+如果您无法决定使用哪一个,我们的建议是 NST。
+SST 需要抽象技能来编写在任何用例中都不会崩溃的代码。 好的抽象可以带来高生产力,但错误的抽象(外观上的共性)会导致适得其反的结果。(NST 可以通过故意将抽象保持在最低限度来降低这种风险。如果您不是库实现者,那么仅使用 NST 进行编码并不是一个坏主意。
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/type/07_patch.md b/doc/zh_CN/syntax/type/07_patch.md
new file mode 100644
index 00000000..8116131b
--- /dev/null
+++ b/doc/zh_CN/syntax/type/07_patch.md
@@ -0,0 +1,224 @@
+# 修补
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/07_patch.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Erg 不允许修改现有类型和类。
+这意味着,不可能在类中定义额外的方法,也不能执行特化(一种语言特性,单态化多态声明的类型并定义专用方法,如在 C++ 中)。
+但是,在许多情况下,您可能希望向现有类型或类添加功能,并且有一个称为“修补”的功能允许您执行此操作。
+
+```python
+StrReverse = Patch Str
+StrReverse.
+ reverse self = self.iter().rev().collect(Str)
+
+assert "abc".reverse() == "cba"
+```
+
+补丁的名称应该是要添加的主要功能的简单描述。
+这样,被修补类型的对象(`Str`)可以使用修补程序的方法(`StrReverse`)。
+实际上,内置方法`.reverse`并不是`Str`的方法,而是`StrRReverse`中添加的方法。
+
+但是,补丁方法的优先级低于名义类型(类/特质)的方法,并且不能覆盖现有类型。
+
+```python
+StrangeInt = Patch Int
+StrangeInt.
+ `_+_` = Int.`_-_` # 赋值错误:. `_+_` 已在 Int 中定义
+```
+
+如果要覆盖,则必须从类继承。
+但是,基本上建议不要覆盖并定义具有不同名称的方法。
+由于一些安全限制,覆盖不是很容易做到。
+
+```python
+StrangeInt = Inherit Int
+StrangeInt.
+# 覆盖方法必须被赋予覆盖装饰器。
+ # 另外,你需要覆盖所有依赖于 Int.`_+_` 的 Int 方法。
+ @Override
+ `_+_` = Super.`_-_` # OverrideError: Int.`_+_` 被 ... ````` 引用,所以这些方法也必须被覆盖
+```
+
+## 选择修补程序
+
+可以为单一类型定义修复程序,并且可以组合在一起。
+
+```python
+# foo.er
+
+StrReverse = Patch(Str)
+StrReverse.
+ reverse self = ...
+StrMultiReplace = Patch(Str)
+StrMultiReverse.
+ multi_replace self, pattern_and_targets: [(Pattern, Str)] = ...
+StrToCamelCase = Patch(Str)
+StrToCamelCase.
+ to_camel_case self = ...
+StrToKebabCase = Patch(Str)
+StrToKebabCase.
+ to_kebab_case self = ...
+
+StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase
+StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase
+```
+
+```python
+{StrBoosterPack; ...} = import "foo"
+
+assert "abc".reverse() == "cba"
+assert "abc".multi_replace([("a", "A"), ("b", "B")]) == "ABc"
+assert "to camel case".to_camel_case() == "toCamelCase"
+assert "to kebab case".to_kebab_case() == "to-kebab-case"
+```
+
+如果定义了多个修复程序,其中一些可能会导致重复实施
+
+```python
+# foo.er
+
+StrReverse = Patch(Str)
+StrReverse.
+ reverse self = ...
+# 更高效的实现
+StrReverseMk2 = Patch(Str)
+StrReverseMk2.
+ reverse self = ...
+
+"hello".reverse() # 补丁选择错误: `.reverse` 的多个选择: StrReverse, StrReverseMk2
+```
+
+在这种情况下,您可以使用 __related function__ 形式而不是方法形式使其唯一
+
+```python
+assert StrReverseMk2.reverse("hello") == "olleh"
+```
+
+You can also make it unique by selectively importing.
+
+```python
+{StrReverseMk2; ...} = import "foo"
+
+assert "hello".reverse() == "olleh"
+```
+
+## 胶水补丁
+
+维修程序也可以将类型相互关联。 `StrReverse` 补丁涉及 `Str` 和 `Reverse`。
+这样的补丁称为 __glue patch__。
+因为 `Str` 是内置类型,所以用户需要使用胶水补丁来改造特征。
+
+```python
+Reverse = Trait {
+ .reverse = Self.() -> Self
+}
+
+StrReverse = Patch Str, Impl := Reverse
+StrReverse.
+ reverse self =
+ self.iter().rev().collect(Str)
+```
+
+每个类型/特征对只能定义一个胶水补丁。
+这是因为如果多个胶水修复程序同时“可见”,就不可能唯一确定选择哪个实现。
+但是,当移动到另一个范围(模块)时,您可以交换维修程序。
+
+```python
+NumericStr = Inherit Str
+NumericStr.
+ ...
+
+NumStrRev = Patch NumericStr, Impl := Reverse
+NumStrRev.
+ ...
+# 重复修补程序错误:数值Str已与“反向”关联`
+# 提示:'Str'(NumericStr'的超类)通过'StrReverse'与'Reverse'关联
+```
+
+## 附录:与 Rust 特征的关系
+
+Erg 修复程序相当于 Rust 的(改造的)`impl` 块。
+
+```rust
+// Rust
+trait Reverse {
+ fn reverse(self) -> Self;
+}
+
+impl Reverse for String {
+ fn reverse(self) -> Self {
+ self.chars().rev().collect()
+ }
+}
+```
+
+可以说,Rust 的特征是 Erg 的特征和修复程序的特征。 这使得 Rust 的特征听起来更方便,但事实并非如此。
+
+```python
+# Erg
+Reverse = Trait {
+ .reverse = Self.() -> Self
+}
+
+StrReverse = Patch(Str, Impl := Reverse)
+StrReverse.
+ reverse self =
+ self.iter().rev().collect(Str)
+```
+
+因为 impl 块在 Erg 中被对象化为补丁,所以在从其他模块导入时可以选择性地包含。 作为副作用,它还允许将外部特征实现到外部结构。
+此外,结构类型不再需要诸如 `dyn trait` 和 `impl trait` 之类的语法。
+
+```python
+# Erg
+reversible: [Reverse; 2] = [[1, 2, 3], "hello"]
+
+iter|T|(i: Iterable T): Iterator T = i.iter()
+```
+
+```rust
+// Rust
+let reversible: [Box; 2] = [Box::new([1, 2, 3]), Box::new("hello")];
+
+fn iter(i: I) -> impl Iterator- where I: IntoIterator {
+ i.into_iter()
+}
+```
+
+## 通用补丁
+
+补丁不仅可以为一种特定类型定义,还可以为“一般功能类型”等定义。
+在这种情况下,要给出自由度的项作为参数给出(在下面的情况下,`T:Type`)。 以这种方式定义的补丁称为全对称补丁。
+如您所见,全对称补丁正是一个返回补丁的函数,但它本身也可以被视为补丁。
+
+```python
+FnType T: Type = Patch(T -> T)
+FnType(T).
+ type = T
+
+assert (Int -> Int).type == Int
+```
+
+## 结构补丁
+
+此外,可以为满足特定结构的任何类型定义修复程序。
+但是,这比名义上的维修程序和类方法具有较低的优先级。
+
+在定义结构修复程序时应使用仔细的设计,因为某些属性会因扩展而丢失,例如以下内容。
+
+```python
+# 这不应该是 `Structural`
+Norm = Structural Patch {x = Int; y = Int}
+Norm.
+ norm self = self::x**2 + self::y**2
+
+Point2D = Class {x = Int; y = Int}
+assert Point2D.new({x = 1; y = 2}).norm() == 5
+
+Point3D = Class {x = Int; y = Int; z = Int}
+assert Point3D.new({x = 1; y = 2; z = 3}).norm() == 14 # AssertionError:
+```
+
+
+ 上一页 | 下一页
+
diff --git a/doc/zh_CN/syntax/type/08_value.md b/doc/zh_CN/syntax/type/08_value.md
new file mode 100644
index 00000000..fa3eef3f
--- /dev/null
+++ b/doc/zh_CN/syntax/type/08_value.md
@@ -0,0 +1,39 @@
+# 值类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/08_value.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+值类型是可以在编译时评估的 Erg 内置类型,具体来说:
+
+```python
+Value = (
+ Int
+ or Nat
+ or Ratio
+ or Float
+ or Complex
+ or Bool
+ or Str
+ or NoneType
+ or Array Const
+ or Tuple Const
+ or Set Const
+ or ConstFunc(Const, _)
+ or ConstProc(Const, _)
+ or ConstMethod(Const, _)
+)
+```
+
+应用于它们的值类型对象、常量和编译时子例程称为 __constant 表达式__。
+
+```python
+1, 1.0, 1+2im, True, None, "aaa", [1, 2, 3], Fib(12)
+```
+
+小心子程序。子例程可能是也可能不是值类型。
+由于子程序的实质只是一个指针,因此可以将其视为一个值[1 ](#1),但是在编译不是子程序的东西时不能使用 在恒定的上下文中。 不是值类型,因为它没有多大意义。
+
+将来可能会添加归类为值类型的类型。
+
+---
+
+1 Erg 中的术语“值类型”与其他语言中的定义不同。 纯 Erg 语义中没有内存的概念,并且因为它被放置在堆栈上而说它是值类型,或者因为它实际上是一个指针而说它不是值类型是不正确的。 值类型仅表示它是“值”类型或其子类型。 [↩](#f1)
diff --git a/doc/zh_CN/syntax/type/09_attributive.md b/doc/zh_CN/syntax/type/09_attributive.md
new file mode 100644
index 00000000..c56369ad
--- /dev/null
+++ b/doc/zh_CN/syntax/type/09_attributive.md
@@ -0,0 +1,11 @@
+# 属性类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/09_attributive.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
+属性类型是包含 Record 和 Dataclass、Patch、Module 等的类型。
+属于属性类型的类型不是值类型。
+
+## 记录类型复合
+
+可以展平复合的记录类型。
+例如,`{... {.name = Str; .age = Nat}; ... {.name = Str; .id = Nat}}` 变成 `{.name = Str; .age = 自然; .id = Nat}`。
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/10_interval.md b/doc/zh_CN/syntax/type/10_interval.md
new file mode 100644
index 00000000..3bbbb1b1
--- /dev/null
+++ b/doc/zh_CN/syntax/type/10_interval.md
@@ -0,0 +1,38 @@
+# 间隔类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/10_interval.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+`Range` 对象最基本的用途是作为迭代器。
+
+```python
+for! 0..9, i =>
+ print! i
+```
+
+请注意,与 Python 不同,它包含一个结束编号。
+
+然而,这不仅仅用于 `Range` 对象。 也可以使用类型。 这种类型称为Interval类型。
+
+```python
+i: 0..10 = 2
+```
+
+`Nat` 类型等价于 `0.. ExtraStatus,Status的元素可以使用ExtraStatus的方法
+Status = Trait {"Ok", "Error"}
+ # ...
+ExtraStatus = Trait {"Ok", "Error", "Unknown"}
+ # ...
+```
+
+方法也可以通过补丁添加。
+
+使用“或”运算符明确指示包含或向现有 Enum 类型添加选项。
+
+```python
+ExtraStatus = Status or {"Unknown"}
+```
+
+一个元素所属的所有类都相同的枚举类型称为同质枚举类型。
+
+默认情况下,可以将需求类型为同类枚举类型的类视为元素所属类的子类。
+
+如果您不想这样做,可以将其设为包装类
+
+```python
+Abc = Class {"A", "B", "C"}
+Abc.new("A").is_uppercase()
+
+OpaqueAbc = Class {inner = {"A", "B", "C"}}.
+ new inner: {"A", "B", "C"} = Self.new {inner;}
+OpaqueAbc.new("A").is_uppercase() # 类型错误
+```
diff --git a/doc/zh_CN/syntax/type/12_refinement.md b/doc/zh_CN/syntax/type/12_refinement.md
new file mode 100644
index 00000000..be86096f
--- /dev/null
+++ b/doc/zh_CN/syntax/type/12_refinement.md
@@ -0,0 +1,77 @@
+# 细化类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/12_refinement.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+细化类型是受谓词表达式约束的类型。 枚举类型和区间类型是细化类型的语法糖。
+
+细化类型的标准形式是`{Elem: Type | (预)*}`。 这意味着该类型是其元素为满足 `Pred` 的 `Elem` 的类型。
+可用于筛选类型的类型仅为 [Const type](./advanced/const.md)。
+
+```python
+Nat = 0.. _
+Odd = {N: Int | N % 2 == 1}
+Char = StrWithLen 1
+# StrWithLen 1 == {_: StrWithLen N | N == 1}
+[Int; 3] == {_: Array Int, N | N == 3}
+Array3OrMore == {A: Array _, N | N >= 3}
+```
+
+当有多个 pred 时,可以用 `;` 或 `and` 或 `or` 分隔。 `;` 和 `and` 的意思是一样的。
+
+`Odd` 的元素是 `1, 3, 5, 7, 9, ...`。
+它被称为细化类型,因为它的元素是现有类型的一部分,就好像它是细化一样。
+
+`Pred` 被称为(左侧)谓词表达式。 和赋值表达式一样,它不返回有意义的值,左侧只能放置一个模式。
+也就是说,诸如`X**2 - 5X + 6 == 0`之类的表达式不能用作细化类型的谓词表达式。 在这方面,它不同于右侧的谓词表达式。
+
+```python
+{X: Int | X**2 - 5X + 6 == 0} # 语法错误:谓词形式无效。 只有名字可以在左边
+```
+
+如果你知道如何解二次方程,你会期望上面的细化形式等价于`{2, 3}`。
+但是,Erg 编译器对代数的了解很少,因此无法解决右边的谓词。
+
+## 智能投射
+
+很高兴您定义了 `Odd`,但事实上,它看起来不能在文字之外使用太多。 要将普通 `Int` 对象中的奇数提升为 `Odd`,即将 `Int` 向下转换为 `Odd`,您需要传递 `Odd` 的构造函数。
+对于细化类型,普通构造函数 `.new` 可能会出现恐慌,并且有一个名为 `.try_new` 的辅助构造函数返回一个 `Result` 类型。
+
+```python
+i = Odd.new (0..10).sample!()
+i: Odd # or Panic
+```
+
+它也可以用作 `match` 中的类型说明。
+
+```python
+# i: 0..10
+i = (0..10).sample!
+match i:
+ o: Odd ->
+ log "i: Odd"
+ n: Nat -> # 0..10 < Nat
+ log "i: Nat"
+```
+
+但是,Erg 目前无法做出诸如“偶数”之类的子决策,因为它不是“奇数”等。
+
+## 枚举、区间和筛选类型
+
+前面介绍的枚举/区间类型是细化类型的语法糖。
+`{a, b, ...}` 是 `{I: Typeof(a) | I == a 或 I == b 或 ... }`,并且 `a..b` 被去糖化为 `{I: Typeof(a) | 我 >= a 和我 <= b}`。
+
+```python
+{1, 2} == {I: Int | I == 1 or I == 2}
+1..10 == {I: Int | I >= 1 and I <= 10}
+1... <10 == {I: Int | I >= 1 and I < 10}
+```
+
+## 细化模式
+
+正如 `_: {X}` 可以重写为 `X`(常量模式),`_: {X: T | Pred}` 可以重写为`X: T | Pred`
+
+```python
+# 方法 `.m` 是为长度为 3 或更大的数组定义的
+Array(T, N | N >= 3)
+ .m(&self) = ...
+```
diff --git a/doc/zh_CN/syntax/type/13_algebraic.md b/doc/zh_CN/syntax/type/13_algebraic.md
new file mode 100644
index 00000000..98156aa3
--- /dev/null
+++ b/doc/zh_CN/syntax/type/13_algebraic.md
@@ -0,0 +1,86 @@
+# 代数类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/13_algebraic.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e)
+
+代数类型是通过将类型视为代数来操作类型而生成的类型。
+它们处理的操作包括Union、Intersection、Diff、Complement等。
+普通类只能进行Union,其他操作会导致类型错误。
+
+## 联合(Union)
+
+联合类型可以为类型提供多种可能性。 顾名思义,它们是由“或”运算符生成的。
+一个典型的 Union 是 `Option` 类型。 `Option` 类型是 `T 或 NoneType` 补丁类型,主要表示可能失败的值。
+
+```python
+IntOrStr = Int or Str
+assert dict.get("some key") in (Int or NoneType)
+
+# 隐式变为 `T != NoneType`
+Option T = T or NoneType
+```
+
+## 路口
+
+交集类型是通过将类型与 `and` 操作组合得到的。
+
+```python
+Num = Add and Sub and Mul and Eq
+```
+
+如上所述,普通类不能与“and”操作结合使用。 这是因为实例只属于一个类。
+
+## 差异
+
+Diff 类型是通过 `not` 操作获得的。
+最好使用 `and not` 作为更接近英文文本的符号,但建议只使用 `not`,因为它更适合与 `and` 和 `or` 一起使用。
+
+```python
+CompleteNum = Add and Sub and Mul and Div and Eq and Ord
+Num = CompleteNum not Div not Ord
+
+True = Bool not {False}
+OneTwoThree = {1, 2, 3, 4, 5, 6} - {4, 5, 6, 7, 8, 9, 10}
+```
+
+## 补充
+
+补码类型是通过 `not` 操作得到的,这是一个一元操作。 `not T` 类型是 `{=} not T` 的简写。
+类型为“非 T”的交集等价于 Diff,类型为“非 T”的 Diff 等价于交集。
+但是,不推荐这种写法。
+
+```python
+# 非零数类型的最简单定义
+NonZero = Not {0}
+# 不推荐使用的样式
+{True} == Bool and not {False} # 1 == 2 + - 1
+Bool == {True} not not {False} # 2 == 1 - -1
+```
+
+## 真代数类型
+
+有两种代数类型:可以简化的表观代数类型和不能进一步简化的真实代数类型。
+“表观代数类型”包括 Enum、Interval 和 Record 类型的 `or` 和 `and`。
+这些不是真正的代数类型,因为它们被简化了,并且将它们用作类型说明符将导致警告; 要消除警告,您必须简化它们或定义它们的类型。
+
+```python
+assert {1, 2, 3} or {2, 3} == {1, 2, 3}
+assert {1, 2, 3} and {2, 3} == {2, 3}
+assert -2..-1 or 1..2 == {-2, -1, 1, 2}
+
+i: {1, 2} or {3, 4} = 1 # 类型警告:{1, 2} 或 {3, 4} 可以简化为 {1, 2, 3, 4}
+p: {x = Int, ...} and {y = Int; ...} = {x = 1; y = 2; z = 3}
+# 类型警告:{x = Int, ...} 和 {y = Int; ...} 可以简化为 {x = Int; y = 整数; ...}
+
+Point1D = {x = Int; ...}
+Point2D = Point1D and {y = Int; ...} # == {x = Int; y = Int; ...}
+q: Point2D = {x = 1; y = 2; z = 3}
+```
+
+真正的代数类型包括类型“或”和“与”。 类之间的“或”等类属于“或”类型。
+
+```python
+assert Int or Str == Or(Int, Str)
+assert Int and Marker == And(Int, Marker)
+```
+
+Diff, Complement 类型不是真正的代数类型,因为它们总是可以被简化。
diff --git a/doc/zh_CN/syntax/type/14_dependent.md b/doc/zh_CN/syntax/type/14_dependent.md
new file mode 100644
index 00000000..64e0c1eb
--- /dev/null
+++ b/doc/zh_CN/syntax/type/14_dependent.md
@@ -0,0 +1,76 @@
+# 依赖类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/14_dependent.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+依赖类型是一个特性,可以说是 Erg 的最大特性。
+依赖类型是将值作为参数的类型。 普通的多态类型只能将类型作为参数,但依赖类型放宽了这个限制。
+
+依赖类型等价于`[T; N]`(`数组(T,N)`)。
+这种类型不仅取决于内容类型“T”,还取决于内容数量“N”。 `N` 包含一个`Nat` 类型的对象。
+
+```python
+a1 = [1, 2, 3]
+assert a1 in [Nat; 3]
+a2 = [4, 5, 6, 7]
+assert a1 in [Nat; 4]
+assert a1 + a2 in [Nat; 7]
+```
+
+如果函数参数中传递的类型对象与返回类型有关,则写:
+
+```python
+narray: |N: Nat| {N} -> [{N}; N]
+narray(N: Nat): [N; N] = [N; N]
+assert array(3) == [3, 3, 3]
+```
+
+定义依赖类型时,所有类型参数都必须是常量。
+
+依赖类型本身存在于现有语言中,但 Erg 具有在依赖类型上定义过程方法的特性
+
+```python
+x=1
+f x =
+ print! f::x, module::x
+
+# Phantom 类型有一个名为 Phantom 的属性,其值与类型参数相同
+T X: Int = Class Impl := Phantom X
+T(X).
+ x self = self::Phantom
+
+T(1).x() # 1
+```
+
+可变依赖类型的类型参数可以通过方法应用程序进行转换。
+转换规范是用 `~>` 完成的
+
+```python
+# 注意 `Id` 是不可变类型,不能转换
+VM!(State: {"stopped", "running"}! := _, Id: Nat := _) = Class(..., Impl := Phantom! State)
+VM!().
+ # 不改变的变量可以通过传递`_`省略。
+ start! ref! self("stopped" ~> "running") =
+ self.initialize_something!()
+ self::set_phantom!("running")
+
+# 你也可以按类型参数切出(仅在定义它的模块中)
+VM!.new() = VM!(!"stopped", 1).new()
+VM!("running" ~> "running").stop!ref!self =
+ self.close_something!()
+ self::set_phantom!("stopped")
+
+vm = VM!.new()
+vm.start!()
+vm.stop!()
+vm.stop!() # 类型错误:VM!(!"stopped", 1) 没有 .stop!()
+# 提示:VM!(!"running", 1) 有 .stop!()
+```
+
+您还可以嵌入或继承现有类型以创建依赖类型。
+
+```python
+MyArray(T, N) = Inherit[T; N]
+
+# self 的类型:Self(T, N) 与 .array 一起变化
+MyStruct!(T, N: Nat!) = Class {.array: [T; !N]}
+```
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/15_quantified.md b/doc/zh_CN/syntax/type/15_quantified.md
new file mode 100644
index 00000000..d6212a30
--- /dev/null
+++ b/doc/zh_CN/syntax/type/15_quantified.md
@@ -0,0 +1,282 @@
+# 类型变量,量化类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/15_quantified.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+类型变量是用于例如指定子程序参数类型的变量,它的类型是任意的(不是单态的)。
+首先,作为引入类型变量的动机,考虑 `id` 函数,它按原样返回输入。
+
+```python
+id x: Int = x
+```
+
+返回输入的“id”函数是为“Int”类型定义的,但这个函数显然可以为任何类型定义。
+让我们使用 `Object` 来表示最大的类。
+
+```python
+id x: Object = x
+
+i = id 1
+s = id "foo"
+b = id True
+```
+
+当然,它现在接受任意类型,但有一个问题:返回类型被扩展为 `Object`。 返回类型扩展为 `Object`。
+如果输入是“Int”类型,我想查看返回类型“Int”,如果输入是“Str”类型,我想查看“Str”。
+
+```python
+print! id 1 #
+id(1) + 1 # 类型错误:无法添加 `Object` 和 `Int
+```
+
+要确保输入的类型与返回值的类型相同,请使用 __type 变量__。
+类型变量在`||`(类型变量列表)中声明。
+
+```python
+id|T: Type| x: T = x
+assert id(1) == 1
+assert id("foo") == "foo"
+assert id(True) == True
+```
+
+这称为函数的 __universal quantification(泛化)__。 有细微的差别,但它对应于其他语言中称为泛型的函数。 泛化函数称为__多态函数__。
+定义一个多态函数就像为所有类型定义一个相同形式的函数(Erg 禁止重载,所以下面的代码真的不能写)。
+
+```python
+id|T: Type| x: T = x
+# 伪代码
+id x: Int = x
+id x: Str = x
+id x: Bool = x
+id x: Ratio = x
+id x: NoneType = x
+...
+```
+
+此外,类型变量“T”可以推断为“Type”类型,因为它在类型规范中使用。 所以 `|T: Type|` 可以简单地缩写为 `|T|`。
+你也可以省略`|T, N| 脚; N]` 如果可以推断它不是类型对象(`T: Type, N: Nat`)。
+
+如果类型对于任意类型来说太大,您也可以提供约束。
+约束也有优势,例如,子类型规范允许使用某些方法。
+
+```python
+# T <: Add
+# => T 是 Add 的子类
+# => 可以做加法
+add|T <: Add| l: T, r: T = l + r
+```
+
+在本例中,`T` 必须是`Add` 类型的子类,并且要分配的`l` 和`r` 的实际类型必须相同。
+在这种情况下,“T”由“Int”、“Ratio”等满足。因此,例如,“Int”和“Str”的添加没有定义,因此被拒绝。
+
+您也可以像这样键入它。
+
+```python
+f|
+ Y, Z: Type
+ X <: Add Y, O1
+ O1 <: Add Z, O2
+ O2 <: Add X, _
+| x: X, y: Y, z: Z =
+ x + y + z + x
+```
+
+如果注释列表很长,您可能需要预先声明它。
+
+```python
+f: |Y, Z: Type, X <: Add(Y, O1), O1 <: Add(Z, O2), O2 <: Add(X, O3)| (X, Y, Z) -> O3
+f|X, Y, Z| x: X, y: Y, z: Z =
+ x + y + z + x
+```
+
+与许多具有泛型的语言不同,所有声明的类型变量都必须在临时参数列表(`x: X, y: Y, z: Z` 部分)或其他类型变量的参数中使用。
+这是 Erg 语言设计的一个要求,即所有类型变量都可以从真实参数中推断出来。
+因此,无法推断的信息,例如返回类型,是从真实参数传递的; Erg 允许从实参传递类型。
+
+```python
+Iterator T = Trait {
+ # 从参数传递返回类型。
+ # .collect: |K: Type -> Type| Self(T). ({K}) -> K(T)
+ .collect(self(T), K: Type -> Type): K(T) = ...
+ ...
+}
+
+it = [1, 2, 3].iter().map i -> i + 1
+it.collect(Array) # [2, 3, 4].
+```
+
+类型变量只能在 `||` 期间声明。 但是,一旦声明,它们就可以在任何地方使用,直到它们退出作用域
+
+```python
+f|X|(x: X): () =
+ y: X = x.clone()
+ log X.__name__
+ log X
+
+f 1
+# Int
+#
+```
+
+您也可以在使用时明确单相如下
+
+```python
+f: Int -> Int = id|Int|
+```
+
+在这种情况下,指定的类型优先于实际参数的类型(匹配失败将导致类型错误,即实际参数的类型错误)。
+即如果传递的实际对象可以转换为指定的类型,则进行转换; 否则会导致编译错误。
+
+```python
+assert id(1) == 1
+assert id|Int|(1) in Int
+assert id|Ratio|(1) in Ratio
+# 你也可以使用关键字参数
+assert id|T: Int|(1) == 1
+id|Int|("str") # 类型错误: id|Int| is type `Int -> Int`但得到了 Str
+```
+
+当此语法与理解相冲突时,您需要将其括在 `()` 中。
+
+```python
+# {id|Int| x | x <- 1..10} 将被解释为 {id | ...}
+{(id|Int| x) | x <- 1..10}
+```
+
+不能使用与已存在的类型相同的名称来声明类型变量。 这是因为所有类型变量都是常量。
+
+```python
+I: Type
+# ↓ 无效类型变量,已经存在
+f|I: Type| ... = ...
+```
+
+## 在方法定义中输入参数
+
+默认情况下,左侧的类型参数被视为绑定变量。
+
+```python
+K(T: Type, N: Nat) = ...
+K(T, N).
+ foo(x) = ...
+```
+
+使用另一个类型变量名称将导致警告。
+
+```python
+K(T: Type, N: Nat) = ...
+K(U, M). # 警告:K 的类型变量名是 'T' 和 'N'
+ foo(x) = ...
+```
+
+自定义以来,所有命名空间中的常量都是相同的,因此它们当然不能用于类型变量名称
+
+```python
+N = 1
+K(N: Nat) = ... # 名称错误:N 已定义
+
+L(M: Nat) = ...
+# 仅当 M == N == 1 时才定义
+L(N).
+ foo(self, x) = ...
+# 为任何定义 M: Nat
+L(M).
+ .bar(self, x) = ...
+```
+
+每个类型参数不能有多个定义,但可以定义具有相同名称的方法,因为未分配类型参数的依赖类型(非原始类型)和分配的依赖类型(原始类型)之间没有关系 )。
+
+```python
+K(I: Int) = ...
+K.
+ # K 不是真正的类型(atomic Kind),所以我们不能定义方法
+ # 这不是方法(更像是静态方法)
+ foo(x) = ...
+K(0).
+ foo(self, x): Nat = ...
+```
+
+## 所有对称类型
+
+上一节中定义的 `id` 函数是一个可以是任何类型的函数。 那么 `id` 函数本身的类型是什么?
+
+```python
+print! classof(id) # |T: Type| T -> T
+```
+
+我们得到一个类型`|T: Type| T -> T`。 这称为一个 __封闭的全称量化类型/全称类型__,即`['a. ...]'` 在 ML 和 `forall t. ...` 在 Haskell 中。 为什么使用形容词“关闭”将在下面讨论。
+
+封闭的全称量化类型有一个限制:只有子程序类型可以被通用量化,即只有子程序类型可以放在左子句中。 但这已经足够了,因为子程序是 Erg 中最基本的控制结构,所以当我们说“我要处理任意 X”时,即我想要一个可以处理任意 X 的子程序。所以,量化类型具有相同的含义 作为多态函数类型。 从现在开始,这种类型基本上被称为多态函数类型。
+
+与匿名函数一样,多态类型具有任意类型变量名称,但它们都具有相同的值。
+
+```python
+assert (|T: Type| T -> T) == (|U: Type| U -> U)
+```
+
+当存在 alpha 等价时,等式得到满足,就像在 lambda 演算中一样。 由于对类型的操作有一些限制,所以总是可以确定等价的(如果我们不考虑 stoppage 属性)。
+
+## 多态函数类型的子类型化
+
+多态函数类型可以是任何函数类型。 这意味着与任何函数类型都存在子类型关系。 让我们详细看看这种关系。
+
+类型变量在左侧定义并在右侧使用的类型,例如 `OpenFn T: Type = T -> T`,称为 __open 通用类型__。
+相反,在右侧定义和使用类型变量的类型,例如 `ClosedFn = |T: Type| T -> T`,被称为 __封闭的通用类型__。
+
+开放通用类型是所有同构“真”类型的超类型。 相反,封闭的通用类型是所有同构真类型的子类型。
+
+```python
+(|T: Type| T -> T) < (Int -> Int) < (T -> T)
+```
+
+您可能还记得封闭的较小/开放的较大。
+但为什么会这样呢? 为了更好地理解,让我们考虑每个实例。
+
+```python
+# id: |T: Type| T -> T
+id|T|(x: T): T = x
+
+# iid: Int -> Int
+iid(x: Int): Int = x
+
+# 按原样返回任意函数
+id_arbitrary_fn|T|(f1: T -> T): (T -> T) = f
+# id_arbitrary_fn(id) == id
+# id_arbitrary_fn(iid) == iid
+
+# return the poly correlation number as it is
+id_poly_fn(f2: (|T| T -> T)): (|T| T -> T) = f
+# id_poly_fn(id) == id
+id_poly_fn(iid) # 类型错误
+
+# 按原样返回 Int 类型函数
+id_int_fn(f3: Int -> Int): (Int -> Int) = f
+# id_int_fn(id) == id|Int|
+# id_int_fn(iid) == iid
+```
+
+由于 `id` 是 `|T: Type| 类型T -> T`,可以赋值给`Int-> Int`类型的参数`f3`,我们可以考虑`(|T| T -> T) < (Int -> Int)`。
+反之,`Int -> Int`类型的`iid`不能赋值给`(|T| T -> T)`类型的参数`f2`,但可以赋值给`(|T| T -> T)`的参数`f1`输入 `T -> T`,所以 `(Int -> Int) < (T -> T)`。
+因此,确实是`(|T| T -> T) < (Int -> Int) < (T -> T)`。
+
+## 量化类型和依赖类型
+
+依赖类型和量化类型(多态函数类型)之间有什么关系,它们之间有什么区别?
+我们可以说依赖类型是一种接受参数的类型,而量化类型是一种赋予参数任意性的类型。
+
+重要的一点是封闭的多态类型本身没有类型参数。例如,多态函数类型`|T| T -> T` 是一个接受多态函数 __only__ 的类型,它的定义是封闭的。您不能使用其类型参数`T`来定义方法等。
+
+在 Erg 中,类型本身也是一个值,因此带参数的类型(例如函数类型)可能是依赖类型。换句话说,多态函数类型既是量化类型又是依赖类型。
+
+```python
+PolyFn = Patch(|T| T -> T)
+PolyFn.
+ type self = T # 名称错误:找不到“T”
+DepFn T = Patch(T -> T)
+DepFn.
+ type self =
+ log "by DepFn"
+ T
+
+assert (Int -> Int).type() == Int # 由 DepFn
+assert DepFn(Int).type() == Int # 由 DepFn
+```
diff --git a/doc/zh_CN/syntax/type/16_subtyping.md b/doc/zh_CN/syntax/type/16_subtyping.md
new file mode 100644
index 00000000..5ca87c63
--- /dev/null
+++ b/doc/zh_CN/syntax/type/16_subtyping.md
@@ -0,0 +1,78 @@
+# 子类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/16_subtyping.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+在 Erg 中,可以使用比较运算符 `<`、`>` 确定类包含。
+
+```python
+Nat < Int
+Int < Object
+1... _ < Nat
+{1, 2} > {1}
+{=} > {x = Int}
+{I: Int | I >= 1} < {I: Int | I >= 0}
+```
+
+请注意,这与 `<:` 运算符的含义不同。 它声明左侧的类是右侧类型的子类型,并且仅在编译时才有意义。
+
+```python
+C <: T # T: 结构类型
+f|D <: E| ...
+
+assert F < G
+```
+
+您还可以为多态子类型规范指定 `Self <: Add`,例如 `Self(R, O) <: Add(R, O)`。
+
+## 结构类型和类类型关系
+
+结构类型是结构类型的类型,如果它们具有相同的结构,则被认为是相同的对象。
+
+```python
+T = Structural {i = Int}
+U = Structural {i = Int}
+
+assert T == U
+t: T = {i = 1}
+assert t in T
+assert t in U
+```
+
+相反,类是符号类型的类型,不能在结构上与类型和实例进行比较
+
+```python
+C = Class {i = Int}
+D = Class {i = Int}
+
+assert C == D # 类型错误:无法比较类
+c = C.new {i = 1}
+assert c in C
+assert not c in D
+```
+
+## 子程序的子类型化
+
+子例程的参数和返回值只采用一个类。
+换句话说,您不能直接将结构类型或特征指定为函数的类型。
+必须使用部分类型规范将其指定为“作为该类型子类型的单个类”。
+
+```python
+# OK
+f1 x, y: Int = x + y
+# NG
+f2 x, y: Add = x + y
+# OK
+# A 是一些具体的类
+f3 x, y: A = x + y
+```
+
+子程序中的类型推断也遵循此规则。 当子例程中的变量具有未指定的类型时,编译器首先检查它是否是其中一个类的实例,如果不是,则在特征范围内查找匹配项。 如果仍然找不到,则会发生编译错误。 此错误可以通过使用结构类型来解决,但由于推断匿名类型可能会给程序员带来意想不到的后果,因此它被设计为由程序员使用 `Structural` 显式指定。
+
+## 类向上转换
+
+```python
+i: Int
+i as (Int or Str)
+i as (1..10)
+i as {I: Int | I >= 0}
+```
diff --git a/doc/zh_CN/syntax/type/17_type_casting.md b/doc/zh_CN/syntax/type/17_type_casting.md
new file mode 100644
index 00000000..cd04bcc6
--- /dev/null
+++ b/doc/zh_CN/syntax/type/17_type_casting.md
@@ -0,0 +1,74 @@
+# 投掷
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/17_type_casting.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 向上转型
+
+因为 Python 是一种使用鸭子类型的语言,所以没有强制转换的概念。没有必要向上转型,本质上也没有向下转型。
+但是,Erg 是静态类型的,因此有时必须进行强制转换。
+一个简单的例子是 `1 + 2.0`:`+`(Int, Ratio) 或 Int(<: Add(Ratio, Ratio)) 操作在 Erg 语言规范中没有定义。这是因为 `Int <: Ratio`,所以 1 向上转换为 1.0,即 Ratio 的一个实例。
+
+~~ Erg扩展字节码在BINARY_ADD中增加了类型信息,此时类型信息为Ratio-Ratio。在这种情况下,BINARY_ADD 指令执行 Int 的转换,因此没有插入指定转换的特殊指令。因此,例如,即使您在子类中重写了某个方法,如果您将父类指定为类型,则会执行类型强制,并在父类的方法中执行该方法(在编译时执行名称修改以引用父母的方法)。编译器只执行类型强制验证和名称修改。运行时不强制转换对象(当前。可以实现强制转换指令以优化执行)。 ~~
+
+```python
+@Inheritable
+Parent = Class()
+Parent.
+ greet!() = print! "Hello from Parent"
+
+Child = Inherit Parent
+Child.
+ # Override 需要 Override 装饰器
+ @Override
+ greet!() = print! "Hello from Child"
+
+greet! p: Parent = p.greet!()
+
+parent = Parent.new()
+child = Child.new()
+
+parent # 来自Parent的问候!
+child # 来自child的问候!
+```
+
+此行为不会造成与 Python 的不兼容。 首先,Python 没有指定变量的类型,所以可以这么说,所有的变量都是类型变量。 由于类型变量会选择它们可以适应的最小类型,因此如果您没有在 Erg 中指定类型,则可以实现与 Python 中相同的行为。
+
+```python
+@Inheritable
+Parent = Class()
+Parent.
+ greet!() = print! "Hello from Parent"
+
+Child = Inherit Parent
+Child.
+ greet!() = print! "Hello from Child" Child.
+
+greet! some = some.greet!()
+
+parent = Parent.new()
+child = Child.new()
+
+parent # 来自Parent的问候!
+child # 来自child的问候!
+```
+
+您还可以使用 `.from` 和 `.into`,它们会为相互继承的类型自动实现
+
+```python
+assert 1 == 1.0
+assert Ratio.from(1) == 1.0
+assert 1.into() == 1.0
+```
+
+## 向下转型
+
+由于向下转换通常是不安全的并且转换方法很重要,我们改为实现“TryFrom.try_from”
+
+```python
+IntTryFromFloat = Patch Int
+IntTryFromFloat.
+ try_from r: Float =
+ if r.ceil() == r:
+ then: r.ceil()
+ else: Error "conversion failed".
+```
diff --git a/doc/zh_CN/syntax/type/18_mut.md b/doc/zh_CN/syntax/type/18_mut.md
new file mode 100644
index 00000000..d1f11fc8
--- /dev/null
+++ b/doc/zh_CN/syntax/type/18_mut.md
@@ -0,0 +1,165 @@
+# 可变类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/18_mut.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+> __Warning__:本节中的信息是旧的并且包含一些错误。
+
+默认情况下,Erg 中的所有类型都是不可变的,即它们的内部状态无法更新。
+但是你当然也可以定义可变类型。 变量类型用 `!` 声明。
+
+```python
+Person! = Class({name = Str; age = Nat!})
+Person!.
+ greet! ref! self = print! "Hello, my name is {self::name}. I am {self::age}."
+ inc_age!ref!self = self::name.update!old -> old + 1
+```
+
+准确地说,基类型是可变类型或包含可变类型的复合类型的类型必须在类型名称的末尾有一个“!”。 没有 `!` 的类型可以存在于同一个命名空间中,并被视为单独的类型。
+在上面的例子中,`.age` 属性是可变的,`.name` 属性是不可变的。 如果即使一个属性是可变的,那么整个属性也是可变的。
+
+可变类型可以定义重写实例的过程方法,但具有过程方法并不一定使它们可变。 例如数组类型`[T; N]` 实现了一个 `sample!` 随机选择一个元素的方法,但当然不会破坏性地修改数组。
+
+对可变对象的破坏性操作主要是通过 .update! 方法完成的。 `.update!` 方法是一个高阶过程,它通过应用函数 `f` 来更新 `self`
+
+```python
+i = !1
+i.update! old -> old + 1
+assert i == 2
+```
+
+`.set!` 方法只是丢弃旧内容并用新值替换它。 .set!x = .update!_ -> x。
+
+```python
+i = !1
+i.set! 2
+assert i == 2
+```
+
+`.freeze_map` 方法对不变的值进行操作
+
+```python
+a = [1, 2, 3].into [Nat; !3]
+x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(Array)
+```
+
+在多态不可变类型中,该类型的类型参数“T”被隐式假定为不可变。
+
+```python
+# ImmutType < Type
+KT: ImmutType = Class ...
+K!T: Type = Class ...
+```
+
+在标准库中,变量 `(...)!` 类型通常基于不可变 `(...)` 类型。 但是,`T!` 和 `T` 类型没有特殊的语言关系,并且不能这样构造 [1 ](#1) 。
+
+请注意,有几种类型的对象可变性。
+下面我们将回顾内置集合类型的不可变/可变语义。
+
+```python
+# 数组类型
+## 不可变类型
+[T; N] # 不能执行可变操作
+## 可变类型
+[T; N] # 可以一一改变内容
+[T; !N] # 可变长度,内容不可变但可以通过添加/删除元素来修改
+[!T; N] # 内容是不可变的对象,但是可以替换成不同的类型(实际上可以通过不改变类型来替换)
+[!T; !N] # 类型和长度可以改变
+[T; !N] # 内容和长度可以改变
+[!T!; N] # 内容和类型可以改变
+[!T!; !N] # 可以执行各种可变操作
+```
+
+当然,您不必全部记住和使用它们。
+对于可变数组类型,只需将 `!` 添加到您想要可变的部分,实际上是 `[T; N]`, `[T!; N]`,`[T; !N]`, ` [T!; !N]` 可以涵盖大多数情况。
+
+这些数组类型是语法糖,实际类型是:
+
+```python
+# actually 4 types
+[T; N] = Array(T, N)
+[T; !N] = Array!(T, !N)
+[!T; N] = ArrayWithMutType!(!T, N)
+[!T; !N] = ArrayWithMutTypeAndLength!(!T, !N)
+[T!; !N] = Array!(T!, !N)
+[!T!; N] = ArrayWithMutType!(!T!, N)
+[!T!; !N] = ArrayWithMutTypeAndLength!(!T!, !N)
+```
+
+这就是能够改变类型的意思。
+
+```python
+a = [1, 2, 3].into [!Nat; 3]
+a.map!(_ -> "a")
+a: [!Str; 3]
+```
+
+其他集合类型也是如此。
+
+```python
+# 元组类型
+## 不可变类型
+(T, U) # 元素个数不变,内容不能变
+## 可变类型
+(T!, U) # 元素个数不变,第一个元素可以改变
+(T,U)! # 元素个数不变,内容可以替换
+...
+```
+
+```python
+# 设置类型
+## 不可变类型
+{T; N} # 不可变元素个数,内容不能改变
+## 可变类型
+{T!; N} # 不可变元素个数,内容可以改变(一个一个)
+{T; N}! # 可变元素个数,内容不能改变
+{T!; N}! # 可变元素个数,内容可以改变
+...
+```
+
+```python
+# 字典类型
+## 不可变类型
+{K: V} # 长度不可变,内容不能改变
+## 可变类型
+{K:V!} # 恒定长度,值可以改变(一一)
+{K:V}! # 可变长度,内容不能改变,但可以通过添加或删除元素来增加或删除,内容类型也可以改变
+...
+```
+
+```python
+# 记录类型
+## 不可变类型
+{x = Int; y = Str} # 内容不能改变
+## 可变类型
+{x = Int!; y = Str} # 可以改变x的值
+{x = Int; y = Str}! # 替换 {x = Int; 的任何实例 y = Str}
+...
+```
+
+一个类型 `(...)` 简单地变成了 `T! = (...)!` 当 `T = (...)` 被称为简单结构化类型。 简单的结构化类型也可以(语义上)说是没有内部结构的类型。
+数组、元组、集合、字典和记录类型都是非简单的结构化类型,但 Int 和 Sieve 类型是。
+
+```python
+#筛子类型
+## 枚举
+{1, 2, 3} # 1, 2, 3 之一,不可更改
+{1、2、3}! # 1、2、3,可以改
+##区间类型
+1..12 #1到12,不能改
+1..12! # 1-12中的任意一个,你可以改变
+##筛型(普通型)
+{I: Int | I % 2 == 0} #偶数类型,不可变
+{I: Int | I % 2 == 0} #偶数类型,可以改变
+{I: Int | I % 2 == 0}! # 与上面完全相同的类型,但上面的表示法是首选
+```
+
+从上面的解释来看,可变类型不仅包括自身可变的,还包括内部类型可变的。
+诸如 `{x: Int!}` 和 `[Int!; 之类的类型3]` 是内部可变类型,其中内部的对象是可变的,而实例本身是不可变的。
+
+对于具有内部结构并在类型构造函数本身上具有 `!` 的类型 `K!(T, U)`,`*self` 可以更改整个对象。也可以进行局部更改。
+但是,希望尽可能保持本地更改权限,因此如果只能更改 `T`,最好使用 `K(T!, U)`。
+而对于没有内部结构的类型‘T!’,这个实例只是一个可以交换的‘T’盒子。方法不能更改类型。
+
+---
+
+1 `T!` 和 `T` 类型没有特殊的语言关系是有意的。这是一个设计。如果存在关系,例如命名空间中存在`T`/`T!`类型,则无法从其他模块引入`T!`/`T`类型。此外,可变类型不是为不可变类型唯一定义的。给定定义 `T = (U, V)`,`T!` 的可能变量子类型是 `(U!, V)` 和 `(U, V!)`。[↩](#f1)
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/19_bound.md b/doc/zh_CN/syntax/type/19_bound.md
new file mode 100644
index 00000000..cba0b9ca
--- /dev/null
+++ b/doc/zh_CN/syntax/type/19_bound.md
@@ -0,0 +1,20 @@
+# 类型绑定
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/19_bound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+类型边界为类型规范添加条件。 实现这一点的函数是守卫(守卫子句)。
+此功能可用于函数签名、匿名函数签名以及筛选类型。
+守卫写在返回类型之后。
+
+## 谓词
+
+您可以使用返回 `Bool` 的表达式(谓词表达式)指定变量满足的条件。
+只能使用 [值对象](./08_value.md) 和运算符。 未来版本可能会支持编译时函数
+
+```python
+f a: [T; N] | T, N, N > 5 = ...
+g a: [T; N | N > 5] | T, N = ...
+Odd = {I: Int | I % 2 == 1}
+R2Plus = {(L, R) | L, R: Ratio; L > 0 and R > 0}
+GeneralizedOdd = {I | U; I <: Div(Nat, U); I % 2 == 0}
+```
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced.md b/doc/zh_CN/syntax/type/advanced.md
new file mode 100644
index 00000000..95724a0c
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced.md
@@ -0,0 +1,2 @@
+下面,我们将讨论更高级的类型系统。 初学者不必阅读所有部分。[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/syntax/type/advanced/GADTs.md b/doc/zh_CN/syntax/type/advanced/GADTs.md
new file mode 100644
index 00000000..80e00bb5
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/GADTs.md
@@ -0,0 +1,68 @@
+# 广义代数数据类型 (GADT)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/GADTs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg 可以通过对 Or 类型进行分类来创建广义代数数据类型 (GADT)。
+
+```python
+Nil T = Class(Impl := Phantom T)
+Cons T = Class {head = T; rest = List T}, Impl := Unpack
+List T: Type = Class(Nil T or Cons T)
+List.
+ nil|T|() = Self(T).new Nil(T).new()
+ cons head, rest | T = Self(T).new Cons(T).new(head, rest)
+ head self = match self:
+ {head; ...}: Cons_ -> head
+ _: Nil -> panic "empty list"
+{nil; cons; ...} = List
+
+print! cons(1, cons(2, nil())).head() # 1
+print! nil.head() # 运行时错误:“空list”
+```
+
+我们说 `List.nil|T|() = ...` 而不是 `List(T).nil() = ...` 的原因是我们在使用它时不需要指定类型。
+
+```python
+i = List.nil()
+_: List Int = cons 1, i
+```
+
+这里定义的 `List T` 是 GADTs,但它是一个幼稚的实现,并没有显示 GADTs 的真正价值。
+例如,上面的 .head 方法会在 body 为空时抛出运行时错误,但是这个检查可以在编译时进行。
+
+```python
+List: (Type, {"Empty", "Nonempty"}) -> Type
+List T, "Empty" = Class(Impl := Phantom T)
+List T, "Nonempty" = Class {head = T; rest = List(T, _)}, Impl := Unpack
+List.
+ nil|T|() = Self(T, "Empty").new Nil(T).new()
+ cons head, rest | T = Self(T, "Nonempty").new {head; rest}
+List(T, "Nonempty").
+ head {head; ...} = head
+{nil; cons; ...} = List
+
+print! cons(1, cons(2, nil())).head() # 1
+print! nil().head() # 类型错误
+```
+
+街上经常解释的 GADT 的一个例子是一个列表,可以像上面那样通过类型来判断内容是否为空。
+Erg 可以进一步细化以定义一个有长度的列表。
+
+```python
+List: (Type, Nat) -> Type
+List T, 0 = Class(Impl := Phantom T)
+List T, N = Class {head = T; rest = List(T, N-1)}, Impl := Unpack
+List.
+ nil|T|() = Self(T, 0).new Nil(T).new()
+ cons head, rest | T, N = Self(T, N).new {head; rest}
+List(_, N | N >= 1).
+ head {head; ...} = head
+List(_, N | N >= 2).
+ pair {head = first; rest = {head = second; ...}} = [first, second]
+{nil; cons; ...} = List
+
+print! cons(1, cons(2, nil)).pair() # [1, 2]
+print! cons(1, nil).pair() # 类型错误
+print! cons(1, nil).head() # 1
+print! nil. head() # 类型错误
+```
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced/_rank2type.md b/doc/zh_CN/syntax/type/advanced/_rank2type.md
new file mode 100644
index 00000000..676743a7
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/_rank2type.md
@@ -0,0 +1,144 @@
+# rank-2 多态性
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/_rank2type.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+> __Warning__:本文档已过时,一般包含错误。
+
+Erg 允许您定义接受各种类型的函数,例如 `id|T|(x: T): T = x`,即多相关。
+那么,我们可以定义一个接受多相关的函数吗?
+比如这样的函数(注意这个定义是错误的):
+
+```python
+# 我想要 tuple_map(i -> i * 2, (1, "a")) == (2, "aa")
+tuple_map|T|(f: T -> T, tup: (Int, Str)): (Int, Str) = (f(tup.0), f(tup.1))
+```
+
+注意 `1` 和 `"a"` 有不同的类型,所以匿名函数一次不是单态的。 需要单相两次。
+这样的函数不能在我们目前讨论的类型范围内定义。 这是因为类型变量没有范围的概念。
+让我们暂时离开类型,看看值级别的范围概念。
+
+```python
+arr = [1, 2, 3]
+arr.map i -> i + 1
+```
+
+上面代码中的 `arr` 和 `i` 是不同作用域的变量。 因此,每个寿命都是不同的(`i` 更短)。
+
+到目前为止,所有类型变量的类型都具有相同的生命周期。 换句话说,‘T’、‘X’和‘Y’必须同时确定,之后保持不变。
+反之,如果我们可以将 `T` 视为“内部作用域”中的类型变量,我们可以组成一个 `tuple_map` 函数。 __Rank 2 type__ 就是为此目的而准备的。
+
+```python
+# tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str)
+tuple_map f: (|T: Type| T -> T), tup: (Int, Str) = (f(tup.0), f(tup.1))
+assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa")
+```
+
+`{(type) | 形式的类型 (类型变量列表)}` 被称为通用类型(详见[通用类型](./../quantified.md))。
+目前我们看到的`id`函数是一个典型的通用函数=多相关函数。
+
+```python
+id x = x
+id: |T: Type| T -> T
+```
+
+通用类型与函数类型构造函数`->`的关联有特殊的规则,根据关联的方式,类型的语义是完全不同的。
+
+用简单的单参数函数来考虑这一点。
+
+```python
+f1: (T -> T) -> 整数 | T # 接受任何函数并返回 Int 的函数
+f2: (|T: Type| T -> T) -> Int # 接收多相关并返回 Int 的函数
+f3: Int -> (|T: Type| T -> T) # 一个函数,接受一个 Int 并返回一个封闭的通用函数
+f4: |T: Type|(Int -> (T -> T)) # 同上(首选)
+```
+
+`f1` 和 `f2` 不同,而 `f3` 和 `f4` 相同,这似乎很奇怪。 让我们实际构造一个这种类型的函数。
+
+```python
+# id: |T: Type| T -> T
+id x = x
+# same type as `f1`
+take_univq_f_and_return_i(_: (|T: Type| T -> T), i: Int): Int = i
+# same type as `f2`
+take_arbit_f_and_return_i|T: Type|(_: T -> T, i: Int): Int = i
+# same type as `f3`
+take_i_and_return_univq_f(_: Int): (|T: Type| T -> T) = id
+# same type as `f4`
+take_i_and_return_arbit_f|T: Type|(_: Int): (T -> T) = id
+```
+
+After applying it, you will notice the difference.
+
+```python
+_ = take_univq_f_and_return_i(x -> x, 1) # OK
+_ = take_univq_f_and_return_i(x: Int -> x, 1) #NG
+_ = take_univq_f_and_return_i(x: Str -> x, 1) # NG
+_ = take_arbit_f_and_return_i(x -> x, 1) # OK
+_ = take_arbit_f_and_return_i(x: Int -> x, 1) # OK
+_ = take_arbit_f_anf_return_i(x: Str -> x, 1) # OK
+
+f: |T| T -> T = take_i_and_return_univq_f(1)
+g: |T| T -> T = take_i_and_return_arbit_f(1)
+assert f == g
+f2: Int -> Int = take_i_and_return_univq_f|Int|(1)
+g2: Int -> Int = take_i_and_return_arbit_f|Int|(1)
+assert f2 == g2
+```
+
+开放的多相关函数类型具体称为 __任意函数类型__。 任意函数类型有无数种可能性:`Int -> Int`、`Str -> Str`、`Bool -> Bool`、`|T: Type| T -> T`, ... 是。
+另一方面,只有一个封闭的(返回与参数相同类型的对象)多态类型`|T:Type| T -> T`。 这种类型被专门称为 __多态函数类型__。
+也就是说,`f1`可以通过`x: Int -> x+1`、`x: Bool -> not x`、`x -> x`等=`f1`是一个多相关数是的, 但是您只能将 `x -> x` 等传递给 `f2` = `f2` 不是 __多元相关__。
+但是像`f2`这样的函数类型明显不同于普通类型,我们需要新的概念来处理它们。 那是类型的“等级”。
+
+关于rank的定义,没有量化的类型,如`Int`、`Str`、`Bool`、`T`、`Int -> Int`、`Option Int`等,都被视为“rank” 0”。
+
+```python
+# K 是多项式类型,例如 Option
+R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0)
+```
+
+接下来,具有一阶全称的类型,例如`|T| T -> T`,或者在返回值类型中包含它们的类型是“rank 1”。
+此外,具有二阶全称量化的类型(具有 rank 1 类型作为参数的类型,例如 `(|T| T -> T) -> Int`)或将它们包含在返回类型中的类型称为“rank 2 ”。
+重复上述以定义“Rank N”类型。 此外,秩-N 类型包括秩为N 或更少的所有类型。 因此,混合等级的类型与其中最高的等级相同。
+
+```python
+R1 = (|...| R0) or (R0 -> R1) or K(R1) or R0
+R2 = (|...| R1) or (R1 -> R2) or K(R2) or R1
+...
+Rn = (|...| Rn-1) or (Rn-1 -> Rn) or K(Rn) or Rn-1
+```
+
+让我们看看例子:
+
+```python
+ (|T: Type| T -> T) -> (|U: Type| U -> U)
+=> R1 -> R1
+=> R1 -> R2
+=> R2
+
+Option(|T: Type| T -> T)
+=> Option(R1)
+=> K(R1)
+=> R1
+```
+
+根据定义,`tuple_map` 是 rank-2 类型。
+
+```python
+tuple_map:
+ ((|T: Type| T -> T), (Int, Str)) -> (Int, Str)
+=> (R1, R0) -> R0
+=> R1 -> R2
+=> R2
+```
+
+Erg 最多可以处理 rank 2 的类型(因为 rank N 类型包括所有 rank N 或更少的类型,确切地说,所有 Erg 类型都是 rank 2 类型)。 试图构造更多类型的函数是错误的。
+例如,所有处理多相关的函数都需要指定其他参数类型。 而且,这样的功能是不可配置的。
+
+```python
+# 这是一个 rank-3 类型的函数
+# |X, Y: Type|((|T: Type| T -> T), (X, Y)) -> (X, Y)
+generic_tuple_map|X, Y: Type| f: (|T: Type| T -> T), tup: (X, Y) = (f(tup.0), f(tup.1))
+```
+
+众所周知,具有 3 级或更高等级的类型在理论上无法通过类型推断来确定。 然而,大多数实际需求可以被等级 2 类型覆盖。
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced/default_param.md b/doc/zh_CN/syntax/type/advanced/default_param.md
new file mode 100644
index 00000000..27d3dc18
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/default_param.md
@@ -0,0 +1,30 @@
+# 带默认参数的函数类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/default_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+首先,让我们看一个使用默认参数的示例。
+
+```python
+f: (Int, Int, z := Int) -> Int
+f(x, y, z := 0) = x + y + z
+
+g: (Int, Int, z := Int, w := Int) -> Int
+g(x, y, z := 0, w := 1) = x + y + z + w
+
+fold: ((Int, Int) -> Int, [Int], acc := Int) -> Int
+fold(f, [], acc) = acc
+fold(f, arr, acc := 0) = fold(f, arr[1..], f(acc, arr[0]))
+assert fold(f, [1, 2, 3]) == 6
+assert fold(g, [1, 2, 3]) == 8
+```
+
+`:=` 之后的参数是默认参数。
+子类型规则如下:
+
+```python
+((X, y := Y) -> Z) <: (X -> Z)
+((X, y := Y, ...) -> Z) <: ((X, ...) -> Z)
+```
+
+第一个意味着可以用没有默认参数的函数来识别具有默认参数的函数。
+第二个意味着可以省略任何默认参数。
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced/erasure.md b/doc/zh_CN/syntax/type/advanced/erasure.md
new file mode 100644
index 00000000..3395ecf7
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/erasure.md
@@ -0,0 +1,45 @@
+# 类型擦除
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/erasure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+类型擦除是将类型参数设置为 `_` 并故意丢弃其信息的过程。类型擦除是许多多态语言的特性,但在 Erg 的语法上下文中,将其称为类型参数擦除更为准确。
+
+类型擦除的最常见示例是 `[T, _]`。数组在编译时并不总是知道它们的长度。例如,引用命令行参数的 `sys.argv` 的类型为 `[Str, _]`。由于 Erg 的编译器无法知道命令行参数的长度,因此必须放弃有关其长度的信息。
+然而,一个已经被类型擦除的类型变成了一个未被擦除的类型的超类型(例如`[T; N] <: [T; _]`),所以它可以接受更多的对象。
+类型的对象`[T; N]` 当然可以使用 `[T; _]`,但使用后会删除`N`信息。如果长度没有改变,那么可以使用`[T; N]` 在签名中。如果长度保持不变,则必须由签名指示。
+
+```python
+# 保证不改变数组长度的函数(例如,排序)
+f: [T; N] -> [T; N] # 没有的函数 (f: [T; N])
+# 没有的功能(例如过滤器)
+g: [T; n] -> [T; _]
+```
+
+如果您在类型规范本身中使用 `_`,则类型将向上转换为 `Object`。
+对于非类型类型参数(Int、Bool 等),带有 `_` 的参数将是未定义的。
+
+```python
+i: _ # i: Object
+[_; _] == [Object; _] == Array
+```
+
+类型擦除与省略类型说明不同。 一旦类型参数信息被删除,除非您再次声明它,否则它不会被返回。
+
+```python
+implicit = (1..5).iter().map(i -> i * 2).to_arr()
+explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat))
+```
+
+在 Rust 中,这对应于以下代码:
+
+```rust
+let partial = (1..6).iter().map(|i| i * 2).collect::>();
+```
+
+Erg 不允许部分省略类型,而是使用高阶种类多态性。
+
+```python
+# collect 是采用 Kind 的高阶 Kind 方法
+hk = (1..5).iter().map(i -> i * 2).collect(Array)
+hk: Array(Int)
+```
diff --git a/doc/zh_CN/syntax/type/advanced/existential.md b/doc/zh_CN/syntax/type/advanced/existential.md
new file mode 100644
index 00000000..fb829825
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/existential.md
@@ -0,0 +1,43 @@
+# 存在类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/existential.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+如果存在对应于∀的for-all类型,那么很自然地假设存在对应于∃的存在类型。
+存在类型并不难。 你已经知道存在类型,只是没有意识到它本身。
+
+```python
+T: Trait
+f x: T = ...
+```
+
+上面的 trait `T` 被用作存在类型。
+相比之下,小写的`T`只是一个特征,`X`是一个for-all类型。
+
+```python
+f|X <: T| x: X = ...
+```
+
+事实上,existential 类型被 for-all 类型所取代。 那么为什么会有存在类型这样的东西呢?
+首先,正如我们在上面看到的,存在类型不涉及类型变量,这简化了类型规范。
+此外,由于可以删除类型变量,因此如果它是一个全推定类型,则可以构造一个等级为 2 或更高的类型。
+
+```python
+show_map f: (|T| T -> T), arr: [Show; _] =
+ arr.map x ->
+ y = f x
+ log y
+ y
+```
+
+但是,如您所见,existential 类型忘记或扩展了原始类型,因此如果您不想扩展返回类型,则必须使用 for-all 类型。
+相反,仅作为参数且与返回值无关的类型可以写为存在类型。
+
+```python
+# id(1): 我希望它是 Int
+id|T|(x: T): T = x
+# |S <: Show|(s: S) -> () 是多余的
+show(s: Show): () = log s
+```
+
+顺便说一句,类不称为存在类型。 一个类不被称为存在类型,因为它的元素对象是预定义的。
+存在类型是指满足某种特征的任何类型,它不是知道实际分配了什么类型的地方。
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced/keyword_param.md b/doc/zh_CN/syntax/type/advanced/keyword_param.md
new file mode 100644
index 00000000..8b934d23
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/keyword_param.md
@@ -0,0 +1,28 @@
+# 带有关键字参数的函数类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/keyword_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
+h(f) = f(y: 1, x: 2)
+h: |T: type|((y: Int, x: Int) -> T) -> T
+```
+
+带有关键字参数的函数的子类型化规则如下。
+
+```python
+((x: T, y: U) -> V) <: ((T, U) -> V) # x, y 为任意关键字参数
+((y: U, x: T) -> V) <: ((x: T, y: U) -> V)
+((x: T, y: U) -> V) <: ((y: U, x: T) -> V)
+```
+
+这意味着可以删除或替换关键字参数。
+但是你不能同时做这两件事。
+也就是说,您不能将 `(x: T, y: U) -> V` 转换为 `(U, T) -> V`。
+请注意,关键字参数仅附加到顶级元组,而不附加到数组或嵌套元组。
+
+```python
+Valid: [T, U] -> V
+Invalid: [x: T, y: U] -> V
+Valid: (x: T, ys: (U,)) -> V
+Invalid: (x: T, ys: (y: U,)) -> V
+```
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced/kind.md b/doc/zh_CN/syntax/type/advanced/kind.md
new file mode 100644
index 00000000..7d881724
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/kind.md
@@ -0,0 +1,149 @@
+# Kind
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/kind.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+一切都在 Erg 中输入。类型本身也不例外。 __kind__ 表示“类型的类型”。例如,`Int` 属于 `Type`,就像 `1` 属于 `Int`。 `Type` 是最简单的一种,__atomic kind__。在类型论符号中,`Type` 对应于 `*`。
+
+在Kind的概念中,实际上重要的是一种或多种Kind(多项式Kind)。单项类型,例如`Option`,属于它。一元Kind表示为 `Type -> Type` [1 ](#1)。诸如 `Array` 或 `Option` 之类的 __container__ 特别是一种以类型作为参数的多项式类型。
+正如符号 `Type -> Type` 所表明的,`Option` 实际上是一个接收类型 `T` 并返回类型 `Option T` 的函数。但是,由于这个函数不是通常意义上的函数,所以通常称为一元类。
+
+注意`->`本身,它是一个匿名函数操作符,当它接收一个类型并返回一个类型时,也可以看作是一Kind型。
+
+另请注意,不是原子Kind的Kind不是类型。正如 `-1` 是一个数字但 `-` 不是,`Option Int` 是一个类型但 `Option` 不是。 `Option` 等有时被称为类型构造函数。
+
+```python
+assert not Option in Type
+assert Option in Type -> Type
+```
+
+所以像下面这样的代码会报错:
+在 Erg 中,方法只能在原子类型中定义,并且名称 `self` 不能在方法的第一个参数以外的任何地方使用。
+
+```python
+#K 是一元类型
+K: Type -> Type
+K T = Class...
+K.
+foo x = ... # OK,这就像是所谓的静态方法
+ bar self, x = ... # 类型错误: 无法为非类型对象定义方法
+K(T).
+ baz self, x = ... # OK
+```
+
+二进制或更高类型的示例是 `{T: U}`(: `(Type, Type) -> Type`), `(T, U, V)`(: `(Type, Type, Type) - > Type `), ... 等等。
+
+还有一个零项类型`() -> Type`。 这有时等同于类型论中的原子类型,但在 Erg 中有所区别。 一个例子是`类`。
+
+```python
+Nil = Class()
+```
+
+## 收容类
+
+多项类型之间也存在部分类型关系,或者更确切地说是部分类型关系。
+
+```python
+K T = ...
+L = Inherit K
+L<: K
+```
+
+也就是说,对于任何 `T`,如果 `L T <: K T`,则 `L <: K`,反之亦然。
+
+```python
+∀T. L T <: K T <=> L <: K
+```
+
+## 高阶Kind
+
+还有一种高阶Kind。 这是一种与高阶函数相同的概念,一种自身接收一种类型。 `(Type -> Type) -> Type` 是一种更高的Kind。 让我们定义一个属于更高Kind的对象。
+
+```python
+IntContainerOf K: Type -> Type = K Int
+assert IntContainerOf Option == Option Int
+assert IntContainerOf Result == Result Int
+assert IntContainerOf in (Type -> Type) -> Type
+```
+
+多项式类型的有界变量通常表示为 K, L, ...,其中 K 是 Kind 的 K
+
+## 设置Kind
+
+在类型论中,有记录的概念。 这与 Erg 记录 [2 ](#2) 几乎相同。
+
+```python
+# 这是一条记录,对应于类型论中所谓的记录
+{x = 1; y = 2}
+```
+
+当所有的记录值都是类型时,它是一种类型,称为记录类型。
+
+```python
+assert {x = 1; y = 2} in {x = Int; y = Int}
+```
+
+记录类型键入记录。 一个好的猜测者可能认为应该有一个“记录类型”来键入记录类型。 实际上它是存在的。
+
+```python
+log Typeof {x = Int; y = Int} # {{x = Int; y = Int}}
+```
+
+像 `{{x = Int; 这样的类型 y = Int}}` 是一种记录类型。 这不是一个特殊的符号。 它只是一个枚举类型,只有 `{x = Int; y = Int}` 作为一个元素。
+
+```python
+Point = {x = Int; y = Int}
+Pointy = {Point}
+```
+
+记录类型的一个重要属性是,如果 `T: |T|` 和 `U <: T` 则 `U: |T|`。
+从枚举实际上是筛子类型的语法糖这一事实也可以看出这一点。
+
+```python
+# {c} == {X: T | X == c} 对于普通对象,但是不能为类型定义相等性,所以 |T| == {X | X <: T}
+{Point} == {P | P <: Point}
+```
+
+类型约束中的 `U <: T` 实际上是 `U: |T|` 的语法糖。
+作为此类类型的集合的种类通常称为集合种类。 Setkind 也出现在迭代器模式中。
+
+```python
+Iterable T = Trait {
+ .Iterator = {Iterator}
+ .iter = Self(T).() -> Self.Iterator T
+}
+```
+
+## 多项式类型的类型推断
+
+```python
+Container K: Type -> Type, T: Type = Patch K(T, T)
+Container (K).
+ f self = ...
+Option T: Type = Patch T or NoneType
+Option(T).
+ f self = ...
+Fn T: Type = Patch T -> T
+Fn(T).
+ f self = ...
+Fn2 T, U: Type = Patch T -> U
+Fn2(T, U).
+ f self = ...
+
+(Int -> Int).f() # 选择了哪一个?
+```
+在上面的示例中,方法 `f` 会选择哪个补丁?
+天真,似乎选择了`Fn T`,但是`Fn2 T,U`也是可以的,`Option T`原样包含`T`,所以任何类型都适用,`Container K,T`也匹配`->(Int, Int)`,即 `Container(`->`, Int)` 为 `Int -> Int`。因此,上述所有四个修复程序都是可能的选择。
+
+在这种情况下,根据以下优先标准选择修复程序。
+
+* 任何 `K(T)`(例如 `T or NoneType`)优先匹配 `Type -> Type` 而不是 `Type`。
+* 任何 `K(T, U)`(例如 `T -> U`)优先匹配 `(Type, Type) -> Type` 而不是 `Type`。
+* 类似的标准适用于种类 3 或更多。
+* 选择需要较少类型变量来替换的那个。例如,`Int -> Int` 是 `T -> T` 而不是 `K(T, T)`(替换类型变量:K, T)或 `T -> U`(替换类型变量:T, U )。(替换类型变量:T)优先匹配。
+* 如果更换的次数也相同,则报错为不可选择。
+
+---
+
+1 在类型理论符号中,`*=>*` [↩](#f1)
+
+2 可见性等细微差别。[↩](#f2)
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced/marker_trait.md b/doc/zh_CN/syntax/type/advanced/marker_trait.md
new file mode 100644
index 00000000..153b4b1b
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/marker_trait.md
@@ -0,0 +1,33 @@
+# 标记特征
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/marker_trait.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+标记特征是没有必需属性的特征。 也就是说,您可以在不实现任何方法的情况下实现 Impl。
+没有 required 属性似乎没有意义,但由于注册了它属于 trait 的信息,因此可以使用 patch 方法或由编译器进行特殊处理。
+
+所有标记特征都包含在“标记”特征中。
+作为标准提供的“光”是一种标记特征。
+
+```python
+Light = Subsume Marker
+```
+
+```python
+Person = Class {.name = Str; .age = Nat} and Light
+```
+
+```python
+M = Subsume Marker
+
+MarkedInt = Inherit Int, Impl := M
+
+i = MarkedInt.new(2)
+assert i + 1 == 2
+assert i in M
+```
+
+标记类也可以使用 `Excluding` 参数排除。
+
+```python
+NInt = Inherit MarkedInt, Impl := N, Excluding: M
+```
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced/mut_struct.md b/doc/zh_CN/syntax/type/advanced/mut_struct.md
new file mode 100644
index 00000000..c84bc953
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/mut_struct.md
@@ -0,0 +1,42 @@
+# 可变结构类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/mut_struct.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+`T!` 类型被描述为可以被任何 `T` 类型对象替换的盒子类型。
+
+```python
+Particle!State: {"base", "excited"}! = Class(... Impl := Phantom State)
+Particle!
+ # 此方法将状态从“base”移动到“excited”
+ apply_electric_field!(ref! self("base" ~> "excited"), field: Vector) = ...
+```
+
+`T!` 类型可以替换数据,但不能改变其结构。
+更像是一个真实程序的行为,它不能改变它的大小(在堆上)。 这样的类型称为不可变结构(mutable)类型。
+
+事实上,有些数据结构不能用不变的结构类型来表示。
+例如,可变长度数组。 `[T; N]!`类型可以包含任何`[T; N]`,但不能被`[T; N+1]` 等等。
+
+换句话说,长度不能改变。 要改变长度,必须改变类型本身的结构。
+
+这是通过可变结构(可变)类型实现的。
+
+```python
+v = [Str; !0].new()
+v.push! "Hello"
+v: [Str; !1].
+```
+
+对于可变结构类型,可变类型参数用 `!` 标记。 在上述情况下,类型 `[Str; !0]` 可以更改为 `[Str; !1]` 等等。 即,可以改变长度。
+顺便说一句,`[T; !N]` 类型是 `ArrayWithLength!(T, !N)` 类型的糖衣语法。
+
+可变结构类型当然可以是用户定义的。 但是请注意,在构造方法方面与不变结构类型存在一些差异。
+
+```python
+Nil T = Class(Impl := Phantom T)
+List T, !0 = Inherit Nil T
+List T, N: Nat! = Class {head = T; rest = List(T, !N-1)}
+List(T, !N).
+ push! ref! self(N ~> N+1, ...), head: T =
+ self.update! old -> Self.new {head; old}
+```
diff --git a/doc/zh_CN/syntax/type/advanced/newtype.md b/doc/zh_CN/syntax/type/advanced/newtype.md
new file mode 100644
index 00000000..d1cb33db
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/newtype.md
@@ -0,0 +1,33 @@
+# 新类型模式
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/newtype.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+这是 Rust 中常用的 newtype 模式的 Erg 版本。
+
+Erg 允许定义类型别名如下,但它们只引用相同的类型。
+
+```python
+UserID = Int
+```
+
+因此,例如,如果你有一个规范,类型为 `UserId` 的数字必须是一个正的 8 位数字,你可以输入 `10` 或 `-1`,因为它与类型 `Int` 相同 . 如果设置为 `Nat`,则可以拒绝 `-1`,但 8 位数字的性质不能仅用 Erg 的类型系统来表达。
+
+此外,例如,在设计数据库系统时,假设有几种类型的 ID:用户 ID、产品 ID、产品 ID 和用户 ID。 如果 ID 类型的数量增加,例如用户 ID、产品 ID、订单 ID 等,可能会出现将不同类型的 ID 传递给不同函数的 bug。 即使用户 ID 和产品 ID 在结构上相同,但它们在语义上是不同的。
+
+对于这种情况,newtype 模式是一个很好的设计模式。
+
+```python
+UserId = Class {id = Nat}
+UserId.
+ new id: Nat =
+ assert id.dights().len() == 8, else: "UserId 必须是长度为 8 的正数"
+ UserId::__new__ {id;}
+
+i = UserId.new(10000000)
+print! i # <__main__.UserId object>
+i + UserId.new(10000001) # TypeError: + is not implemented between `UserId` and `UserId
+```
+
+构造函数保证 8 位数字的前置条件。
+`UserId` 失去了 `Nat` 拥有的所有方法,所以每次都必须重新定义必要的操作。
+如果重新定义的成本不值得,最好使用继承。 另一方面,在某些情况下,方法丢失是可取的,因此请根据情况选择适当的方法。
diff --git a/doc/zh_CN/syntax/type/advanced/overloading.md b/doc/zh_CN/syntax/type/advanced/overloading.md
new file mode 100644
index 00000000..db6a3602
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/overloading.md
@@ -0,0 +1,91 @@
+# 重载
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/overloading.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Erg 不支持 __ad hoc 多态性__。 也就是说,函数和种类(重载)的多重定义是不可能的。 但是,您可以通过使用特征和补丁的组合来重现重载行为。
+您可以使用特征而不是特征类,但随后将涵盖所有实现 `.add1` 的类型。
+
+```python
+Add1 = Trait {
+ .add1: Self.() -> Self
+}
+IntAdd1 = Patch Int, Impl := Add1
+IntAdd1.
+ add1 self = self + 1
+RatioAdd1 = Patch Ratio, Impl := Add1
+RatioAdd1.
+ add1 self = self + 1.0
+
+add1|X <: Add1| x: X = x.add1()
+assert add1(1) == 2
+assert add1(1.0) == 2.0
+```
+
+这种接受一个类型的所有子类型的多态称为__subtyping polymorphism__。
+
+如果每种类型的过程完全相同,则可以编写如下。 当行为从类到类(但返回类型相同)时,使用上述内容。
+使用类型参数的多态称为 __parametric polymorphism__。 参数多态性通常与子类型结合使用,如下所示,在这种情况下,它是参数和子类型多态性的组合。
+
+```python
+add1|T <: Int or Str| x: T = x + 1
+assert add1(1) == 2
+assert add1(1.0) == 2.0
+```
+
+此外,可以使用默认参数重现具有不同数量参数的类型的重载。
+
+```python
+C = Class {.x = Int; .y = Int}
+C.
+ new(x, y := 0) = Self::__new__ {.x; .y}
+
+assert C.new(0, 0) == C.new(0)
+```
+
+Erg 的立场是,您不能定义行为完全不同的函数,例如根据参数的数量具有不同的类型,但如果行为不同,则应该以不同的方式命名。
+
+综上所述,Erg 禁止重载,采用子类型加参数多态,原因如下。
+
+首先,重载函数分布在它们的定义中。 这使得在发生错误时很难报告错误的原因。
+此外,导入子程序可能会改变已定义子程序的行为。
+
+```python
+{id; ...} = import "foo"
+...
+id x: Int = x
+...
+id x: Ratio = x
+...
+id "str" # 类型错误:没有为 Str 实现 id
+# 但是……但是……这个错误是从哪里来的?
+```
+
+其次,它与默认参数不兼容。 当具有默认参数的函数被重载时,会出现一个优先级的问题。
+
+```python
+f x: Int = ...
+f(x: Int, y := 0) = ...
+
+f(1) # 选择哪个?
+```
+
+此外,它与声明不兼容。
+声明 `f: Num -> Num` 不能指定它引用的定义。 这是因为 `Int -> Ratio` 和 `Ratio -> Int` 不包含在内。
+
+```python
+f: Num -> Num
+f(x: Int): Ratio = ...
+f(x: Ratio): Int = ...
+```
+
+并且语法不一致:Erg禁止变量重新赋值,但是重载的语法看起来像重新赋值。
+也不能用匿名函数代替。
+
+```python
+# 同 `f = x -> body`
+f x = body
+
+# 一样……什么?
+f x: Int = x
+f x: Ratio = x
+```
diff --git a/doc/zh_CN/syntax/type/advanced/phantom.md b/doc/zh_CN/syntax/type/advanced/phantom.md
new file mode 100644
index 00000000..df02c8f2
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/phantom.md
@@ -0,0 +1,58 @@
+# 幻影(phantom)类
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/phantom.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+幻像类型是标记特征,其存在仅用于向编译器提供注释。
+作为幻像类型的一种用法,让我们看一下列表的结构。
+
+```python
+Nil = Class()
+List T, 0 = Inherit Nil
+List T, N: Nat = Class {head = T; rest = List(T, N-1)}
+```
+
+此代码导致错误。
+
+```python
+3 | List T, 0 = Inherit Nil
+ ^^^
+类型构造错误:由于Nil没有参数T,所以无法用Nil构造List(T, 0)
+提示:使用 'Phantom' 特质消耗 T
+```
+
+此错误是在使用 `List(_, 0).new Nil.new()` 时无法推断 `T` 的抱怨。
+在这种情况下,无论 `T` 类型是什么,它都必须在右侧使用。 大小为零的类型(例如长度为零的元组)很方便,因为它没有运行时开销。
+```python
+Nil T = Class((T; 0))
+List T, 0 = Inherit Nil T
+List T, N: Nat = Class {head = T; rest = List(T, N-1)}
+```
+
+此代码通过编译。 但是理解意图有点棘手,除非类型参数是类型,否则不能使用它。
+
+在这种情况下,幻影类型正是您所需要的。 幻像类型是大小为 0 的广义类型。
+
+```python
+Nil T = Class(Impl := Phantom T)
+List T, 0 = Inherit Nil T
+List T, N: Nat = Class {head = T; rest = List(T, N-1)}
+
+nil = Nil(Int).new()
+assert nil.__size__ == 0
+```
+
+`Phantom` 拥有`T` 类型。 但实际上 `Phantom T` 类型的大小是 0 并且不包含 `T` 类型的对象。
+
+此外,`Phantom` 可以使用除其类型之外的任意类型参数。 在下面的示例中,`Phantom` 包含一个名为 `State` 的类型参数,它是 `Str` 的子类型对象。
+同样,`State` 是一个假的类型变量,不会出现在对象的实体中。
+
+```python
+VM! State: {"stopped", "running"}! = Class(... State)
+VM!("stopped").
+ start ref! self("stopped" ~> "running") =
+ self.do_something!()
+ self::set_phantom!("running"))
+```
+
+`state` 是通过 `update_phantom!` 或 `set_phantom!` 方法更新的。
+这是标准补丁为`Phantom!`(`Phantom`的变量版本)提供的方法,其用法与变量`update!`和`set!`相同。
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced/projection.md b/doc/zh_CN/syntax/type/advanced/projection.md
new file mode 100644
index 00000000..ec90aa23
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/projection.md
@@ -0,0 +1,26 @@
+# 投影类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/projection.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+投影类型表示如下代码中的“Self.AddO”等类型。
+
+```python
+Add R = Trait {
+ . `_+_` = Self, R -> Self.AddO
+ .AddO = Type
+}
+
+AddForInt = Patch(Int, Impl := Add Int)
+AddForInt.
+ AddO = Int
+```
+
+类型“Add(R)”可以说是定义了与某个对象的加法的类型。 由于方法应该是一个类型属性,`+` 类型声明应该写在缩进下面。
+`Add` 类型的场景是声明 `.AddO = Type`,而 `.AddO` 类型的实体是一个投影类型,由一个作为 ` 子类型的类型持有 添加`。 例如,`Int.AddO = Int`、`Odd.AddO = Even`。
+
+```python
+assert Int < Add
+assert Int.AddO == Int
+assert Odd < Add
+assert Odd.AddO == Even
+```
diff --git a/doc/zh_CN/syntax/type/advanced/quantified_dependent.md b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md
new file mode 100644
index 00000000..69a963d2
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md
@@ -0,0 +1,29 @@
+# 量化依赖类型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/quantified_dependent.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Erg 有量化和依赖类型。 那么很自然地,就可以创建一个将两者结合起来的类型。 那是量化的依赖类型。
+
+```python
+NonNullStr = |N: Nat| StrWithLen N | N ! = 0 # 同 {S | N: Nat; S: StrWithLen N; N ! = 0}
+NonEmptyArray = |N: Nat| [_; N | N > 0] # 同 {A | N: Nat; A: Array(_, N); N > 0}
+```
+
+量化依赖类型的标准形式是“K(A, ... | Pred)”。 `K` 是类型构造函数,`A, B` 是类型参数,`Pred` 是条件表达式。
+
+作为左值的量化依赖类型只能在与原始类型相同的模块中定义方法。
+
+```python
+K A: Nat = Class ...
+K(A).
+ ...
+K(A | A >= 1).
+ method ref! self(A ~> A+1) = ...
+```
+
+作为右值的量化依赖类型需要在类型变量列表 (`||`) 中声明要使用的类型变量。
+
+```python
+# T 是具体类型
+a: |N: Nat| [T; N | N > 1]
+```
diff --git a/doc/zh_CN/syntax/type/advanced/shared.md b/doc/zh_CN/syntax/type/advanced/shared.md
new file mode 100644
index 00000000..41678db2
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/shared.md
@@ -0,0 +1,74 @@
+# 共享参考
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/shared.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+共享引用是必须小心处理的语言特性之一。
+例如,在 TypeScript 中,以下代码将通过类型检查。
+
+```typescript
+class NormalMember {}
+class VIPMember extends NormalMember {}
+
+let vip_area: VIPMember[] = []
+let normal_area: NormalMember[] = vip_area
+
+normal_area.push(new NormalMember())
+console.log(vip_area) # [NormalMember]
+```
+
+一个 NormalMember 已进入 vip_area。 这是一个明显的错误,但是出了什么问题?
+原因是共享引用 [denatured](./variance.md)。 `normal_area` 是通过复制 `vip_area` 来创建的,但是这样做的时候类型已经改变了。
+但是 `VIPMember` 继承自 `NormalMember`,所以 `VIPMember[] <: NormalMember[]`,这不是问题。
+关系 `VIPMember[] <: NormalMember[]` 适用于不可变对象。 但是,如果您执行上述破坏性操作,则会出现故障。
+
+在 Erg 中,由于所有权系统,此类代码会被回放。
+
+```python
+NormalMember = Class()
+VIPMember = Class()
+
+vip_area = [].into [VIPMember; !_]
+normal_area: [NormalMember; !_] = vip_area
+
+normal_area.push!(NormalMember.new())
+log vip_area # 所有权错误:`vip_room` 已移至 `normal_room`
+```
+
+然而,一个对象只属于一个地方可能会很不方便。
+出于这个原因,Erg 有一个类型 `SharedCell!T!`,它代表一个共享状态。
+
+```python
+$p1 = SharedCell!.new(!1)
+$p2 = $p1.mirror!()
+$p3 = SharedCell!.new(!1)
+# 如果$p1 == $p2,比较内容类型Int!
+assert $p1 == $p2
+assert $p1 == $p3
+# 检查 $p1 和 $p2 是否用 `.addr!` 指向同一个东西。
+assert $p1.addr!() == $p2.addr!()
+assert $p1.addr!() != $p3.addr!()
+$p1.add! 1
+assert $p1 == 2
+assert $p2 == 2
+assert $p3 == 1
+```
+
+`SharedCell!` 类型的对象必须以`$` 为前缀。 此外,就其性质而言,它们不可能是常数。
+
+`SharedCell! T!` 类型也是 `T!` 的子类型,可以调用 `T!` 类型的方法。 `SharedCell!T!` 类型特有的唯一方法是 `.addr!`、`.mirror!` 和 `.try_take`。
+
+一个重要的事实是`SharedCell! T!` 是非变体的,即没有为不同类型的参数定义包含。
+
+```python
+$vip_area = SharedCell!.new([].into [VIPMember; !_])
+$normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() #类型错误:预期 SharedCell!([NormalMember;!_]),但得到 SharedCell!([VIPMember;!_])
+# 提示:SharedCell!(T) 是非变体的,这意味着它不能有超类型或子类型。
+```
+
+但是,下面的代码没有问题。 在最后一行,它是 `VIPMember` 参数已被类型转换
+
+```python
+$normal_area = SharedCell!.new([].into [NormalMember; !_])
+$normal_area.push!(NormalMember.new()) # OK
+$normal_area.push!(VIPMember.new()) # OK
+```
diff --git a/doc/zh_CN/syntax/type/advanced/special.md b/doc/zh_CN/syntax/type/advanced/special.md
new file mode 100644
index 00000000..a2c86f07
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/special.md
@@ -0,0 +1,53 @@
+# 特殊类型(Self、Super)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`Self` 代表它自己的类型。 您可以将其用作别名,但请注意派生类型的含义会发生变化(指的是自己的类型)。
+
+```python
+@Inheritable
+C = Class()
+C.
+ new_self() = Self. new()
+ new_c() = C.new()
+D = Inherit C
+
+classof D. new_self() # D
+classof D. new_c() # C
+```
+
+`Super` 表示基类的类型。方法本身引用基类,但实例使用自己的类型。
+
+```python
+@Inheritable
+C = Class()
+
+D = Inherit(C)
+D.
+ new_super() = Super.new()
+ new_c() = C.new()
+
+classof D. new_super() # D
+classof D. new_c() # C
+```
+
+## 特殊类型变量
+
+`Self` 和 `Super` 可以用作结构化类型和特征中的类型变量。 这指的是作为该类型子类型的类。 也就是说,`T` 类型中的`Self` 表示`Self <: T`。
+
+```python
+Add R = Trait {
+ .AddO = Type
+ .`_+_`: Self, R -> Self.AddO
+}
+ClosedAdd = Subsume Add(Self)
+
+ClosedAddForInt = Patch(Int, Impl := ClosedAdd)
+ClosedAddForInt.
+ AddO = Int
+
+assert 1 in Add(Int, Int)
+assert 1 in ClosedAdd
+assert Int < Add(Int, Int)
+assert Int < ClosedAdd
+```
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced/typeof.md b/doc/zh_CN/syntax/type/advanced/typeof.md
new file mode 100644
index 00000000..a59fc6e6
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/typeof.md
@@ -0,0 +1,67 @@
+# Typeof, classof
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/typeof.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`Typeof` 是一个可以窥探 Erg 类型推断系统的函数,它的行为很复杂
+
+```python
+assert Typeof(1) == {I: Int | I == 1}
+i: 1..3 or 5..10 = ...
+assert Typeof(i) == {I: Int | (I >= 1 and I <= 3) or (I >= 5 and I <= 10)}
+
+C = Class {i = Int}
+I = C. new {i = 1}
+assert Typeof(I) == {X: C | X == I}
+J: C = ...
+assert Typeof(J) == {i = Int}
+
+assert {X: C | X == I} < C and C <= {i = Int}
+```
+
+`Typeof` 函数返回派生类型,而不是对象的类。
+因此,例如 `C = Class T` 类的`I: C`,`Typeof(I) == T`。
+值类没有对应的记录类型。 为了解决这个问题,值类应该是具有 `__valueclass_tag__` 属性的记录类型。
+请注意,您不能访问此属性,也不能在用户定义的类型上定义 `__valueclass_tag__` 属性。
+
+```python
+i: Int = ...
+assert Typeof(i) == {__valueclass_tag__ = Phantom Int}
+s: Str = ...
+assert Typeof(s) == {__valueclass_tag__ = Phantom Str}
+```
+
+`Typeof` 仅输出结构化类型。 我解释说结构化类型包括属性类型、筛类型和(真正的)代数类型。
+这些是独立的类型(存在推理优先级),不会发生推理冲突。
+属性类型和代数类型可以跨越多个类,而筛类型是单个类的子类型。
+Erg 尽可能将对象类型推断为筛类型,如果不可能,则将筛基类扩展为结构化类型(见下文)。
+
+## 结构化的
+
+所有类都可以转换为派生类型。 这称为 __结构化__。 类的结构化类型可以通过 `Structure` 函数获得。
+如果一个类是用`C = Class T`定义的(所有类都以这种形式定义),那么`Structure(C) == T`。
+
+```python
+C = Class {i = Int}
+assert Structure(C) == {i = Int}
+D = Inherit C
+assert Structure(D) == {i = Int}
+Nat = Class {I: Int | I >= 0}
+assert Structure(Nat) == {I: Int | I >= 0}
+Option T = Class (T or NoneType)
+assert Structure(Option Int) == Or(Int, NoneType)
+assert Structure(Option) # 类型错误:只能构造单态类型
+# 你实际上不能用 __valueclass_tag__ 定义一条记录,但在概念上
+assert Structure(Int) == {__valueclass_tag__ = Phantom Int}
+assert Structure(Str) == {__valueclass_tag__ = Phantom Str}
+assert Structure((Nat, Nat)) == {__valueclass_tag__ = Phantom(Tuple(Nat, Nat))}
+assert Structure(Nat -> Nat) == {__valueclass_tag__ = Phantom(Func(Nat, Nat))}
+# 标记类也是带有 __valueclass_tag__ 的记录类型
+M = Inherit Marker
+assert Structure(M) == {__valueclass_tag__ = Phantom M}
+D = Inherit(C and M)
+assert Structure(D) == {i = Int; __valueclass_tag__ = Phantom M}
+E = Inherit(Int and M)
+assert Structure(E) == {__valueclass_tag__ = Phantom(And(Int, M))}
+F = Inherit(E not M)
+assert Structure(F) == {__valueclass_tag__ = Phantom Int}
+```
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced/variance.md b/doc/zh_CN/syntax/type/advanced/variance.md
new file mode 100644
index 00000000..5bf2d16c
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/variance.md
@@ -0,0 +1,144 @@
+# 变化
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/variance.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg 可以对多态类型进行子类型化,但有一些注意事项。
+
+首先,考虑普通多态类型的包含关系。一般来说,有一个容器`K`和它分配的类型`A,B`,当`A < B`时,`K A < K B`。
+例如,`Option Int < Option Object`。因此,在`Option Object`中定义的方法也可以在`Option Int`中使用。
+
+考虑典型的多态类型 `Array!(T)`。
+请注意,这一次不是 `Array!(T, N)` 因为我们不关心元素的数量。
+现在,`Array!(T)` 类型具有称为 `.push!` 和 `.pop!` 的方法,分别表示添加和删除元素。这是类型:
+
+`Array.push!: Self(T).(T) => NoneType`
+`Array.pop!: Self(T).() => T`
+
+可以直观地理解:
+
+* `Array!(Object).push!(s)` is OK when `s: Str` (just upcast `Str` to `Object`)
+* When `o: Object`, `Array!(Str).push!(o)` is NG
+* `Array!(Object).pop!().into(Str)` is NG
+* `Array!(Str).pop!().into(Object)` is OK
+
+就类型系统而言,这是
+
+* `(Self(Object).(Object) => NoneType) < (Self(Str).(Str) => NoneType)`
+* `(Self(Str).() => Str) < (Self(Object).() => Object)`
+方法
+
+前者可能看起来很奇怪。即使是 `Str < Object`,包含关系在将其作为参数的函数中也是相反的。
+在类型论中,这种关系(`.push!` 的类型关系)称为逆变,反之,`.pop!` 的类型关系称为协变。
+换句话说,函数类型就其参数类型而言是逆变的,而就其返回类型而言是协变的。
+这听起来很复杂,但正如我们之前看到的,如果将其应用于实际示例,这是一个合理的规则。
+如果您仍然不明白,请考虑以下内容。
+
+Erg 的设计原则之一是“大输入类型,小输出类型”。这正是函数可变性的情况。
+看上面的规则,输入类型越大,整体类型越小。
+这是因为通用函数明显比专用函数少。
+而且输出类型越小,整体越小。
+
+这样一来,上面的策略就相当于说“尽量减少函数的类型”。
+
+## 不变性
+
+Erg 有另一个修改。它是不变的。
+这是对 `SharedCell! T!`等内置类型的修改。这意味着对于两种类型 `T!, U!` 其中 `T! != U!`,在 `SharedCell! T!` 和 `SharedCell!意思是
+这是因为`SharedCell! T!` 是共享参考。有关详细信息,请参阅 [共享参考](shared.md)。
+
+## 变异的泛型类型
+
+通用类型变量可以指定其上限和下限。
+
+```python
+|A <: T| K(A)
+|B :> T| K(B)
+```
+
+在类型变量列表中,执行类型变量的__variant说明__。 在上述变体规范中,类型变量“A”被声明为“T”类型的任何子类,“B”类型被声明为“T”类型的任何超类。
+在这种情况下,`T` 也称为 `A` 的上部类型和 `B` 的下部类型。
+
+突变规范也可以重叠。
+
+```python
+# U U}
+```
+
+这是使用变量规范的代码示例:
+
+```python
+show|S <: Show| s: S = log s
+
+Nil T = Class(Impl = Phantom T)
+Cons T = Class(Nil T or List T)
+List T = Class {head = T; rest = Cons T}
+List(T).
+ push|U <: T|(self, x: U): List T = Self. new {head = x; rest = self}
+ upcast(self, U :> T): List U = self
+```
+
+## 更改规范
+
+`List T` 的例子很棘手,所以让我们更详细一点。
+要理解上面的代码,你需要了解多态类型退化。 [this section](./variance.md) 中详细讨论了方差,但现在我们需要三个事实:
+
+* 普通的多态类型,例如`List T`,与`T`是协变的(`List U > List T` when `U > T`)
+* 函数 `T -> U` 对于参数类型 `T` 是逆变的(`(S -> U) < (T -> U)` when `S > T`)
+* 函数 `T -> U` 与返回类型 `U` 是协变的(`(T -> U) > (T -> S)` 当 `U > S` 时)
+
+例如,`List Int` 可以向上转换为 `List Object`,而 `Obj -> Obj` 可以向上转换为 `Int -> Obj`。
+
+现在让我们考虑如果我们省略方法的变量说明会发生什么。
+
+```python
+...
+List T = Class {head = T; rest = Cons T}
+List(T).
+ # 如果 T > U,列表 T 可以被推入 U
+ push|U|(self, x: U): List T = Self. new {head = x; rest = self}
+ # List T 可以是 List U 如果 T < U
+ upcast(self, U): List U = self
+```
+
+即使在这种情况下,Erg 编译器也能很好地推断 `U` 的上下类型。
+但是请注意,Erg 编译器不理解方法的语义。编译器只是根据变量和类型变量的使用方式机械地推断和派生类型关系。
+
+正如评论中所写,放在`List T`的`head`中的`U`类型是`T`的子类(`T:Int`,例如`Nat`)。也就是说,它被推断为 `U <: T`。此约束将 `.push{U}` upcast `(List(T), U) -> List(T) 的参数类型更改为 (List(T), T) -> List(T)`(例如 disallow `列表(整数).push{对象}`)。但是请注意,`U <: T` 约束不会改变函数的类型包含。 `(List(Int), Object) -> List(Int) to (List(Int), Int) -> List(Int)` 的事实并没有改变,只是在 `.push` 方法中表示强制转换无法执行。
+类似地,从 `List T` 到 `List U` 的转换可能会受到约束 `U :> T` 的约束,因此可以推断出变体规范。此约束将 `.upcast(U)` 的返回类型更改为向上转换 `List(T) -> List(T) 到 List(T) -> List(T)`(例如 `List(Object) .upcast(Int )`) 被禁止。
+
+现在让我们看看如果我们允许这种向上转换会发生什么。
+让我们反转变性名称。
+
+```python
+...
+List T = Class {head = T; rest = Cons T}
+List(T).
+ push|U :> T|(self, x: U): List T = Self. new {head = x; rest = self}
+ upcast(self, U :> T): List U = self
+# 类型警告:`.push` 中的 `U` 不能接受除 `U == T` 之外的任何内容。 将“U”替换为“T”。
+# 类型警告:`.upcast` 中的 `U` 不能接受除 `U == T` 之外的任何内容。 将“U”替换为“T”。
+```
+
+只有当 `U == T` 时,约束 `U <: T` 和修改规范`U :> T` 才满足。 所以这个称号没有多大意义。
+只有“向上转换使得 `U == T`” = “向上转换不会改变 `U` 的位置”实际上是允许的。
+
+##附录:用户定义类型的修改
+
+默认情况下,用户定义类型的突变是不可变的。 但是,您也可以使用 `Inputs/Outputs` 标记特征指定可变性。
+如果您指定 `Inputs(T)`,则类型相对于 `T` 是逆变的。
+如果您指定 `Outputs(T)`,则类型相对于 `T` 是协变的。
+
+```python
+K T = Class(...)
+assert not K(Str) <= K(Object)
+assert not K(Str) >= K(Object)
+
+InputStream T = Class ..., Impl := Inputs(T)
+# 接受Objects的流也可以认为接受Strs
+assert InputStream(Str) > InputStream(Object)
+
+OutputStream T = Class ..., Impl := Outputs(T)
+# 输出Str的流也可以认为输出Object
+assert OutputStream(Str) < OutputStream(Object)
+```
\ No newline at end of file
diff --git a/doc/zh_CN/syntax/type/advanced/widening.md b/doc/zh_CN/syntax/type/advanced/widening.md
new file mode 100644
index 00000000..8a542a21
--- /dev/null
+++ b/doc/zh_CN/syntax/type/advanced/widening.md
@@ -0,0 +1,94 @@
+# 类型加宽
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/widening.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+例如,定义多相关系数如下。
+
+```python
+ids|T|(x: T, y: T) = x, y
+```
+
+分配同一类的一对实例并没有错。
+当您分配另一个具有包含关系的类的实例对时,它会向上转换为较大的类并成为相同的类型。
+另外,很容易理解,如果分配了另一个不在包含关系中的类,就会发生错误。
+
+```python
+assert ids(1, 2) == (1, 2)
+assert ids(1, 2.0) == (1.0, 2.0)
+ids(1, "a") #TypeError
+```
+
+现在,具有不同派生类型的类型呢?
+
+```python
+i: Int or Str
+j: Int or NoneType
+ids(i, j) # ?
+```
+
+在解释这一点之前,我们必须关注 Erg 的类型系统实际上并不关注(运行时)类这一事实。
+
+```python
+1: {__valueclass_tag__ = Phantom Int}
+2: {__valueclass_tag__ = Phantom Int}
+2.0: {__valueclass_tag__ = Phantom Ratio}
+"a": {__valueclass_tag__ = Phantom Str}
+ids(1, 2): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Int} == {__valueclass_tag__ = Phantom Int}
+ids(1, 2.0): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Ratio} == {__valueclass_tag__ = Phantom Ratio} # Int < Ratio
+ids(1, "a"): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Str} == Never # 类型错误
+```
+
+我看不到该类,因为它可能无法准确看到,因为在 Erg 中,对象的类属于运行时信息。
+例如,一个`Int`或Str`类型的对象的类是`Int`或`Str`,但你只有通过执行才能知道它是哪一个。
+当然,`Int` 类型的对象的类被定义为 `Int`,但是在这种情况下,从类型系统中可见的是 `Int` 的结构类型 `{__valueclass_tag__ = Int}`。
+
+现在让我们回到另一个结构化类型示例。 总之,上述代码将导致类型错误,因为类型不匹配。
+但是,如果您使用类型注释进行类型扩展,编译将通过。
+
+```python
+i: Int or Str
+j: Int or NoneType
+ids(i, j) # 类型错误:i 和 j 的类型不匹配
+# 提示:尝试扩大类型(例如 ids)
+ids(i, j) # OK
+```
+
+`A 和 B` 有以下可能性。
+
+* `A and B == A`:当`A <: B`或`A == B`时。
+* `A and B == B`:当 `A :> B` 或 `A == B` 时。
+* `A and B == {}`:当 `!(A :> B)` 和 `!(A <: B)` 时。
+
+`A 或 B` 具有以下可能性。
+
+* `A 或 B == A`:当`A :> B` 或`A == B` 时。
+* `A or B == B`:当`A <: B`或`A == B`时。
+* `A 或 B` 是不可约的(独立类型):如果 `!(A :> B)` 和 `!(A <: B)`。
+
+## 子程序定义中的类型扩展
+
+如果返回类型不匹配,Erg 默认会出错。
+
+```python
+parse_to_int s: Str =
+ if not s.is_numeric():
+ do parse_to_int::return error("not numeric")
+... # 返回 Int 对象
+# 类型错误:返回值类型不匹配
+# 3 | 做 parse_to_int::return error("not numeric")
+# └─ Error
+# 4 | ...
+# └ Int
+```
+
+为了解决这个问题,需要将返回类型显式指定为 Or 类型
+
+```python
+parse_to_int(s: Str): Int or Error =
+ if not s.is_numeric():
+ do parse_to_int::return error("not numeric")
+ ... # 返回 Int 对象
+```
+
+这是设计使然,这样您就不会无意中将子例程的返回类型与另一种类型混合。
+但是,如果返回值类型选项是具有包含关系的类型,例如 `Int` 或 `Nat`,它将与较大的对齐。
\ No newline at end of file
diff --git a/doc/zh_CN/tips.md b/doc/zh_CN/tips.md
new file mode 100644
index 00000000..e2e74133
--- /dev/null
+++ b/doc/zh_CN/tips.md
@@ -0,0 +1,137 @@
+# 提示
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tips.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 想要更改显示错误的语言
+
+请为您的语言下载 Erg。
+但是,外部库可能不支持多种语言。
+
+## 只想更改记录的某些属性
+
+```python
+record: {.name = Str; .age = Nat; .height = CentiMeter}
+{height; rest; ...} = record
+mut_record = {.height = !height; ...rest}
+```
+
+## 想要隐藏变量
+
+使用 Erg 无法在相同范围内进行遮蔽。 但是,如果范围发生变化,您可以重新定义它们(这是一种称为实例块的语法)。
+
+````python
+## 获取一个 T!-type 对象,最后将它作为 T 类型赋值给一个变量
+x: T =
+ x: T! = foo()
+ x.bar!()
+ x.freeze()
+````
+
+## 想以某种方式重用最终类(不可继承的类)
+
+您可以创建一个包装类。 这就是所谓的构图模式。
+
+```python
+FinalWrapper = Class {inner = FinalClass}
+FinalWrapper.
+ method self =
+ self::inner.method()
+ ...
+```
+
+## 想使用不是字符串的枚举类型
+
+可以定义其他语言中常见的传统枚举类型(代数数据类型)如下
+如果您实现“单例”,则类和实例是相同的。
+此外,如果您使用 `Enum`,则选择的类型会自动定义为重定向属性。
+
+```python
+Ok = Class Impl := Singleton
+Err = Class Impl := Singleton
+ErrWithInfo = Inherit {info = Str}
+Status = Enum Ok, Err, ErrWithInfo
+stat: Status = Status.cons(ErrWithInfo) {info = "error caused by ..."}
+match! stat:
+ Status.Ok -> ...
+ Status.Err -> ...
+ Status.ErrWithInfo::{info} -> ...
+```
+
+```python
+Status = Enum Ok, Err, ErrWithInfo
+# 相当于
+Status = Class Ok or Err or ErrWithInfo
+Status.
+ Ok = Ok
+ Err = Err
+ ErrWithInfo = ErrWithInfo
+```
+
+## 我想在1开头枚举
+
+方法一:
+
+```python
+arr = [...]
+for! arr.iter().enumerate(start: 1), i =>
+ ...
+```
+
+method 2:
+
+```python
+arr = [...]
+for! arr.iter().zip(1...) , i =>
+ ...
+```
+
+## 想要测试一个(白盒)非公共 API
+
+`foo.er` 中的私有 API 可在 `foo.test.er` 模块中特别访问。
+`foo.test.er` 模块无法导入,因此它保持隐藏状态。
+
+```python
+# foo.er
+private x = ...
+```
+
+```python
+# foo.test.er
+foo = import "foo"
+
+@Test
+'testing private' x =
+ ...
+ y = foo::private x
+ ...
+```
+
+## 想定义一个从外部只读的(变量)属性
+
+您可以将属性设为私有并定义一个 getter。
+
+```python
+C = Class {v = Int!}
+C::
+ inc_v!(ref! self) = self::v.inc!()
+ ...
+C.
+ get_v(ref self): Int = self::v.freeze()
+ ...
+```
+
+## 希望在类型系统上识别参数名称
+
+您可以按记录接收参数。
+
+```python
+Point = {x = Int; y = Int}
+
+norm: Point -> Int
+norm({x: Int; y: Int}): Int = x**2 + y**2
+assert norm({x = 1; y = 2}) == norm({y = 2; x = 1})
+```
+
+## 想要停止警告
+
+Erg 中没有停止警告的选项(这是设计使然)。 请重写你的代码。
diff --git a/doc/zh_CN/tools/build.md b/doc/zh_CN/tools/build.md
new file mode 100644
index 00000000..c80f030e
--- /dev/null
+++ b/doc/zh_CN/tools/build.md
@@ -0,0 +1,16 @@
+# 构建子命令
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/build.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+build 子命令构建包。
+默认构建中执行的步骤如下:
+
+1. 检查注释/文档中的代码(doc 下的 md 文件)
+2. 编译打包所需的代码。
+3. 对于应用程序包,生成批处理文件或相当于命令的shell脚本。
+4. 运行测试。
+
+构建完成后的交付物输出到以下目录。
+
+* 在调试构建期间:build/debug
+* 对于发布构建:build/release
\ No newline at end of file
diff --git a/doc/zh_CN/tools/env.md b/doc/zh_CN/tools/env.md
new file mode 100644
index 00000000..6bcfc01f
--- /dev/null
+++ b/doc/zh_CN/tools/env.md
@@ -0,0 +1,9 @@
+# 环境子命令
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+env 子命令指定 erg 执行环境。
+使用 `erg env new [env name]` 创建一个新的执行环境。 将打开一个交互式工具,当您指定 erg 版本时,将安装该版本的 erg(如果已存在,将使用它),您将能够将其用作新环境。
+您可以使用 `erg env switch [env name]` 切换环境。
+可以使用 `erg env edit` 编辑创建的环境以预安装软件包并指定其他语言的依赖项。
+该命令最大的特点是`erg env export`可以将重现环境的信息输出为`[env name].env.er`文件。 这使您可以立即开始在与其他人相同的环境中进行开发。 此外,`erg env publish` 可以像包一样发布环境。
\ No newline at end of file
diff --git a/doc/zh_CN/tools/fmt.md b/doc/zh_CN/tools/fmt.md
new file mode 100644
index 00000000..69451162
--- /dev/null
+++ b/doc/zh_CN/tools/fmt.md
@@ -0,0 +1,8 @@
+# fmt
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/fmt.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+可以使用 fmt 子命令来完成代码格式化。
+常用的标志有:
+
+* 显式类型:在省略类型说明的情况下自动完成。
\ No newline at end of file
diff --git a/doc/zh_CN/tools/index.md b/doc/zh_CN/tools/index.md
new file mode 100644
index 00000000..f08300dc
--- /dev/null
+++ b/doc/zh_CN/tools/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_CN/tools/install.md b/doc/zh_CN/tools/install.md
new file mode 100644
index 00000000..97ac813b
--- /dev/null
+++ b/doc/zh_CN/tools/install.md
@@ -0,0 +1,12 @@
+# 安装子命令
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/install.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+您可以使用 install 安装在注册表站点上注册的软件包。
+基本用法与cargo等包管理器相同。
+
+## 便利功能
+
+* 如果有同名的包名,且下载次数超过该包名的10倍以上,会提示可能输入错误。 这可以防止拼写错误。
+* 如果包很大(超过 50MB),请显示大小并建议您是否真的要安装它。
+* 如果包装重复,建议使用替代包装。
\ No newline at end of file
diff --git a/doc/zh_CN/tools/pack.md b/doc/zh_CN/tools/pack.md
new file mode 100644
index 00000000..09e59f2c
--- /dev/null
+++ b/doc/zh_CN/tools/pack.md
@@ -0,0 +1,102 @@
+# 包管理器
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/pack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg 标配有一个包管理器,您可以使用 `pack` 子命令调用它。
+以下是典型的选项。
+
+* `erg pack init`:将当前目录初始化为一个包。会生成一个 `package.er` 文件和一个 `src` 目录。指定 `app` 将产生一个可执行包,`lib` 将产生一个库包,而 `hybrid` 将产生两个包。如果指定了 `--license`,将自动放置许可文件。
+* `erg pack build`:构建一个包。使用 `--release` 可以运行和优化测试。工件放置在 `build/debug` 或 `build/release` 中。
+* `erg pack install`:安装一个包。在库的情况下,`src` 被放置在 `.erg/lib` 中,而应用程序作为 shell 脚本被放置在 `.erg/app` 中。使用 `--release` 进行优化。
+* `erg pack run`:构建包并运行应用程序(仅限应用程序包)。
+* `erg pack clean`:删除构建目录的内容。
+* `erg pack test`:运行包测试。有关详细信息,请参阅 [test.md](./test.md)。
+* `erg pack publish`:发布/发布包。您将需要一个 GitHub 帐户和公钥。
+
+本文档解释了如何管理您自己的包。
+如果要安装或搜索外部包,请参阅 [install.md](./install.md)。
+另请参阅 [package_system.md](../syntax/33_package_system.md) 了解 Erg 包系统。
+
+## 整个包的标准目录结构(对于应用程序包)
+
+```console
+/package # package root directory
+ /build # Directory to store build results
+ /debug # Artifacts during debug build
+ /release # Artifacts of release build
+ /doc # Documents (in addition, by dividing into subdirectories such as `en`, `ja` etc., it is possible to correspond to each language)
+ /src # source code
+ /main.er # file that defines the main function
+ /tests # Directory to store (black box) test files
+ /package.er # file that defines package settings
+```
+
+## package.er
+
+`erg pack init` 将生成如下所示的 `package.er` 文件。 `package.er` 描述了包的配置。
+下面是一个`package.er`的例子。
+
+```python
+name = "example" # package 名称
+author = "John Smith" # package 作者名称
+version="0.1.0"
+description = "An awesome package"
+categories = ["cli"] # package 类别
+type = "app" # "app" 或者 "lib"
+license = "" # 例如"MIT", "APACHE-2.0", "MIT OR Apache-2.0"
+pre_build = "" # 构建前要执行的脚本文件名
+post_build = "" # 构建后要执行的脚本文件名
+dependencies = {
+ # 如果不指定版本,则选择最新的
+ # 如果省略版本说明,包管理器会自动将上次成功构建的版本添加到注释中
+ foo = pack("foo") # [INFO] 最后成功构建的版本:1.2.1
+ # 包可以重命名
+ bar1 = pack("bar", "1.*.*") # [INFO] 最后成功构建的版本:1.2.0
+ bar2 = pack("bar", "2.*.*") # [INFO] 最后成功构建的版本:2.0.0
+ baz = pack("baz", "1.1.0")
+}
+deprecated=False
+successors = [] # 替代包(当一个包被弃用时)
+```
+
+## 语义版本控制
+
+Erg 包是基于 [语义版本控制](https://semver.org/lang/en/) 进行版本控制的。
+语义版本控制大致以“x.y.z”格式指定(x、y、z 是大于或等于 0 的整数)。
+每个数字的含义如下。
+
+* x:主要版本(更新破坏兼容性时增加 1)
+* y:次要版本(执行兼容更新时增加1(API添加,弃用等),错误修复等由补丁版本升级处理)
+* z:补丁版本(当进行小的更改以修复错误或保持兼容性时增加1,破坏兼容性的严重修复由主要版本升级处理)
+
+但是,默认情况下,版本 `0.*.*` 中的更改始终是不兼容的。如果要在保持兼容性的同时升级,请在其后指定 `-compatible`(Erg 自己的规则)。例如,如果要在保持与 0.2.1 兼容的同时添加功能,即要升级到 0.3.0,则指定 0.3.0-compatible。如果您已修复错误,还请指定“0.2.2-compatible”。
+该版本将被视为与以前的版本兼容。
+即使您想将 `0.*.*` 升级到 `1.0.0`,这仍然有效。也就是说,`1.0.0-compatible` 与之前的版本 `0.y.z` 兼容。
+
+生成锁文件时,语义版本控制非常重要。锁定文件是为保持依赖项兼容而生成的文件,因此除非明确更新,否则较新版本的依赖项依赖于较旧的包。
+当多人开发具有依赖包的包时,锁定文件很有用。它还通过允许依赖于它们的包在兼容的情况下重用包来节省本地存储。
+
+Erg 的包管理器严格执行这些规则,并将拒绝违反这些规则的包更新。
+Erg 包管理器与版本控制系统(例如 git)一起使用,以检测代码差异并在发布包时验证版本控制的正确性。
+具体来说,包管理器会查看 API 的类型。如果类型是旧版本的子类型,则认为更改是兼容的(请注意,这不是完整的验证;类型兼容但语义上不兼容的重大更改是可能的,这是开发人员的工作来确定这一点)。
+
+此外,由于整个包存储库都在注册表中注册,即使是开发人员也无法在不通过包管理器的情况下更新包。
+此外,包可以被弃用但不能被删除。
+
+### 附录:语义版本控制问题和对策
+
+语义版本控制存在(至少)两个已知问题。
+首先,语义版本控制可能过于严格。
+使用语义版本控制,单个不兼容的 API 更改会增加整个包的主要版本。
+发生这种情况时,诸如“我想尝试一个新的 API,但我必须处理另一个不兼容的 API 更改,所以我不会升级”之类的事情。
+其次,语义版本控制可以承诺太多。
+如上一节所述,对 API 的“兼容更改”在理论上是不可证明的。如果您指定要使用版本为 `1.0.1` 的包,则可以在语义版本控制方面使用 `1.0.1` 和 `2.0.0` 之间的任何包(`1.0.0` 不能被使用,因为错误已被修复),但由于包开发人员无意使用 API,构建可能不会成功。
+
+Erg 通过允许同时使用不同版本的包(通过重命名)解决了这个问题。这使得在部分引入 ver2 API 的同时继续使用 ver1 API 成为可能。
+此外,虽然这不是一个非常理想的状态,但如果只能使用 API 的某个次要版本而没有错误,则可以不理会它并继续前进到下一个版本。
+
+## 发布
+
+可以使用 `publish` 子命令发布包。发布需要 GitHub 帐户。
+默认情况下,包使用 `(owner_name)/(package_name)` 注册。如果满足一定条件(下载次数、维护频率等),可以申请注册一个省略所有者名称的别名。
+请注意,包名称不区分大小写,并且不区分诸如 `_` 和 `-` 之类的分隔符。
\ No newline at end of file
diff --git a/doc/zh_CN/tools/repl.md b/doc/zh_CN/tools/repl.md
new file mode 100644
index 00000000..954841b2
--- /dev/null
+++ b/doc/zh_CN/tools/repl.md
@@ -0,0 +1,17 @@
+# REPL
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/repl.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+运行不带参数的 `erg` 命令会调用 REPL。 它也可以用 `repl` 子命令调用。
+此外,您可以指定以下标志:
+
+* typed:显示对象及其类型。
+
+```console
+$ erg repl --typed
+Erg interpreter ... (tags/?:, ...) on ...
+>>> 1
+1: {1}
+>>> id x = x
+id = : |T: Type| T -> T
+```
\ No newline at end of file
diff --git a/doc/zh_CN/tools/test.md b/doc/zh_CN/tools/test.md
new file mode 100644
index 00000000..93abac45
--- /dev/null
+++ b/doc/zh_CN/tools/test.md
@@ -0,0 +1,47 @@
+# 测试子命令
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/test.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+erg 命令有一个名为 test 的子命令,它支持测试的实现和执行。
+
+## 测试装饰器 (@Test)
+
+Erg 使用 `erg test` 命令测试包中 `tests` 目录或 `*.test.er` 文件中的 `@Test` 子例程。
+`tests` 子例程负责黑盒测试(不测试私有函数),`*.test.er` 子例程负责白盒测试(也测试私有函数)。
+
+```python
+# tests/test1.er
+{add; ...} = import "foo"
+
+@Test
+test_1_plus_n(n: Nat) =
+ assert add(1, n) == n + 1
+```
+
+执行结果以摘要形式显示,可以以各种文件格式(.md、.csv 等)输出。
+
+## 文档测试
+
+在 Erg 中,`#` 和 `#[` 是注释行,但 `##` 和 `#[[` 是 doc 注释,并且注释可以从 VSCode 等编辑器显示为 markdown。
+此外,如果指定了 erg,则使用 erg test 命令自动测试文档注释中的源代码。
+下面是一个示例测试。
+
+```python
+VMs =...
+ ...
+ #[[
+ execute commands.
+ ```python
+ # 标准配置的虚拟机
+ {vm1; ...} = import "tests/mock"
+
+ assert vm1.exec!("i = 0") == None
+ assert vm1.exec!("i").try_into(Int)? == 0
+ ```
+ ]]#
+ .exec! ref self, src =
+ ...
+ ...
+```
+
+用于测试的模拟对象(mock objects)在 `tests/mock` 模块中定义。
\ No newline at end of file
diff --git a/doc/zh_TW/API/consts.md b/doc/zh_TW/API/consts.md
new file mode 100644
index 00000000..05440468
--- /dev/null
+++ b/doc/zh_TW/API/consts.md
@@ -0,0 +1,15 @@
+# 內置常量
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/consts.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## True
+
+## False
+
+## None
+
+## Ellipsis
+
+## NotImplemented
+
+## Inf
diff --git a/doc/zh_TW/API/funcs.md b/doc/zh_TW/API/funcs.md
new file mode 100644
index 00000000..a66a7555
--- /dev/null
+++ b/doc/zh_TW/API/funcs.md
@@ -0,0 +1,123 @@
+# 功能
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/funcs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 基本功能
+
+### if|T; U|(cond: Bool, then: T, else: U) -> T or U
+
+### map|T; U|(i: Iterable T, f: T -> U) -> Map U
+
+請注意,參數的順序與 Python 相反
+
+### log(x: Object, type: LogType = Info) -> None
+
+在調試顯示中記錄“x”。 執行完成后匯總并顯示日志
+支持表情符號的終端根據“類型”添加前綴
+
+* type == Info: ??
+* type == Ok: ?
+* type == Warn: ??
+* type == Hint: ??
+
+### panic(msg: Str) -> Panic
+
+顯示msg并停止。
+支持表情符號的終端有一個??前綴。
+
+### discard|T|(x: ...T) -> NoneType
+
+扔掉`x`。不使用返回值時使用。與 `del` 不同,它不會使變量 `x` 不可訪問
+
+```python
+p! x =
+ # q!應該返回一些不是None或()的值
+ # 如果不需要,請使用`discard`
+ discard q!(x)
+ f x
+
+discard True
+assert True # OK
+```
+
+### import(path: Path) -> Module or CompilerPanic
+
+導入一個模塊。如果找不到模塊,則引發編譯錯誤
+
+### eval(code: Str) -> Object
+
+將`code`作為代碼進行評估并返回。
+
+### classof(object: Object) -> Class
+
+返回`object`的類。
+但是,由于無法比較類,如果要判斷實例,請使用`object in Class`而不是`classof(object) == Class`
+編譯時確定的結構類型是通過`Typeof`獲得的
+
+## Iterator, Array生成系統
+
+### repeat|T|(x: T) -> RepeatIterator T
+
+```python
+rep = repeat 1 # Repeater(1)
+for! rep, i =>
+ print! i
+# 1 1 1 1 1 ...
+```
+
+### dup|T; N|(x: T, N: Nat) -> [T; N]
+
+```python
+[a, b, c] = dup new(), 3
+print! a #
+print! a == b # False
+```
+
+### cycle|T|(it: Iterable T) -> CycleIterator T
+
+```python
+cycle([0, 1]).take 4 # [0, 1, 0, 1]
+cycle("hello").take 3 # "hellohellohello"
+```
+
+## 定數式関數
+
+### Class
+
+創建一個新類。 與`Inherit`不同,通過`Class`傳遞與基類型無關,并且方法會丟失
+您將無法進行比較,但您可以進行模式匹配等操作
+
+```python
+C = Class {i = Int}
+NewInt = Class Int
+Months = Class 1..12
+jan = Months.new(1)
+jan + Months.new(2) # TypeError: `+` is not implemented for 'Months'
+match jan:
+ 1 -> log "January"
+ _ -> log "Other"
+```
+
+第二個參數 Impl 是要實現的特征
+
+### Inherit
+
+繼承一個類。您可以按原樣使用基類方法
+
+### Trait
+
+創造一個新的特質。目前,只能指定記錄類型
+
+### Typeof
+
+返回參數類型。如果要獲取運行時類,請使用`classof`。
+如果您將其用于類型規范,則會出現警告。
+
+```python
+x: Typeof i = ...
+# TypeWarning: Typeof(i) == Int, please replace it
+```
+
+### Deprecated
+
+作為解碼器使用。警告不推薦使用的類型或函數
\ No newline at end of file
diff --git a/doc/zh_TW/API/index.md b/doc/zh_TW/API/index.md
new file mode 100644
index 00000000..77223195
--- /dev/null
+++ b/doc/zh_TW/API/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/API/modules/external/alstruct.md b/doc/zh_TW/API/modules/external/alstruct.md
new file mode 100644
index 00000000..ff5b14f4
--- /dev/null
+++ b/doc/zh_TW/API/modules/external/alstruct.md
@@ -0,0 +1,59 @@
+# 結構
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/external/alstruct.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+模塊為它們提供代表代數結構和補丁的特征
+
+* 成員
+
+## 二進制運算
+
+```python
+BinOp Op: Kind 2 = Subsume Op(Self, Self.ReturnTypeOf Op), Additional: {
+ .ReturnTypeof = TraitType -> Type
+}
+
+Nat <: BinOp Add
+assert Nat. ReturnTypeof(Add) == Nat
+assert Nat. ReturnTypeof(Sub) == Int
+assert Nat. ReturnTypeof(Mul) == Nat
+assert Nat.ReturnTypeof(Div) == Positive Ratio
+```
+
+## 半群(一個二元運算的代數系統)
+
+```python
+SemiGroup Op: Kind 2 = Op(Self, Self)
+
+IntIsSemiGroupAdd = Patch Int, Impl=SemiGroupAdd
+
+Int <: SemiGroup Add
+```
+
+## 函子
+
+```python
+# * Identity law: x.map(id) == x
+# * Composition law: x.map(f).map(g) == x.map(f.then g)
+Functor = Trait {
+ .map|T, U: Type| = (Self(T), T -> U) -> Self U
+}
+```
+
+## 應用
+
+```python
+# * Identity law: x.app(X.pure(id)) == x
+Applicative = Subsume Functor, Additional: {
+ .pure|T: Type| = T -> Self T
+ .app|T, U: Type| = (Self(T), Self(T -> U)) -> Self U
+}
+```
+
+## 單子(交互式命令行工具以及面向對象的腳本技術)
+
+```python
+Monad = Subsume Applicative, Additional: {
+ .bind|T, U: Type| = (Self(T), T -> Self U) -> Self U
+}
+```
\ No newline at end of file
diff --git a/doc/zh_TW/API/modules/repl.md b/doc/zh_TW/API/modules/repl.md
new file mode 100644
index 00000000..8f13c939
--- /dev/null
+++ b/doc/zh_TW/API/modules/repl.md
@@ -0,0 +1,26 @@
+# 模塊`repl`
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/repl.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+提供REPL(Read-Eval-Print-Loop)相關的API。
+
+## 功能
+
+* `gui_help`
+
+在瀏覽器中查看有關對象的信息。 可以離線使用。
+
+## 類型
+
+### 猜測 = 對象
+
+#### 方法
+
+* `.guess`
+
+在給定參數和返回值的情況下推斷函數。
+
+```python
+1.guess((1,), 2) #
+[1, 2].guess((3, 4), [1, 2, 3, 4]) #
+```
\ No newline at end of file
diff --git a/doc/zh_TW/API/modules/status.md b/doc/zh_TW/API/modules/status.md
new file mode 100644
index 00000000..77ebb0e8
--- /dev/null
+++ b/doc/zh_TW/API/modules/status.md
@@ -0,0 +1,8 @@
+ # 模塊`status`
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/status.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+定義了一個類型來表示狀態。請根據情況刪除選項來使用它
+
+* ExecResult = {"success", "warning", "failure", "fatal", "unknown"}
+* ExecStatus = {"ready", "running", "sleeping", "plague", "completed", "terminated"}
\ No newline at end of file
diff --git a/doc/zh_TW/API/modules/unit.md b/doc/zh_TW/API/modules/unit.md
new file mode 100644
index 00000000..6c3e4b95
--- /dev/null
+++ b/doc/zh_TW/API/modules/unit.md
@@ -0,0 +1,74 @@
+# 模塊`unit`
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unit.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`unit` 模塊是將數值計算中經常使用的單位定義為類型的模塊。
+Erg 數值類型包括 `Nat`、`Int`、`Ratio` 等。但是,這些類型沒有關于“數字的含義”的信息,因此可以執行諸如添加米和碼之類的無意義計算。
+通過使用 `unit` 模塊,您可以避免錯誤,例如將不同單位的數字傳遞給函數。
+這樣的錯誤確實會發生,并且會導致諸如[由于錯誤的單位系統導致火星探測器丟失](http://www.sydrose.com/case100/287/)之類的嚴重錯誤。
+如果您希望代碼在進行數值計算時更加健壯,您應該使用此模塊。
+
+```python
+{*} = import "unit"
+
+x = 6m # 相當于 `x = Meter.new(6)`
+t = 3s # 相當于 `t = Sec.new(3)`
+#m/s是速度單位對象,類型為velocity
+print! x/t # 2m/s
+print! x + 4m # 10m
+print! x + 2s # 類型錯誤: `+`(Meter, Sec) 未實現
+```
+對象`m`、`s`和`m/s`被稱為單元對象。它本身具有1m、1s、1m/s的含義。 `m/s`可以說是結合m和s創建的單位對象。
+
+在單元中,以下單元被定義為類型。它被稱為SI(國際單位制)。
+
+* 長度:Meter(單位常數:m)
+* 質量:KiloGram(單位常數:kg,g = 0.001kg)
+* 時間:Sec(分、時、日、年等有分、時、日、年等常量由秒生成)
+* 電流:Amper(單位常數:a)
+* 溫度:Kelvin(單位常數:k。華氏、攝氏度類型也可用,可相互轉換)
+* 物質量:Mol(單位常數:mol)
+* 發光強度:Candela(單位常數:cd)
+
+此外,還定義了`Unit1`、`UnitMul`和`UnitDiv`類型,可以通過組合基本類型來創建新的單元。
+例如`UnitDiv(Unit1, Sec)`,因為頻率單位赫茲(hertz)被定義為振動周期(秒)的倒數。
+如果要將此類型視為有意義的類型(例如添加專用方法),則應創建 [patch](./../../syntax/type/07_patch.md)。
+
+```python
+Hertz = Patch UnitDiv(Unit1, Sec)
+SquareMeter = Patch UnitMul(Meter, Meter)
+```
+
+一些輔助單元也是預定義的:
+
+* 頻率: Hertz(hz)
+* 力: Newton(newton)
+* 能量: Joule(j)
+* 功率: Watt(w)
+* 電壓: Volt(v)
+* 電阻: Ohm(ohm)
+* 速度: Velocity(m/s)
+* 面積: SquareMeter(m^2)
+* 體積: CubicMeter(m^3) (liter = 10e-3 m^3)
+* 角度: Degree(deg) (rad = 180/pi deg)
+* 長度: Feet, Yard, Inch, Mile, Ly, Au, Angstrom
+* 重量: Pound
+
+它還定義了一個前綴:
+
+* Femto = 1e-15
+* Pico = 1e-12
+* Nano = 1e-9
+* Micro = 1e-6
+* Milli = 1e-3
+* Centi = 1e-2
+* Deci = 1e-1
+* Hecto = 1e+2
+* Kilo = 1e+3
+* Mega = 1e+6
+* Giga = 1e+9
+* Tera = 1e+12
+* Peta = 1e+15
+* Exa = 1e+18
+
+* 與名字的由來相反,Erg基本采用MKS單位制。如果需要 CGS 單位制的單位模塊,請使用外部庫[cgs](https://github.com/mtshiba/cgs)等)。
\ No newline at end of file
diff --git a/doc/zh_TW/API/modules/unsound.md b/doc/zh_TW/API/modules/unsound.md
new file mode 100644
index 00000000..1a896545
--- /dev/null
+++ b/doc/zh_TW/API/modules/unsound.md
@@ -0,0 +1,26 @@
+# 模塊 `unsound`
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unsound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+讓 API 執行在 Erg 的類型系統中無法保證的不健全和不安全的操作。
+
+## `unsafe!`
+
+執行“不安全”過程。 就像 Rust 一樣,`Unsafe` API 不能直接調用,而是作為高階函數傳遞給這個過程。
+
+```python
+unsound = import "unsound"
+
+i = unsound. unsafe! do!:
+ # 將 `Result Int` 轉換為 `Int`
+ unsound.transmute input!().try_into(Int), Int
+```
+
+## transmit
+
+將第一個參數的對象轉換為第二個參數的類型。沒有進行類型檢查。
+這個函數破壞了類型系統的類型安全。請在使用前進行驗證。
+
+## 隱式轉換
+
+與 `transmute` 不同,它會自動轉換為預期的類型。與 Ocaml 的 `Obj.magic` 工作方式相同。
\ No newline at end of file
diff --git a/doc/zh_TW/API/operators.md b/doc/zh_TW/API/operators.md
new file mode 100644
index 00000000..7ddcbeca
--- /dev/null
+++ b/doc/zh_TW/API/operators.md
@@ -0,0 +1,66 @@
+# 操作員
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/operators.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## 中綴運算符
+
+### `_+_`|R; O; A <: Add(R, O)|(x: A, y: R) -> O
+
+執行加法。
+
+### `_-_`|R; O; S <: Sub(R, O)|(x: S, y: R) -> O
+
+執行減法。
+
+### `*`|R; O; M <: Mul R, O|(x: M, y: R) -> O
+
+執行乘法。
+
+### `/`|R; O; D <: Div(R, O)|(x: D, y: R) -> O
+
+進行除法。
+
+## 中綴字母運算符
+
+### `and`(x: Bool, y: Bool) -> Bool
+
+執行 and 操作。
+
+### `or`(x: Bool, y: Bool) -> Bool
+
+執行 and 操作。
+
+## 前綴運算符
+
+### `+_`|T <: Num|(x: T) -> T
+
+默認與 id 相同。
+
+### `-_`|T <: Num|(x: T) -> T.Neg
+
+例如 Nat.`-`: Nat -> Neg 和返回值不同。
+
+### `!`|T <: Immut|(x: T) -> `T!`
+
+從不可變對象創建可變對象。
+該運算符本身不是程序性的,可以在函數內部使用。
+
+### `..`|T <: Ord|(x: T) -> Range T
+
+在 x 的末尾創建一個沒有下限的 Range 對象。
+x..x 僅返回 x 作為迭代器。
+
+### `..<`|T <: Ord|(x: T) -> Range T
+
+x.. Range T
+
+創建一個從 x 開始沒有上限的 Range 對象。
+
+### |T <: Ord|(x: T)`<..` -> Range T
\ No newline at end of file
diff --git a/doc/zh_TW/API/procs.md b/doc/zh_TW/API/procs.md
new file mode 100644
index 00000000..c1ffdb32
--- /dev/null
+++ b/doc/zh_TW/API/procs.md
@@ -0,0 +1,41 @@
+# 過程
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/procs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## print!
+
+```python
+打印!(x)->無類型
+```
+
+ 使用換行符返回 x。
+
+## 調試&排除;
+
+```python
+調試!(x,類型=信息)-> NoneType
+```
+
+用換行符調試 x(文件名、行號、變量名一起顯示)。 在發布模式中刪除。
+支持表情符號的終端根據類型加前綴。
+
+* type == Info: ??
+* type == Ok: ?
+* type == Warn: ??
+* type == Hint: ??
+
+## for!i: Iterable T, block: T => NoneType
+
+以塊的動作遍歷迭代器。
+
+## while!cond: Bool!, block: () => NoneType
+
+當cond為True時的執行塊。
+
+## Lineno!() -> Nat
+
+## Filename!() -> Str
+
+## Namespace!() -> Str
+
+## Module!() -> Module
\ No newline at end of file
diff --git a/doc/zh_TW/API/special.md b/doc/zh_TW/API/special.md
new file mode 100644
index 00000000..d67578bc
--- /dev/null
+++ b/doc/zh_TW/API/special.md
@@ -0,0 +1,177 @@
+# 特殊形式
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+特殊形式是不能在 Erg 類型系統中表達的運算符、子程序(等等)。它被`包圍,但實際上無法捕獲。
+此外,為方便起見,還出現了“Pattern”、“Body”和“Conv”等類型,但不存在此類類型。它的含義也取決于上下文。
+
+## `=`(pat: Pattern, body: Body) -> NoneType
+
+將 body 分配給 pat 作為變量。如果變量已存在于同一范圍內或與 pat 不匹配,則引發錯誤。
+它還用于記錄屬性定義和默認參數。
+
+```python
+record = {i = 1; j = 2}
+f(x: Int, y = 2) = ...
+```
+
+當主體是類型或函數時,`=` 具有特殊行為。
+左側的變量名嵌入到右側的對象中。
+
+```python
+print! Class() # >
+print! x: Int -> x + 1 # >
+C = Class()
+print! c #
+f = x: Int -> x + 1
+print! f #
+g x: Int = x + 1
+print! g #
+K X: Int = Class(...)
+print! K #
+L = X: Int -> Class(...)
+print! L #
+```
+
+`=` 運算符的返回值為“未定義”。
+函數中的多個賦值和 `=` 會導致語法錯誤。
+
+```python
+i = j = 1 # SyntaxError: 不允許多次賦值
+print!(x=1) # SyntaxError: cannot use `=` in function arguments
+# 提示:您的意思是關鍵字參數(`x: 1`)嗎?
+if True, do:
+ i = 0 # SyntaxError: 塊不能被賦值表達式終止
+```
+
+## `->`(pat: Pattern, body: Body) -> Func
+
+生成匿名函數,函數類型。
+
+## `=>`(pat: Pattern, body: Body) -> Proc
+
+生成匿名過程,過程類型。
+
+## `:`(subject, T)
+
+確定主題是否與 T 匹配。如果它們不匹配,則拋出編譯錯誤。
+
+```python
+a: Int
+f x: Int, y: Int = x / y
+```
+
+也用于 `:` 應用樣式。
+
+```python
+f x:
+ y
+ z
+```
+
+像`:`和`=`一樣,運算的結果是不確定的。
+
+```python
+_ = x: Int # 語法錯誤:
+print!(x: Int) # 語法錯誤:
+```
+
+## `.`(obj, attr)
+
+讀取obj的屬性。
+`x.[y, z]` 將 x 的 y 和 z 屬性作為數組返回。
+
+## `|>`(obj, c: Callable)
+
+執行`c(obj)`。 `x + y |>.foo()` 與 `(x + y).foo()` 相同。
+
+### (x: Option T)`?` -> T | T
+
+后綴運算符。如果出現錯誤,請立即調用 `x.unwrap()` 和 `return`。
+
+## match(obj, ...lambdas: Lambda)
+
+對于 obj,執行與模式匹配的 lambda。
+
+```python
+match [1, 2, 3]:
+ (l: Int) -> log "this is type of Int"
+ [[a], b] -> log a, b
+ [...a] -> log a
+# (1, 2, 3)
+```
+
+## del(x: ...T) -> NoneType | T
+
+刪除變量“x”。但是,無法刪除內置對象。
+
+```python
+a = 1
+del a # OK
+
+del True # SyntaxError: cannot delete a built-in object
+```
+
+## do(body: Body) -> Func
+
+生成一個不帶參數的匿名函數。 `() ->` 的語法糖。
+
+## do!(body: Body) -> Proc
+
+生成不帶參數的匿名過程。 `() =>` 的語法糖。
+
+## `else`(l, r) -> Choice
+
+創建一個由兩對組成的類元組結構,稱為 Choice 對象。
+`l, r` 被懶惰地評估。也就是說,只有在調用 .get_then 或 .get_else 時才會計算表達式。
+
+```python
+choice = 1 else 2
+assert choice.get_then() == 1
+assert choice.get_else() == 2
+assert True.then(choice) == 1
+```
+
+## 集合運算符
+
+### `[]`(...objs)
+
+從參數創建一個數組或從可選參數創建一個字典。
+
+### `{}`(...objs)
+
+從參數創建一個集合。
+
+### `{}`(...fields: ((Field, Value); N))
+
+生成記錄。
+
+### `{}`(layout, ...names, ...preds)
+
+生成篩型,等級2型。
+
+### `...`
+
+展開嵌套集合。它也可以用于模式匹配。
+
+```python
+[x, ...y] = [1, 2, 3]
+assert x == 1 and y == [2, 3]
+assert [x, ...y] == [1, 2, 3]
+assert [...y, x] == [2, 3, 1]
+{x; ...yz} = {x = 1; y = 2; z = 3}
+assert x == 1 and yz == {y = 2; z = 3}
+assert {x; ...yz} == {x = 1; y = 2; z = 3}
+```
+
+## 虛擬運算符
+
+用戶不能直接使用的運算符。
+
+### ref(x: T) -> Ref T | T
+
+返回對對象的不可變引用。
+
+### ref!(x: T!) -> Ref!T! | T!
+
+返回對可變對象的可變引用。
\ No newline at end of file
diff --git a/doc/zh_TW/API/types.md b/doc/zh_TW/API/types.md
new file mode 100644
index 00000000..2dba366c
--- /dev/null
+++ b/doc/zh_TW/API/types.md
@@ -0,0 +1,264 @@
+# 內置 Erg 類型列表
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+類型本身的屬性不存儲在 `.__dict__` 中,不能從實例中引用
+
+## 基本類型
+
+### 對象
+
+* `__dir__`:將對象的屬性作為數組返回(dir函數)
+* `__getattribute__`: 獲取并返回一個屬性
+* `__hash__`:返回對象的哈希值
+* `__repr__`:對象的字符串表示(不存在豐富/默認實現)
+* `__sizeof__`:返回對象的大小(包括在堆中分配的大小)
+
+### 顯示
+
+* `__str__`:返回對象的字符串表示(豐富)
+
+### Fmt
+
+* `__format__`: 返回一個格式化的字符串
+
+### 文檔
+
+* `__doc__`:對象描述
+
+### 命名
+
+* `__name__`: 對象的名稱
+
+### 泡菜
+
+* `__reduce__`: 用 Pickle 序列化對象
+* `__reduce_ex__`: __reduce__ 允許你指定協議版本
+
+## 對象系統
+
+Trait 類相當于 Python 中的 ABC(抽象基類,接口)
+實例屬于1、True、“aaa”等。
+類是 Int、Bool、Str 等。
+
+### 類型
+
+* `__父類__`:超類型(`__mro__` 是一個數組,但這個是一個 Set)
+* `__basicsize__`:
+* `__dictoffset__`:Evm 不支持
+* `__flags__`:
+* `__itemsize__`:實例的大小(如果不是類,則為 0)
+* `__weakrefoffset__`:Evm 不支持
+* `__membercheck__`: 相當于`ismember(x, T)`
+* `__subtypecheck__`:等價于`issubtype(U, T)`,別名`__subclasshook__`(兼容CPython)
+
+### 實例
+
+* `__class__`:返回創建實例的類(自動附加到使用 `.new` 創建的對象)
+
+### Class
+
+* `__mro__`:用于方法解析的類型數組(包括自身,始終以 Object 結尾)
+* `__base__`:基本類型(`__mro__[1]` 如果有多個)
+* `__new__`: 實例化
+* `__init__`: 初始化實例
+* `__init_subclass__`: 初始化實例
+* `__intstancecheck__`:使用類似于 `MyClass.__instancecheck__(x)`,等價于 `isinstance(x, MyClass)`
+* `__subclasscheck__`:等價于 `issubclass(C, MyClass)`
+
+## 運算符
+
+此處指定以外的運算符沒有特殊類型
+
+### 方程
+
+* `__eq__(self, rhs: Self) -> Bool`: 對象比較函數 (==)
+* `__ne__`: 對象比較函數 (!=),默認實現
+
+### 秩序
+
+* `__lt__(self, rhs: Self) -> Bool`: 對象比較函數 (<)
+* `__le__`:對象比較函數(<=),默認實現
+* `__gt__`:對象比較函數(>),默認實現
+* `__ge__`:對象比較函數(>=),默認實現
+
+### BinAdd
+
+* 實現 `__add__(self, rhs: Self) -> Self`: `+`
+
+### 添加R
+
+* `__add__(self, rhs: R) -> Self.AddO`
+
+### Sub R
+
+* `__sub__(self, rhs: R) -> Self.SubO`
+
+### Mul R
+
+* `__mul__(self, rhs: R) -> Self.MulO`
+
+### BinMul <: Mul Self
+
+* `__pow__`:實現 `**`(默認實現)
+
+### Div R, O
+
+* 實現 `__div__(self, rhs: Self) -> Self`: `/`,可能會因為 0 而恐慌
+
+### BinDiv <: Div Self
+
+* `__mod__`: 實現 `%` (默認實現)
+
+## 數值型
+
+### Num (= Add and Sub and Mul and Eq)
+
+例如,除了Complex,Vector、Matrix和Tensor都是Num(Matrix和Tensor中的*分別與dot和product相同)
+
+### Complex (= Inherit(Object, Impl := Num))
+
+* `imag: Ratio`:返回虛部
+* `real: Ratio`:返回實部
+* `conjugate self -> Complex`:返回復共軛
+
+### Float (= Inherit(FloatComplex, Impl := Num))
+
+### Ratio (= Inherit(Complex, Impl := Num))
+
+* `numerator: Int`: 返回分子
+* `denominator: Int`: 返回分母
+
+### Int (= Inherit Ratio)
+
+### Nat (= Inherit Int)
+
+* `times!`: 運行 proc self 時間
+
+## 其他基本類型
+
+### 布爾值
+
+* `__and__`:
+* `__or__`:
+* `not`:
+
+## 字符串 (<: 序列)
+
+* `capitalize`
+* `chomp`: 刪除換行符
+* `isalnum`:
+* `isascii`:
+* `isalpha`:
+* `isdecimal`:
+* `isdight`:
+* `isidentifier`
+* `islower`
+* `isnumeric`
+* `isprintable`
+* `isspace`
+* `istitle`
+* `isupper`
+* `lower`
+* `swapcase`
+* `title`
+* `upper`
+
+## 其他
+
+### 位
+
+* `from_bytes`:從字節轉換
+* `to_bytes`:轉換為字節(指定長度和字節序(字節序))
+* `bit_length`:返回位長度
+
+### 可迭代 T
+
+請注意,它不是 `Iterator` 本身的類型。 `Nat` 是 `Iterable` 但你不能 `Nat.next()`,你需要 `Nat.iter().next()`。
+
+* `iter`:創建一個迭代器。
+
+### 迭代器 T
+
+Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter().fold (sum, n) -> sum + n*2`等是可能的。
+由于所有和任何在使用后都會被破壞,因此沒有副作用。這些應該使用沒有副作用的 `next` 來實現,但內部使用 `Iterator!.next!` 來提高執行效率。
+
+* `next`:返回第一個元素和剩余的迭代器。
+* `all`
+* `any`
+* `filter`
+* `filter_map`
+* `find`
+* `find_map`
+* `flat_map`
+* `flatten`
+* `fold`
+* `for_each`
+* `map`
+* `map_while`
+* `nth`
+* `pos`
+* `take`
+* `unzip`
+* `zip`
+
+### Iterator!T = IteratorT 和 ...
+
+* `next!`:獲取第一個元素。
+
+## SizedIterator T = 迭代器 T 和 ...
+
+有限數量元素的迭代器。
+
+* `len`:
+* `chain`:
+* `count`:
+* `is_empty`:
+* `rev`:
+* `next_back`:
+* `nth_back`:
+* `rfind`:
+* `rfold`:
+* `sum`:
+* `max`:
+* `min`:
+
+## Seq T = SizedIterable T 和 ...
+
+* `concat`: 合并兩個 Seq
+* `__getitem__`:等同于使用 `[]` 訪問(否則會出現恐慌)
+* 與 `get`: __getitem__ 不同,它返回 Option
+* `maketrans`:創建替換表(靜態方法)
+* `replace`: 替換
+* `translate`:根據替換表替換
+* `insert`: 添加到 idx
+* `remove`: 刪除 idx
+* `prepend`: 前置
+* `dequeue`: 移除頭部
+* `push`:添加到末尾
+* `pop`: 取尾巴
+* `dedup`:刪除連續值
+* `uniq`:刪除重復元素(通過 sort |> dedup 實現,因此順序可能會改變)
+* `swap`:交換元素
+* `reverse`:反轉元素
+* `sort`: 排序元素
+* `first`:
+* `last`:
+
+### Seq!T (= Seq T and ...)
+
+* `__setitem__!`:
+* `__delitem__!`:
+* `插入!`:添加到 idx
+* `remove!`: 刪除 idx
+* `prepend!`:前置
+* `dequeue!`: 刪除開頭
+* `push!`:添加到末尾
+* `pop!`:拿尾巴
+* `dedup!`:刪除連續值
+* `uniq!`: 刪除重復元素(通過排序實現!|> dedup!,因此順序可能會改變)
+* `swap!`:交換元素
+* `reverse!`:反轉元素
+* `set!`
+* `sort!`: 排序元素
+* `translate!`
\ No newline at end of file
diff --git a/doc/zh_TW/API/types/classes/Array!(T).md b/doc/zh_TW/API/types/classes/Array!(T).md
new file mode 100644
index 00000000..264c3d17
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Array!(T).md
@@ -0,0 +1,5 @@
+# Array! T
+
+[.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array!(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示可變長度數組的類型。在編譯時長度未知時使用。 有一個語法糖叫做` [t]!`。在`Array! T = ArrayWithMutLength! T, !_`中被定義
\ No newline at end of file
diff --git a/doc/zh_TW/API/types/classes/Array(T).md b/doc/zh_TW/API/types/classes/Array(T).md
new file mode 100644
index 00000000..f2bfc5f0
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Array(T).md
@@ -0,0 +1,5 @@
+# Array T: Type
+
+[.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+由`Array T = ArrayWithLen T, _`定義。 有一種語法糖叫做`[T]`。
\ No newline at end of file
diff --git a/doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md b/doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md
new file mode 100644
index 00000000..671a95fd
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md
@@ -0,0 +1,36 @@
+# ArrayWithLen T: Type, N: Nat
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithLen(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`[T; N]`是語法糖。還有一個[`Array` 類型](./Array.md)省略了長度。
+
+## 方法
+
+* values_at(self, selectors: [Nat; N]) -> [T; N]
+
+```python
+assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"]
+```
+
+* all(self, pred: T -> Bool) -> Bool
+ 返回是否所有元素都滿足 pred。
+ 如果元素為 0,則無論 pred 為 `True`,但會發出警告。
+ 該規范本身已被多種語言采用,是邏輯一致性所必需的。
+
+ ```python
+ assert [].all(_ -> False)
+ ```
+
+ ```python
+ assert all(False for _ in [])
+ ```
+
+## ArrayWithLen T, N | T <: Eq 的方法
+
+* freq self -> [{T: Nat}]
+ 返回對象出現的次數。
+
+```python
+assert ["a", "b", "c", "b", "c", "b"].freq() \
+== [{"a", 1}, {"b": 3}, {"c": 2}]
+```
diff --git a/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md
new file mode 100644
index 00000000..9301585d
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md
@@ -0,0 +1,28 @@
+# ArrayWithMutLength! T: Type, N: Nat!
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+一個可變長度數組,其長度在編譯時已知。還有語法糖`ArrayWithMutLength(T, !N) == [T; !N]`
+
+## 方法
+
+* push! ref! self(N ~> N+1, ...), elem: T
+
+* pop! ref! (N ~> N-1, ...) -> T
+
+* sample!(ref! self) -> T
+* sample! ref! self, M: Nat -> [T; M]
+ 隨機選擇里面的一個元素并返回一個副本
+
+* shuffle!(ref! self)
+ 把里面的東西隨機擺放
+
+* assert_len ref! self(_ ~> N, ...), N: Nat -> () or Panic
+ 驗證長度。
+ `panic!` 如果長度無效。
+
+## Impl
+
+* From Range Int
+* From [T; N]
+* Num
diff --git a/doc/zh_TW/API/types/classes/Class.md b/doc/zh_TW/API/types/classes/Class.md
new file mode 100644
index 00000000..8cad7741
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Class.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Class.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/API/types/classes/Complex.md b/doc/zh_TW/API/types/classes/Complex.md
new file mode 100644
index 00000000..bc783294
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Complex.md
@@ -0,0 +1,16 @@
+# Complex
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Complex.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示復數的類型。在 Erg 中表示數字的類型,例如 Float、Int和Nat,通常派生于Complex
+
+## 父類
+
+Num 和 Norm
+
+## 方法
+
+* abs
+* conjugate
+* imag
+* real
diff --git a/doc/zh_TW/API/types/classes/Dict!.md b/doc/zh_TW/API/types/classes/Dict!.md
new file mode 100644
index 00000000..95950ea7
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Dict!.md
@@ -0,0 +1,9 @@
+# Dict! K, V
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Dict!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示字典(哈希Map)的類型。 有一個語法糖叫做`{K: V}`
+
+## 方法
+
+* invert!(self) -> Self! V, K
diff --git a/doc/zh_TW/API/types/classes/Either.md b/doc/zh_TW/API/types/classes/Either.md
new file mode 100644
index 00000000..38517463
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Either.md
@@ -0,0 +1,14 @@
+# Either L, R = L or R
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Either.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示L或R的類型。 您可以將其視為Or類型的二元形式
+
+## 方法
+
+* orl
+* orr
+* andl
+* andr
+* mapl
+* mapr
diff --git a/doc/zh_TW/API/types/classes/Float.md b/doc/zh_TW/API/types/classes/Float.md
new file mode 100644
index 00000000..77a3ee9d
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Float.md
@@ -0,0 +1,23 @@
+# Float size
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Float.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示實數(包含小數的數)的類型。符合IEEE 754的浮點數,在其他語言中一般是float的類型。
+Float的大小為8(1byte)~128(16byte)。如果只是Float,則表示`Float64`。
+Erg 中的 0.1 實際上屬于 Ratio 類型,而不是 Float 類型。沒有浮點類型字面量,它是由 `(Ratio object)f64` 生成的(例如 (1/2)f64, 15f64)。 f64 對應實數 1
+
+## 父類
+
+Complex 和 Ord
+
+## 方法
+
+* sgn(self) -> {-1, 0, 1}
+ 返回標志
+
+* truncate(self) -> Int
+ 返回最接近自身的整數
+
+* separate(self) -> [Str]
+* separate(self, dight: Nat) -> [Str]
+ 按digit位數劃分。沒有自變量
diff --git a/doc/zh_TW/API/types/classes/Function(N).md b/doc/zh_TW/API/types/classes/Function(N).md
new file mode 100644
index 00000000..08d6b7b0
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Function(N).md
@@ -0,0 +1,11 @@
+# Function N: Nat
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Function(N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## Function 1 的方法
+
+* then(self, g: Self) -> Self
+
+```python
+assert f(g(x)) == f.then(g) x
+```
diff --git a/doc/zh_TW/API/types/classes/Inf.md b/doc/zh_TW/API/types/classes/Inf.md
new file mode 100644
index 00000000..685cf242
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Inf.md
@@ -0,0 +1,9 @@
+# Inf
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Inf.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+Inf是一個類,其唯一實例是inf。
+inf的主要用途是用于區間類型。
+例如,大于等于 2 的整數類型是 `2.. Self(L1+L2, R1+R2)
+
+正常加法。 `Int` 和 `Nat` 的添加在此定義為假裝它在每個類中定義
+
+```python
+0..10 + 1..12 == 1..22
+Int + 0..10 == _..|Int|_ + 0..10 == _..|Int|_ == Int
+Nat + Nat == 0.._ + 0.._ == 0.._ == Nat
+```
diff --git a/doc/zh_TW/API/types/classes/Interval.md b/doc/zh_TW/API/types/classes/Interval.md
new file mode 100644
index 00000000..4335d7aa
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Interval.md
@@ -0,0 +1,20 @@
+# Interval begin, end := WellOrder
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Interval.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+表示有序集合類型 (WellOrder) 的子類型的類型。Interval 類型具有派生類型,例如 PreOpen(x<..y)。
+
+```python
+Months = 1..12
+Alphabet = "a".."z"
+Weekdays = Monday..Friday
+Winter = November..December or January..February
+```
+
+```python
+0..1 # 整數范圍
+0.0..1.0 # 真實(有理)范圍
+# 或 0/1..1/1 相同
+```
+
+計算機無法處理無限位數的數字,所以實數的范圍實際上是有理數的范圍。
\ No newline at end of file
diff --git a/doc/zh_TW/API/types/classes/Iterator.md b/doc/zh_TW/API/types/classes/Iterator.md
new file mode 100644
index 00000000..d0af23ee
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Iterator.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Iterator.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/API/types/classes/Kind(N).md b/doc/zh_TW/API/types/classes/Kind(N).md
new file mode 100644
index 00000000..28843fe0
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Kind(N).md
@@ -0,0 +1,7 @@
+# Kind N: Nat
+
+[.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Kind(N).md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+```python
+Kind N: Nat = (Type; N) -> Type
+```
diff --git a/doc/zh_TW/API/types/classes/Matrix.md b/doc/zh_TW/API/types/classes/Matrix.md
new file mode 100644
index 00000000..06acac62
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Matrix.md
@@ -0,0 +1,9 @@
+# Matrix T: Num, Shape: [M, N]
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Matrix.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示矩陣的類型。 它繼承自 Tensor[M, N]
+
+## 定義
+
+Inherit Tensor T, [M, N]
diff --git a/doc/zh_TW/API/types/classes/Module.md b/doc/zh_TW/API/types/classes/Module.md
new file mode 100644
index 00000000..135a64da
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Module.md
@@ -0,0 +1,5 @@
+# Module
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Module.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## 方法
diff --git a/doc/zh_TW/API/types/classes/Nat.md b/doc/zh_TW/API/types/classes/Nat.md
new file mode 100644
index 00000000..1fe9da24
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Nat.md
@@ -0,0 +1,20 @@
+# Nat
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Nat.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+表示自然數的類型。 用于數組索引和范圍類型
+
+## 定義
+
+```python
+Nat = 0.._
+```
+
+## 方法
+
+* times!(self, p: () => NoneType) -> NoneType
+
+```python
+100.times! () =>
+ print! "hello!"
+```
diff --git a/doc/zh_TW/API/types/classes/Neg.md b/doc/zh_TW/API/types/classes/Neg.md
new file mode 100644
index 00000000..5317a2bd
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Neg.md
@@ -0,0 +1,10 @@
+# Neg
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Neg.md&commit_hash=290c43b09f7c3036112a164bed5fd07a1f6a5cda)
+
+表示負整數的類型。 Pos和Neg和{0} == Int
+它還具有一些值得注意的屬性,例如不被零除和 Neg * Neg == Pos
+
+## 定義
+
+Inf<..-1
diff --git a/doc/zh_TW/API/types/classes/Never.md b/doc/zh_TW/API/types/classes/Never.md
new file mode 100644
index 00000000..00dcf7f1
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Never.md
@@ -0,0 +1,15 @@
+# Never
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Never.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+它是所有類型的子類型。 它是一個`Class`,因為它擁有所有的方法,當然還有 `.new`。但是,它沒有實例,并且Erg會在即將創建的那一刻停止。
+還有一種叫做`Panic`的類型沒有實例,但是`Never`用于正常終止或故意無限循環,`Panic`用于異常終止。
+
+```python
+# Never <: Panic
+f(): Panic = exit 0 # OK
+g(): Never = panic() # TypeError
+```
+
+`Never`/`Panic`的 OR 類型,例如`T 或 Never`可以轉換為`T`。 這是因為`Never`在語義上是一個從不出現的選項(如果出現了,程序會立即停止)。
+但是,在函數的返回值類型中使用時,`or Never`不能省略,因為它表示程序可能會終止。
\ No newline at end of file
diff --git a/doc/zh_TW/API/types/classes/NonZero.md b/doc/zh_TW/API/types/classes/NonZero.md
new file mode 100644
index 00000000..c4b9e526
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/NonZero.md
@@ -0,0 +1,32 @@
+# NonZero N
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/NonZero.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示非零數的類。 保證除零的安全性
+
+```mermaid
+classDiagram
+ class NonZero~Int~ {
+ ...
+ }
+ class Int {
+ ...
+ }
+ class Div {
+ <>
+ /(Self, R) -> O or Panic
+ }
+ class SafeDiv {
+ <>
+ /(Self, R) -> O
+ }
+ Int <|-- NonZero~Int~: Inherit
+ Div <|-- SafeDiv: Subsume
+ SafeDiv <|.. NonZero~Int~: Impl
+ Div <|.. Int: Impl
+```
+
+## 方法
+
+@Impl SafeDiv R, O
+.`/`: Self.(R) -> O
diff --git a/doc/zh_TW/API/types/classes/Object.md b/doc/zh_TW/API/types/classes/Object.md
new file mode 100644
index 00000000..ea27c461
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Object.md
@@ -0,0 +1,9 @@
+# Object
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Object.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+它是所有類型的超類型
+
+## 方法
+
+* __sizeof__: Nat
diff --git a/doc/zh_TW/API/types/classes/Operator.md b/doc/zh_TW/API/types/classes/Operator.md
new file mode 100644
index 00000000..363d3bd1
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Operator.md
@@ -0,0 +1,9 @@
+# Operator [...T], O
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Operator.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+是運算符的類型
+
+## 定義
+
+Inherit Func [...T], O
diff --git a/doc/zh_TW/API/types/classes/Option.md b/doc/zh_TW/API/types/classes/Option.md
new file mode 100644
index 00000000..dd14db2a
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Option.md
@@ -0,0 +1,23 @@
+# Option T = T or NoneType
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Option.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+表示“可能失敗”的類型。
+
+## 方法
+
+* unwrap(self, msg = "unwrapped a None value") -> T or Panic
+
+提取它,期望內容是 `T` 類型。 如果是 `None`,則輸出 `msg` 并恐慌
+
+```python
+x = "...".parse(Int).into(Option Int)
+x.unwrap() # UnwrappingError: unwrapped a None value
+x.unwrap("failed to convert from string to number") # UnwrappingError: failed to convert from string to number
+```
+
+* unwrap_or(self, else: T) -> T
+
+* unwrap_or_exec(self, f: () -> T) -> T
+
+* unwrap_or_exec!(self, p!: () => T) -> T
diff --git a/doc/zh_TW/API/types/classes/Pos.md b/doc/zh_TW/API/types/classes/Pos.md
new file mode 100644
index 00000000..02881a92
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Pos.md
@@ -0,0 +1,10 @@
+# Pos
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Pos.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+Pos是一種表示正數(大于或等于1的整數)的類型。
+由于不包括0,因此具有消除被零除的可能性等優點。
+
+## 定義
+
+`Pos = 1.._`
diff --git a/doc/zh_TW/API/types/classes/Ratio.md b/doc/zh_TW/API/types/classes/Ratio.md
new file mode 100644
index 00000000..a3b9fb05
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Ratio.md
@@ -0,0 +1,7 @@
+# Ratio
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Ratio.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示有理數的類型。 它主要用于當您要使用分數時。
+實際上,Erg中的/運算符返回 Ratio。1/3等不被評估為 0.33333... 并且被處理為1/3。 此外,0.1 相當于 1/10。 所以`0.1 + 0.2 == 0.3`。 這聽起來很明顯,但在 Python中它是False。
+但是,Ratio類型的效率往往比Float類型略低。 在執行速度很重要且不需要精確數值的地方應該使用浮點類型。 然而,正如Rob Pike所說,過早優化是萬惡之源。 在丟棄Ratio類型并使用Float類型之前,請進行真實的性能測試。 業余愛好者無條件偏愛較輕的模具。
diff --git a/doc/zh_TW/API/types/classes/Record.md b/doc/zh_TW/API/types/classes/Record.md
new file mode 100644
index 00000000..74bd0baf
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Record.md
@@ -0,0 +1,16 @@
+# Record
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Record.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+記錄所屬的類。例如,`{i = 1}` 是`Structural {i = Int}` 類型的元素,并且是`{i = Int}` 類的實例
+請注意,其他類的實例是記錄類型的元素,而不是記錄類的實例
+
+```python
+assert not Structural({i = Int}) in Class
+assert {i = Int} in Class
+
+C = Class {i = Int}
+c = C.new {i = 1}
+assert c in Structural {i = Int}
+assert not c in {i = Int}
+```
diff --git a/doc/zh_TW/API/types/classes/Result.md b/doc/zh_TW/API/types/classes/Result.md
new file mode 100644
index 00000000..0205b31f
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Result.md
@@ -0,0 +1,9 @@
+# Result T, E
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Result.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
+Result T, E <: Error = Either T, E
+```
+
+和 `Option` 一樣,它代表“一個可能失敗的值”,但它可以有失敗的上下文。 用法與`Either`幾乎相同。
\ No newline at end of file
diff --git a/doc/zh_TW/API/types/classes/Str!.md b/doc/zh_TW/API/types/classes/Str!.md
new file mode 100644
index 00000000..62c50c4d
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Str!.md
@@ -0,0 +1,5 @@
+# StrWithLen! N: Nat! = Inherit StrWithLen N
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示可變長度字符串的類型
diff --git a/doc/zh_TW/API/types/classes/Str.md b/doc/zh_TW/API/types/classes/Str.md
new file mode 100644
index 00000000..24c3cac3
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Str.md
@@ -0,0 +1,11 @@
+# Str
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+(不變長度)表示字符串的類型。 簡單的 `Str` 類型是刪除了字符數的 `StrWithLen N` 類型(`Str = StrWithLen _`)
+
+## 方法
+
+* isnumeric
+
+返回字符串是否為阿拉伯數字。 使用 `isunicodenumeric` 判斷漢字數字和其他表示數字的字符(注意此行為與 Python 不同)。
\ No newline at end of file
diff --git a/doc/zh_TW/API/types/classes/StrWithLen.md b/doc/zh_TW/API/types/classes/StrWithLen.md
new file mode 100644
index 00000000..67caca65
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/StrWithLen.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/StrWithLen.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/API/types/classes/Subroutine.md b/doc/zh_TW/API/types/classes/Subroutine.md
new file mode 100644
index 00000000..5de32879
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Subroutine.md
@@ -0,0 +1,21 @@
+# Subroutine
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Subroutine.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Func和Proc的基本類型。
+
+## 方法
+
+* return
+
+中斷子程序并返回指定的值。 用于快速逃離嵌套
+
+```python
+f x =
+ for 0..10, i ->
+ if i == 5:
+ do
+ f::return i
+ do
+ log i
+```
diff --git a/doc/zh_TW/API/types/classes/Tensor.md b/doc/zh_TW/API/types/classes/Tensor.md
new file mode 100644
index 00000000..db3304b9
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Tensor.md
@@ -0,0 +1,26 @@
+# Tensor Shape: [Nat; N]
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tensor.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+ 用于有效操作多維數組的類。 它還定義了諸如多維數組上的乘法之類的操作
+ Matrix、Vector 等都繼承自該類型
+
+```python
+Tensor.arange(0..9) # Tensor [10]
+```
+
+* reshape(self, NewShape: [Nat; M]) -> Self NewShape
+
+```python
+(1..9).into(Tensor).reshape [3, 3]
+```
+
+* identity i: Nat -> Self shape: [Nat; N]
+* zeros(Shape: [Nat; N]) -> Self
+* ones(Shape: [Nat; N]) -> Self
+
+* diag
+
+* linspace
+* logspace
+* geomspace
diff --git a/doc/zh_TW/API/types/classes/TransCell(T).md b/doc/zh_TW/API/types/classes/TransCell(T).md
new file mode 100644
index 00000000..cc95238c
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/TransCell(T).md
@@ -0,0 +1,14 @@
+# TransCell! T: Type!
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/TransCell(T).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+它是一個單元格,其內容可以針對每個模具進行更改。 由于它是T類型的子類型,因此它也表現為T類型
+當它在初始化時輸入T時很有用,并且在某個點之后總是輸入U
+
+```python
+a = TransCell!.new None
+a: TransCell! !NoneType
+a.set! 1
+a: TransCell! !Int
+assert a + 1 == 2
+```
diff --git a/doc/zh_TW/API/types/classes/Tuple.md b/doc/zh_TW/API/types/classes/Tuple.md
new file mode 100644
index 00000000..fb0d5163
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Tuple.md
@@ -0,0 +1,29 @@
+# Tuple T: ...Type
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tuple.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+包含多種類型對象的集合
+
+## 方法
+
+* zip self, other
+
+ 組合兩個有序集合(數組或元組)
+
+ ```python
+ assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4)
+ ```
+
+* zip_by self, op, other
+
+ 一種泛化 zip 的方法。 您可以指定一個二進制操作來組合
+ `()`、`[]`、`{}`、`{:}` 也可以指定為運算符,分別生成元組、數組、集合和字典
+
+ ```python
+ assert ([1, 2, 3].zip([4, 5, 6]))[0] == (1, 4)
+ assert ([1, 2, 3].zip_by((), [4, 5, 6]))[0] == (1, 4)
+ assert ([1, 2, 3].zip_by([], [4, 5, 6]))[0] == [1, 4]
+ assert ([1, 2, 3].zip_by({}, [4, 5, 6]))[0] == {1, 4}
+ assert ([1, 2, 3].zip_by({:}, [4, 5, 6]))[0] == {1: 4}
+ assert ([1, 2, 3].zip_by(`_+_`, [4, 5, 6]))[0] == 5
+ ```
diff --git a/doc/zh_TW/API/types/classes/Type.md b/doc/zh_TW/API/types/classes/Type.md
new file mode 100644
index 00000000..dae4a5c2
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Type.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/API/types/classes/Vector.md b/doc/zh_TW/API/types/classes/Vector.md
new file mode 100644
index 00000000..50e9b3d6
--- /dev/null
+++ b/doc/zh_TW/API/types/classes/Vector.md
@@ -0,0 +1,5 @@
+# Vector T: Num, N: Nat
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Vector.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+表示向量的類型。與同名的Rust和C++類型不同,這種類型只處理數字。
\ No newline at end of file
diff --git a/doc/zh_TW/API/types/patches/BinOp.md b/doc/zh_TW/API/types/patches/BinOp.md
new file mode 100644
index 00000000..5fa493e7
--- /dev/null
+++ b/doc/zh_TW/API/types/patches/BinOp.md
@@ -0,0 +1,9 @@
+# BinOp L, R, O
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/BinOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+二元運算符的類型
+
+## 修補程序
+
+Operator [L, R], O
diff --git a/doc/zh_TW/API/types/patches/UnaryOp.md b/doc/zh_TW/API/types/patches/UnaryOp.md
new file mode 100644
index 00000000..5ac2ae86
--- /dev/null
+++ b/doc/zh_TW/API/types/patches/UnaryOp.md
@@ -0,0 +1,9 @@
+# UnaryOp T, O
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/UnaryOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+一元運算符的類型
+
+## 定義
+
+Operator [T], O
diff --git a/doc/zh_TW/API/types/traits/Add(R,O).md b/doc/zh_TW/API/types/traits/Add(R,O).md
new file mode 100644
index 00000000..726071f0
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/Add(R,O).md
@@ -0,0 +1,36 @@
+# Add R
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Add(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
+Add R = Trait {
+ .AddO = Type
+ .`_+_` = (Self, R) -> Self.AddO
+}
+```
+
+`Add`是一種定義加法的類型。加法有兩種類型的`+`:方法和函數
+`+`作為二元函數,即`_+_`,定義如下:
+
+```python
+`_+_`(l: Add(R, O), r: R): O = l.`_+_` r
+```
+
+這個定義的目的是讓 `+` 可以被視為一個函數而不是一個方法
+
+```python
+assert [1, 2, 3].fold(0, `_+_`) == 6
+
+call op, x, y = op(x, y)
+assert call(`_+_`, 1, 2) == 3
+```
+
+加法是這樣輸入的
+
+```python
+f: |O: Type; A <: Add(Int, O)| A -> O
+f x = x + 1
+
+g: |A, O: Type; Int <: Add(A, O)| A -> O
+g x = 1 + x
+```
diff --git a/doc/zh_TW/API/types/traits/Div(R,O).md b/doc/zh_TW/API/types/traits/Div(R,O).md
new file mode 100644
index 00000000..664dc954
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/Div(R,O).md
@@ -0,0 +1,11 @@
+# Div R, O
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Div(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+如果除以零沒有錯誤,請使用“SafeDiv”
+
+```python
+Div R, O = Trait {
+ .`/` = Self.(R) -> O or Panic
+}
+```
diff --git a/doc/zh_TW/API/types/traits/Eq.md b/doc/zh_TW/API/types/traits/Eq.md
new file mode 100644
index 00000000..6aed2ae0
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/Eq.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Eq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/API/types/traits/Into.md b/doc/zh_TW/API/types/traits/Into.md
new file mode 100644
index 00000000..83093df7
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/Into.md
@@ -0,0 +1,13 @@
+# Into T
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Into.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+一種類型,表明它可以被類型轉換為類型T。
+即使Self和T之間沒有繼承關系,也是在關系可以相互轉換的時候定義的。
+與繼承不同,沒有隱式轉換。您必須始終調用 `.into` 方法。
+
+## 方法
+
+* into(self, T) -> T
+
+ 変換を行います。
diff --git a/doc/zh_TW/API/types/traits/Iterable.md b/doc/zh_TW/API/types/traits/Iterable.md
new file mode 100644
index 00000000..ba458258
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/Iterable.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Iterable.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/API/types/traits/Num.md b/doc/zh_TW/API/types/traits/Num.md
new file mode 100644
index 00000000..ca55178b
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/Num.md
@@ -0,0 +1,18 @@
+# Num
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Num.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 定義初始化
+
+```python
+Num R = Add(R) and Sub(R) and Mul(R) and Eq
+Num = Num Self
+```
+
+## 父類
+
+Add and Sub and Mul and Eq
+
+## 方法
+
+* `abs`
diff --git a/doc/zh_TW/API/types/traits/Ord.md b/doc/zh_TW/API/types/traits/Ord.md
new file mode 100644
index 00000000..3ef5f04a
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/Ord.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Ord.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/API/types/traits/SafeDiv(R,O).md b/doc/zh_TW/API/types/traits/SafeDiv(R,O).md
new file mode 100644
index 00000000..03595643
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/SafeDiv(R,O).md
@@ -0,0 +1,10 @@
+# SafeDiv R, O
+
+[.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/SafeDiv(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
+SafeDiv R, O = Subsume Div, {
+ @Override
+ .`/` = Self.(R) -> O
+}
+```
diff --git a/doc/zh_TW/API/types/traits/Sample.md b/doc/zh_TW/API/types/traits/Sample.md
new file mode 100644
index 00000000..5a601d84
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/Sample.md
@@ -0,0 +1,33 @@
+# Sample
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Sample.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+具有“隨機”選擇實例的`sample`和`sample!`方法的特征。`sample`方法總是返回相同的實例,而`sample!`方法返回一個隨機實例,該實例隨調用而變化
+
+請注意,這是一個假設您想要一個適當的實例進行測試等的特征,并且它不一定是隨機的。 如果您想要隨機抽樣,請使用“隨機”模塊。
+
+所有主要的值類都實現了 `Sample`。它還在由“Sample”類組成的元組類型、記錄類型、Or類型和篩選類型中實現
+
+```python
+assert Int.sample() == 42
+assert Str.sample() == "example"
+# Int默認在64bit范圍內采樣
+print! Int.sample!() # 1313798
+print! {x = Int; y = Int}.sample!() # {x = -32432892, y = 78458576891}
+```
+
+下面是一個`Sample`的實現示例
+
+```python
+EmailAddress = Class {header = Str; domain = Str}, Impl=Sample and Show
+@Impl Show
+EmailAddress.
+ show self = "{self::header}@{self::domain}"
+@Impl Sample
+EmailAddress.
+ sample(): Self = Self.new "sample@gmail.com"
+ sample!(): Self =
+ domain = ["gmail.com", "icloud.com", "yahoo.com", "outlook.com", ...].sample!()
+ header = AsciiStr.sample!()
+ Self.new {header; domain}
+```
diff --git a/doc/zh_TW/API/types/traits/Seq.md b/doc/zh_TW/API/types/traits/Seq.md
new file mode 100644
index 00000000..007f7134
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/Seq.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Seq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/API/types/traits/Show.md b/doc/zh_TW/API/types/traits/Show.md
new file mode 100644
index 00000000..30763e02
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/Show.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Show.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/API/types/traits/Unpack.md b/doc/zh_TW/API/types/traits/Unpack.md
new file mode 100644
index 00000000..37364850
--- /dev/null
+++ b/doc/zh_TW/API/types/traits/Unpack.md
@@ -0,0 +1,15 @@
+# Unpack
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Unpack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+標記性狀。實現時,元素可以像記錄一樣通過模式匹配來分解
+
+```python
+C = Class {i = Int}, Impl=Unpack
+C.new i = Self::new {i;}
+{i} = C.new(1)
+D = Class C or Int
+log match D.new(1):
+ (i: Int) -> i
+ ({i}: C) -> i
+```
diff --git a/doc/zh_TW/compiler/TODO_hint.md b/doc/zh_TW/compiler/TODO_hint.md
new file mode 100644
index 00000000..69f19f36
--- /dev/null
+++ b/doc/zh_TW/compiler/TODO_hint.md
@@ -0,0 +1,6 @@
+# 提示(未實現)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_hint.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+* `x 未定義`(x 已被`Del` 刪除)=> `提示:在第 X 行刪除`
+*補丁方法重復:“提示:指定補丁(如`T.foo(1)`)或使用`Del`刪除任何`.foo`”
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/TODO_recov_suggest.md b/doc/zh_TW/compiler/TODO_recov_suggest.md
new file mode 100644
index 00000000..f21dd8bf
--- /dev/null
+++ b/doc/zh_TW/compiler/TODO_recov_suggest.md
@@ -0,0 +1,13 @@
+# 錯誤恢復建議(尚未實現)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_recov_suggest.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+* `1 or 2`, `1 and 2` => `{1, 2}`?
+* `U = Inherit T` => 非類類型不能被繼承,或者`U = Class T`?
+* `Int and Str` => 不允許多重繼承,或者`Int or Str`?
+* `: [1, 2]` => `: {1, 2}`?
+* `: [Int, 2]` => `: [Int; 2]`?
+* `[Int; Str]` => `(Int, Str)`(Tuple) 還是 `[Int: Str]`(Dict)?
+* `{x: Int}` => `{x = Int}`?
+* `{x = Int}!` => `{x = Int!}`?
+* `ref! immut_expr` => `ref! !immut_expr`?
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/TODO_warn.md b/doc/zh_TW/compiler/TODO_warn.md
new file mode 100644
index 00000000..1fff72b1
--- /dev/null
+++ b/doc/zh_TW/compiler/TODO_warn.md
@@ -0,0 +1,7 @@
+# 警告(尚未實現)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_warn.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+* `t = {(record type)}` => `T = {(record type)}`?(只有定義為常量的類型才能用于類型說明)
+* `{I: Int | ...}!` => `{I: Int! | ...}`
+* for/while 塊中的`return x`(`x != ()`) => `f::return`(外部塊)?
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/abandoned.md b/doc/zh_TW/compiler/abandoned.md
new file mode 100644
index 00000000..1ce62cce
--- /dev/null
+++ b/doc/zh_TW/compiler/abandoned.md
@@ -0,0 +1,12 @@
+# 廢棄/拒絕的語言規范
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/abandoned.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## 重載(臨時多態性)
+
+被放棄了,因為它可以用參數+子類型多態來代替,并且與Python的語義不兼容。 有關詳細信息,請參閱 [overload](../syntax/type/overloading.md) 文章。
+
+## 具有顯式生命周期的所有權系統
+
+原計劃引入 Rust 之類的所有權系統,但由于與 Python 的語義不兼容以及需要引入生命周期注解等復雜規范而被放棄,并且所有不可變對象都是 RC。托管的可變對象現在只有一個所有權.
+Dyne 沒有 C# 和 Nim 那樣的 GIL,策略是允許值對象和低級操作在安全范圍內。
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/architecture.md b/doc/zh_TW/compiler/architecture.md
new file mode 100644
index 00000000..30a908aa
--- /dev/null
+++ b/doc/zh_TW/compiler/architecture.md
@@ -0,0 +1,44 @@
+# `ergc` 的架構
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/architecture.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1)
+
+## 1. 掃描 Erg 腳本 (.er) 并生成 `TokenStream` (parser/lex.rs)
+
+* parser/lexer/Lexer 生成`TokenStream`(這是一個Token的迭代器,TokenStream可以通過lexer.collect()生成)
+ * `Lexer` 由 `Lexer::new` 或 `Lexer::from_str` 構造,其中 `Lexer::new` 從文件或命令選項中讀取代碼。
+ * `Lexer` 可以作為迭代器按順序生成令牌;如果您想一次獲得 `TokenStream`,請使用 `Lexer::lex`。
+ * `Lexer` 輸出 `LexError` 為錯誤,但 `LexError` 沒有足夠的信息顯示自己。如果要顯示錯誤,請使用 `LexerRunner` 轉換錯誤。
+ * 如果你想單獨使用 `Lexer`,也可以使用 `LexerRunner`;`Lexer` 只是一個迭代器,并沒有實現 `Runnable` 特性。
+ * `Runnable` 由 `LexerRunner`、`ParserRunner`、`Compiler` 和 `VirtualMachine` 實現。
+
+## 2. 轉換 `TokenStream` -> `AST` (parser/parse.rs)
+
+* `Parser` 和 `Lexer` 一樣,有兩個構造函數,`Parser::new` 和 `Parser::from_str`,而 `Parser::parse` 會給出 `AST`。
+* `AST` 是 `Vec` 的包裝器類型。
+
+### 2.5 脫糖 `AST`
+
+* 擴展嵌套變量 (`Desugarer::desugar_nest_vars_pattern`)
+* desugar 多模式定義語法(`Desugarer::desugar_multiple_pattern_def`)
+
+## 3. 類型檢查和推斷,轉換 `AST` -> `HIR` (compiler/lower.rs)
+
+* `HIR` 有每個變量的類型信息。它是用于“高級中間表示”的。
+* `HIR` 只保存變量的類型,但這已經足夠了。在極端情況下,這是因為 Erg 只有轉換(或運算符)應用程序的參數對象。
+* `ASTLower` 可以用與`Parser` 和`Lexer` 相同的方式構造。
+* 如果沒有錯誤發生,`ASTLowerer::lower` 將輸出 `HIR` 和 `CompileWarnings` 的元組。
+* `ASTLowerer`歸`Compiler`所有。與傳統結構不同,`ASTLowerer`處理代碼上下文并且不是一次性的。
+* 如果類型推斷的結果不完整(如果存在未知類型變量),名稱解析時會出錯。
+
+## 4. 檢查副作用(compiler/effectcheck.rs)
+
+## 4. 檢查所有權(compiler/memcheck.rs)
+
+## 5. 從`HIR`(compiler/codegen.rs)生成字節碼(`CodeObj`)
+
+* 根據表達式的類型信息,將執行量化子程序的名稱解析。
+
+##(6.(未來計劃)轉換字節碼 -> LLVM IR)
+
+* 字節碼是基于堆棧的,而 LLVM IR 是基于寄存器的。
+ 這個轉換過程會多出幾層中間過程。
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/errors.md b/doc/zh_TW/compiler/errors.md
new file mode 100644
index 00000000..1436942c
--- /dev/null
+++ b/doc/zh_TW/compiler/errors.md
@@ -0,0 +1,133 @@
+# Erg Compiler Errors
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/errors.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## AssignError
+
+嘗試重寫不可變變量時發生
+
+## AttributeError
+
+嘗試訪問不存在的屬性時發生
+
+## PurityError
+
+當您在不允許副作用的范圍內(函數、不可變類型等)編寫導致副作用的代碼時發生
+
+## MoveError
+
+嘗試訪問已移動的變量時發生
+
+## BorrowError
+
+在存在對對象的借用時嘗試獲取可變引用時發生
+
+## CyclicError
+
+當你有一個明顯不可阻擋的循環時發生
+
+```python
+i: Int = i
+
+f(): Int = g()
+g() = f()
+
+h(): Int = module::h()
+
+T = U
+U = T
+```
+
+## BytecodeError
+
+當加載的字節碼損壞時發生
+
+## CompileSystemError
+
+在編譯器內部發生錯誤時發生
+
+## EnvironmentError
+
+如果您在安裝期間沒有訪問權限,則會發生這種情況
+
+## FeatureError
+
+在檢測到未正式提供的實驗性功能時發生
+
+## ImportError
+
+## IndentationError
+
+檢測到不良縮進時發生
+派生自SyntaxError
+
+## NameError
+
+當您訪問不存在的變量時發生
+
+## NotImplementedError
+
+當您調用具有定義但沒有實現的 API 時發生
+派生自 TypeError
+
+## PatternError
+
+當檢測到非法模式時發生
+派生自SyntaxError
+
+## SyntaxError
+
+在檢測到錯誤語法時發生
+
+## TabError
+
+在使用制表符進行縮進/間距時發生
+派生自SyntaxError
+
+## TypeError
+
+當對象類型不匹配時發生
+
+## UnboundLocalError
+
+在定義之前使用變量時發生
+更準確地說,它發生在以前使用過在范圍內定義的變量時
+
+```python
+i = 0
+f x =
+ y = i + x
+ i = 1
+ y + i
+```
+
+在這段代碼中,`y = i + x` 中的 `i` 是一個未定義的變量
+但是,常量可以在定義之前在另一個函數中調用
+
+```python
+f() = g()
+g() = f()
+```
+
+## Erg Compiler Warnings
+
+## SyntaxWarning
+
+它在語法上很好,但是當我們檢測到冗余或不常見的代碼(不必要的 `()` 等)時就會發生這種情況
+
+```python
+if (True): # SyntaxWarning: unnecessary parentheses
+ ...
+```
+
+## DeprecationWarning
+
+在不推薦使用引用的對象時發生
+(開發人員在生成此警告時應始終提供替代方法作為提示)
+
+## FutureWarning
+
+當您檢測到將來可能導致問題的代碼時發生
+此警告是由版本兼容性問題(包括庫)以及語法和 API 的更改引起的
+
+## ImportWarning
diff --git a/doc/zh_TW/compiler/hir.md b/doc/zh_TW/compiler/hir.md
new file mode 100644
index 00000000..addefb11
--- /dev/null
+++ b/doc/zh_TW/compiler/hir.md
@@ -0,0 +1,150 @@
+# 高級中間表示(HIR, High-level Intermediate Representation)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/hir.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+HIR 是 Erg 編譯器從 AST 生成的結構
+此結構包含源代碼中每個表達式的完整類型信息,并且在語法上已脫糖
+AST與源代碼一一對應(純文本),但是HIR去掉了不必要的代碼信息,添加了省略的類型信息,所以HIR可以轉換為源代碼很難恢復
+讓我們在下面的代碼中查看 HIR 的示例
+
+```python
+v = ![]
+for! 0..10, i =>
+ v.push! i
+log v.sum()
+```
+
+從此代碼生成的 AST 如下所示:
+
+```python
+AST(Module[
+ VarDef{
+ sig: VarSignature{
+ pat: VarPattern::Ident(None, VarName("v")),
+ spec_t: None,
+ },
+ op: "=",
+ body: Block[
+ UnaryOp{
+ op: "!",
+ expr: Array([]),
+ },
+ ],
+ },
+ Call{
+ obj: Accessor::Local("for!"),
+ args: [
+ BinOp{
+ op: "..",
+ lhs: Literal(0),
+ rhs: Literal(10),
+ },
+ Lambda{
+ sig: LambdaSignature{
+ params: [
+ ParamSignature{
+ pat: ParamPattern::Name(VarName("i")),
+ },
+ ],
+ spec_ret_t: None,
+ },
+ body: Block[
+ Call{
+ obj: Accessor::Attr{"v", "push!"},
+ args: [
+ Accessor::Local("i"),
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ Call{
+ obj: Accessor::Local("log"),
+ args: [
+ Call{
+ obj: Accessor::Attr("v", "sum"),
+ args: [],
+ }
+ ],
+ }
+])
+```
+
+從 AST 生成的 HIR 如下所示:
+
+```python
+HIR(Module[
+ VarDef{
+ sig: VarSignature{
+ pat: VarPattern::Ident(None, Name("v")),
+ t: [0..10, _]!,
+ },
+ op: "=",
+ body: Block[
+ expr: UnaryOp{
+ op: "!",
+ expr: Array([]),
+ t: [0..10, 0]!,
+ },
+ ],
+ },
+ Call{
+ obj: Accessor::Local{
+ name: "for!",
+ t: (Range Nat, Nat => NoneType) => NoneType,
+ },
+ args: [
+ BinOp{
+ op: "..",
+ lhs: Literal(0),
+ rhs: Literal(10),
+ t: 0..10,
+ },
+ Lambda{
+ sig: LambdaSignature{
+ params: [
+ ParamSignature{
+ pat: ParamPattern::Name(Name("i")),
+ t: 0..10,
+ },
+ ],
+ t: 0..10 => NoneType,
+ },
+ body: Block[
+ Call{
+ obj: Accessor::Attr{
+ obj: Accessor::Local("v"),
+ field: "push!",
+ t: Ref!(Self![T ~> T, N ~> N+1]).(Nat) => NoneType,
+ },
+ args: [
+ Accessor::Local("i"),
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ Call{
+ obj: Accessor::Local{
+ name: "log",
+ t: ...Object => NoneType,
+ },
+ args: [
+ Call{
+ obj: Accessor::Attr{
+ obj: Accessor::Local("v"),
+ field: "sum",
+ t: [0..10, !_] -> Nat
+ },
+ args: [],
+ t: Nat
+ }
+ ],
+ }
+])
+```
+
+對象類型被推斷為盡可能小。 另一方面,子例程推斷實現存在的類型
+因此,實際參數的類型和形式參數的類型可能不匹配
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/index.md b/doc/zh_TW/compiler/index.md
new file mode 100644
index 00000000..33522b77
--- /dev/null
+++ b/doc/zh_TW/compiler/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/compiler/inference.md b/doc/zh_TW/compiler/inference.md
new file mode 100644
index 00000000..719e1707
--- /dev/null
+++ b/doc/zh_TW/compiler/inference.md
@@ -0,0 +1,440 @@
+# 類型推斷算法
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/inference.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+> __Warning__:此部分正在編輯中,可能包含一些錯誤
+
+顯示了下面使用的符號
+
+```python
+Free type variables (type, unbound): ?T, ?U, ...
+Free-type variables (values, unbound): ?a, ?b, ...
+type environment (Γ): { x: T, ... }
+Type assignment rule (S): { ?T --> T, ... }
+Type argument evaluation environment (E): { e -> e', ... }
+```
+
+我們以下面的代碼為例:
+
+```python
+v = ![]
+v.push! 1
+print! v
+```
+
+Erg 的類型推斷主要使用 Hindley-Milner 類型推斷算法(盡管已經進行了各種擴展)。具體而言,類型推斷是通過以下過程執行的。術語將在后面解釋。
+
+1. 推斷右值的類型(搜索)
+2. 實例化結果類型
+3. 如果是調用,執行類型替換(substitute)
+4. 解決已經單態化的特征
+5. 如果有類型變量值,求值/歸約(eval)
+6. 刪除鏈接類型變量(deref)
+7. 傳播可變依賴方法的變化
+8. 如果有左值并且是Callable,則泛化參數類型(generalize)
+9. 如果有左值,對(返回值)類型進行泛化(generalize)
+10. 如果是賦值,則在符號表(`Context`)中注冊類型信息(更新)
+
+具體操作如下。
+
+第 1 行。 Def{sig: v, block: ![]}
+ 獲取塊類型:
+ 獲取 UnaryOp 類型:
+ getArray 類型:`['T; 0]`
+ 實例化:`[?T; 0]`
+ (替代,評估被省略)
+ 更新:`Γ: {v: [?T; 0]!}`
+ 表達式 返回`NoneType`:OK
+
+第 2 行 CallMethod {obj: v, name: push!, args: [1]}
+ 獲取 obj 類型:`Array!(?T, 0)`
+ 搜索:`Γ Array!(?T, 0).push!({1})`
+ 得到:`= Array!('T ~> 'T, 'N ~> 'N+1).push!('T) => NoneType`
+ 實例化:`Array!(?T, ?N).push!(?T) => NoneType`
+ 替代(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!(Nat) => NoneType`
+ 評估: `Array!(Nat, 0 ~> 1).push!({1}) => NoneType`
+ 更新:`Γ:{v:[Nat; 1]!}`
+ 表達式 返回`NoneType`:OK
+
+第 3 行。調用 {obj: print!, args: [v]}
+ 獲取參數類型:`[[Nat; 1]!]`
+ 獲取 obj 類型:
+ 搜索:`Γ print!([Nat; 1]!)`
+ 得到:`= print!(...Object) => NoneType`
+ 表達式 返回`NoneType`:OK
+
+## 類型變量的實現
+
+類型變量最初在 [ty.rs](../../src/common/ty.rs) 的 `Type` 中表示如下。它現在以不同的方式實現,但本質上是相同的想法,所以我將以更天真的方式考慮這種實現。
+`RcCell` 是 `Rc>` 的包裝類型。
+
+```rust
+pub enum Type {
+ ...
+ Var(RcCell>), // a reference to the type of other expression, see docs/compiler/inference.md
+ ...
+}
+```
+
+類型變量可以通過將實體類型保存在外部字典中來實現,并且類型變量本身只有它的鍵。但是,據說使用 `RcCell` 的實現通常更有效(需要驗證,[來源](https://mobile.twitter.com/bd_gfngfn/status/1296719625086877696?s=21))。
+
+類型變量首先被初始化為 `Type::Var(RcCell::new(None))`。
+當分析代碼并確定類型時,會重寫此類型變量。
+如果內容直到最后都保持為 None ,它將是一個無法確定為具體類型的類型變量(當場)。例如,具有 `id x = x` 的 `x` 類型。
+我將這種狀態下的類型變量稱為 __Unbound 類型變量__(我不知道確切的術語)。另一方面,我們將分配了某種具體類型的變量稱為 __Linked 類型變量__。
+
+兩者都是自由類型變量(該術語顯然以“自由變量”命名)。這些是編譯器用于推理的類型變量。它之所以有這樣一個特殊的名字,是因為它不同于程序員指定類型的類型變量,例如 `id: 'T -> 'T` 中的 `'T`。
+
+未綁定類型變量表示為`?T`、`?U`。在類型論的上下文中,經常使用 α 和 β,但這一種是用來簡化輸入的。
+請注意,這是出于一般討論目的而采用的表示法,實際上并未使用字符串標識符實現。
+
+進入類型環境時,未綁定的類型變量 `Type::Var` 被替換為 `Type::MonoQuantVar`。這稱為 __quantified 類型變量__。這類似于程序員指定的類型變量,例如“T”。內容只是一個字符串,并沒有像自由類型變量那樣鏈接到具體類型的工具。
+
+用量化類型變量替換未綁定類型變量的操作稱為__generalization__(或泛化)。如果將其保留為未綁定類型變量,則類型將通過一次調用固定(例如,調用 `id True` 后,`id 1` 的返回類型將是 `Bool`),所以它必須是概括的。
+以這種方式,在類型環境中注冊了包含量化類型變量的通用定義。
+
+## 概括、類型方案、具體化
+
+讓我們將未綁定類型變量 `?T` 泛化為 `gen` 的操作表示。令生成的廣義類型變量為 `|T: Type| T`。
+在類型論中,量化類型,例如多相關類型 `α->α`,通過在它們前面加上 `?α.` 來區分(像 ? 這樣的符號稱為(通用)量詞。)。
+這樣的表示(例如`?α.α->α`)稱為類型方案。 Erg 中的類型方案表示為 `|T: Type| T -> T`。
+類型方案通常不被認為是一流的類型。以這種方式配置類型系統可以防止類型推斷起作用。但是,在Erg中,在一定條件下可以算是一流的類型。有關詳細信息,請參閱 [rank2 類型](../syntax/type/advanced/rank2type.md)。
+
+現在,當在使用它的類型推斷(例如,`id 1`,`id True`)中使用獲得的類型方案(例如`'T -> 'T(id's type scheme)`)時,必須釋放generalize。這種逆變換稱為 __instantiation__。我們將調用操作`inst`。
+
+```python
+gen ?T = 'T
+inst 'T = ?T (?T ? Γ)
+```
+
+重要的是,這兩個操作都替換了所有出現的類型變量。 例如,如果你實例化 `'T -> 'T`,你會得到 `?T -> ?T`。
+實例化需要替換 dict,但為了泛化,只需將 `?T` 與 `'T` 鏈接以替換它。
+
+之后,給出參數的類型以獲取目標類型。 此操作稱為類型替換,將用 `subst` 表示。
+此外,如果表達式是調用,則獲取返回類型的操作表示為 `subst_call_ret`。 第一個參數是參數類型列表,第二個參數是要分配的類型。
+
+類型替換規則 `{?T --> X}` 意味著將 `?T` 和 `X` 重寫為相同類型。 此操作稱為 __Unification__。 `X` 也可以是類型變量。
+[單獨部分](./unification.md) 中描述了詳細的統一算法。 我們將統一操作表示為“統一”。
+
+```python
+unify(?T, Int) == Ok(()) # ?T == (Int)
+
+# S為類型分配規則,T為適用類型
+subst(S: {?T --> X}, T: ?T -> ?T) == X -> X
+# Type assignment rules are {?T --> X, ?U --> T}
+subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y
+```
+
+## 半統一(semi-unification)
+
+統一的一種變體稱為半統一(__Semi-unification__)。 這是更新類型變量約束以滿足子類型關系的操作。
+在某些情況下,類型變量可能是統一的,也可能不是統一的,因此稱為“半”統一。
+
+例如,在參數分配期間會發生半統一。
+因為實際參數的類型必須是形式參數類型的子類型。
+如果參數類型是類型變量,我們需要更新子類型關系以滿足它。
+
+```python
+# 如果形參類型是T
+f(x: T): T = ...
+
+a: U
+# 必須為 U <: T,否則類型錯誤
+f(a)
+```
+
+## 泛化
+
+泛化不是一項簡單的任務。 當涉及多個作用域時,類型變量的“級別管理”就變得很有必要了。
+為了看到層級管理的必要性,我們首先確認沒有層級管理的類型推斷會導致問題。
+推斷以下匿名函數的類型。
+
+```python
+x ->
+ y = x
+ y
+```
+
+首先,Erg 分配類型變量如下:
+y 的類型也是未知的,但暫時未分配。
+
+```python
+x(: ?T) ->
+ y = x
+ y
+```
+
+首先要確定的是右值 x 的類型。 右值是一種“用途”,因此我們將其具體化。
+但是 x 的類型 `?T` 已經被實例化了,因為它是一個自由變量。 Yo`?T` 成為右值的類型。
+
+```python
+x(: ?T) ->
+ y = x (: inst ?T)
+ y
+```
+
+注冊為左值 y 的類型時進行泛化。 然而,正如我們稍后將看到的,這種概括是不完善的,并且會產生錯誤的結果。
+
+```python
+x(: ?T) ->
+ y(:gen?T) = x(:?T)
+ y
+```
+
+```python
+x(: ?T) ->
+ y(: 'T) = x
+ y
+```
+
+y 的類型現在是一個量化類型變量“T”。 在下一行中,立即使用 `y`。 具體的。
+
+```python
+x: ?T ->
+ y(: 'T) = x
+ y(: inst 'T)
+```
+
+請注意,實例化必須創建一個與任何已經存在的(自由)類型變量不同的(自由)類型變量(概括類似)。 這樣的類型變量稱為新類型變量。
+
+```python
+x: ?T ->
+ y = x
+ y(: ?U)
+```
+
+并查看生成的整個表達式的類型。 `?T -> ?U`。
+但顯然這個表達式應該是`?T -> ?T`,所以我們知道推理有問題。
+發生這種情況是因為我們沒有“級別管理”類型變量。
+
+所以我們用下面的符號來介紹類型變量的層次。 級別表示為自然數。
+
+```python
+# 普通類型變量
+?T<1>, ?T<2>, ...
+# 具有子類型約束的類型變量
+?T<1>(<:U) or ?T(<:U)<1>, ...
+```
+
+讓我們再嘗試一次:
+
+```python
+x ->
+ y = x
+ y
+```
+
+首先,按如下方式分配一個 leveled 類型變量: toplevel 級別為 1。隨著范圍的加深,級別增加。
+函數參數屬于內部范圍,因此它們比函數本身高一級。
+
+```python
+# level 1
+x (: ?T<2>) ->
+ # level 2
+ y = x
+ y
+```
+
+首先,實例化右值`x`。和以前一樣,沒有任何改變。
+
+```python
+x (: ?T<2>) ->
+ y = x (: inst ?T<2>)
+ y
+```
+
+這是關鍵。 這是分配給左值`y`的類型時的概括。
+早些時候,這里的結果很奇怪,所以我們將改變泛化算法。
+如果類型變量的級別小于或等于當前范圍的級別,則泛化使其保持不變。
+
+```python
+gen ?T = if n <= current_level, then= ?T, else= 'T
+```
+
+```python
+x (: ?T<2>) ->
+ # current_level = 2
+ y(: gen ?T<2>) = x(: ?T<2>)
+ y
+```
+
+That is, the lvalue `y` has type `?T<2>`.
+
+```python
+x (: ?T<2>) ->
+ # ↓ 不包括
+ y(: ?T<2>) = x
+ y
+```
+
+y 的類型現在是一個未綁定的類型變量 `?T<2>`。 具體如下幾行:但是 `y` 的類型沒有被概括,所以什么也沒有發生
+
+```python
+x (: ?T<2>) ->
+ y(: ?T<2>) = x
+ y (: inst ?T<2>)
+```
+
+```python
+x (: ?T<2>) ->
+ y = x
+ y (: ?T<2>)
+```
+
+我們成功獲得了正確的類型`?T<2> -> ?T<2>`。
+
+讓我們看另一個例子。 這是更一般的情況,具有函數/運算符應用程序和前向引用。
+
+```python
+fx, y = id(x) + y
+id x = x
+
+f10,1
+```
+
+讓我們逐行瀏覽它。
+
+在 `f` 的推斷過程中,會引用后面定義的函數常量 `id`。
+在這種情況下,在 `f` 之前插入一個假設的 `id` 聲明,并為其分配一個自由類型變量。
+注意此時類型變量的級別是`current_level`。 這是為了避免在其他函數中泛化。
+
+```python
+id: ?T<1> -> ?U<1>
+f x (: ?V<2>), y (: ?W<2>) =
+ id(x) (: subst_call_ret([inst ?V<2>], inst ?T<1> -> ?U<1>)) + y
+```
+
+類型變量之間的統一將高級類型變量替換為低級類型變量。
+如果級別相同,則無所謂。
+
+類型變量之間的半統一有點不同。
+不同級別的類型變量不得相互施加類型約束。
+
+```python
+# BAD
+f x (: ?V<2>), y (: ?W<2>) =
+ # ?V<2>(<: ?T<1>)
+ # ?T<1>(:> ?V<2>)
+ id(x) (: ?U<1>) + y (: ?W<2>)
+```
+
+這使得無法確定在何處實例化類型變量。
+對于 Type 類型變量,執行正常統一而不是半統一。
+也就是說,統一到下層。
+
+```python
+# OK
+f x (: ?V<2>), y (: ?W<2>) =
+ # ?V<2> --> ?T<1>
+ id(x) (: ?U<1>) + y (: ?W<2>)
+```
+
+```python
+f x (: ?T<1>), y (: ?W<2>) =
+ (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], inst |'L <: Add('R)| ('L, 'R) -> 'L .AddO)
+```
+
+```python
+f x (: ?T<1>), y (: ?W<2>) =
+ (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], (?L(<: Add(?R<2>))<2>, ?R<2 >) -> ?L<2>.AddO)
+```
+
+```python
+id: ?T<1> -> ?U<1>
+f x (: ?T<1>), y (: ?W<2>) =
+ # ?U<1>(<: Add(?W<2>)) # Inherit the constraints of ?L
+ # ?L<2> --> ?U<1>
+ # ?R<2> --> ?W<2> (not ?R(:> ?W), ?W(<: ?R))
+ (id(x) + x) (: ?U<1>.AddO)
+```
+
+```python
+# current_level = 1
+f(x, y) (: gen ?T<1>, gen ?W<2> -> gen ?U<1>.AddO) =
+ id(x) + x
+```
+
+```python
+id: ?T<1> -> ?U<1>
+f(x, y) (: |'W: Type| (?T<1>, 'W) -> gen ?U<1>(<: Add(?W<2>)).AddO) =
+ id(x) + x
+```
+
+```python
+f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) =
+ id(x) + x
+```
+
+定義時,提高層次,使其可以泛化。
+
+```python
+# ?T<1 -> 2>
+# ?U<1 -> 2>
+id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>)
+```
+
+如果已經分配了返回類型,則與結果類型統一(`?U<2> --> ?T<2>`)。
+
+```python
+# ?U<2> --> ?T<2>
+f(x, y) (: |'W: Type| (?T<2>, 'W) -> ?T<2>(<: Add(?W<2>)).AddO) =
+ id(x) + x
+# current_level = 1
+id(x) (: gen ?T<2> -> gen ?T<2>) = x (: ?T<2>)
+```
+
+如果類型變量已經被實例化為一個簡單的類型變量,
+依賴于它的類型變量也將是一個 Type 類型變量。
+廣義類型變量對于每個函數都是獨立的。
+
+```python
+f(x, y) (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) =
+ id(x) + x
+id(x) (: |'T: Type| 'T -> gen 'T) = x
+```
+
+```python
+f x, y (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) =
+ id(x) + y
+id(x) (: 'T -> 'T) = x
+
+f(10, 1) (: subst_call_ret([inst {10}, inst {1}], inst |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T .AddO)
+```
+
+```python
+f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<1>) -> ? T<1>.AddO))
+```
+
+類型變量綁定到具有實現的最小類型
+
+```python
+# ?T(:> {10} <: Add(?W<1>))<1>
+# ?W(:> {1})<1>
+# ?W(:> {1})<1> <: ?T<1> (:> {10}, <: Add(?W(:> {1})<1>))
+# serialize
+# {1} <: ?W<1> or {10} <: ?T<1> <: Add({1}) <: Add(?W<1>)
+# Add(?W)(:> ?V) 的最小實現特征是 Add(Nat) == Nat,因為 Add 相對于第一個參數是協變的
+# {10} <: ?W<1> or {1} <: ?T<1> <: Add(?W<1>) <: Add(Nat) == Nat
+# ?T(:> ?W(:> {10}) or {1}, <: Nat).AddO == Nat # 如果只有一個候選人,完成評估
+f(10, 1) (: (?W(:> {10}, <: Nat), ?W(:> {1})) -> Nat)
+# 程序到此結束,所以去掉類型變量
+f(10, 1) (: ({10}, {1}) -> Nat)
+```
+
+整個程序的結果類型是:
+
+```python
+f|W: Type, T <: Add(W)|(x: T, y: W): T.AddO = id(x) + y
+id|T: Type|(x: T): T = x
+
+f(10, 1): Nat
+```
+
+我還重印了原始的、未明確鍵入的程序。
+
+```python
+fx, y = id(x) + y
+id x = x
+
+f(10, 1)
+```
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/overview.md b/doc/zh_TW/compiler/overview.md
new file mode 100644
index 00000000..73061113
--- /dev/null
+++ b/doc/zh_TW/compiler/overview.md
@@ -0,0 +1,38 @@
+# `erg` 概覽
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/overview.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+我們將介紹每一層的功能以及特別重要的功能和方法。
+
+## 1. 詞法分析
+
+* `Lexer` 進行詞法分析。 `Lexer::next`(`Lexer`被實現為一個迭代器)負責詞法分析的主要邏輯。 `Token` 作為解析的結果輸出。
+
+## 2. 解析
+
+* `Parser` 進行解析。特別重要的是`Parser::parse_expr`。作為解析的結果,輸出作為`ast::Expr`的集合的`AST`。
+
+## 3. 脫糖
+
+* 脫糖由 `Desugarer` 完成。 `AST` 將被輸出。
+
+## 4. 類型檢查/類型推斷
+
+* `ASTLowerer` 進行打字。類型檢查主要由 `Context` 完成。尤其重要的是 `Context::supertype_of`(確定子類型關系)、`Context::unify/sub_unify`(統一/半統一類型變量)、`Context::init_builtin_*`(定義內置 API)。 `HIR` 作為分析結果輸出。
+
+## 5. 副作用檢查
+
+* `SideEffectChecker` 可以。
+
+## 6. 所有權檢查
+
+* `OwnershipChecker` 可以。
+
+## 7. 字節碼生成
+
+* `CodeGenerator` 將 `HIR` 轉換為 `CodeObj`。 `CodeObj` 保存字節碼和執行配置。特別重要的是`CodeGenerator::compile_expr`。
+
+---
+
+* 以上所有的處理都是由`Compiler`作為一個門面組合起來的。
+* 當然 Python 會執行生成的字節碼,稱為 `DummyVM`。
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/parsing.md b/doc/zh_TW/compiler/parsing.md
new file mode 100644
index 00000000..3d6d4600
--- /dev/null
+++ b/doc/zh_TW/compiler/parsing.md
@@ -0,0 +1,35 @@
+# 解析 Erg 語言
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/parsing.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 空格的處理
+
+Erg語法的一個特點是它對空間敏感。
+這是為了彌補因省略`()`而造成的表達力損失。在 Nim 中可以找到類似的語法,它也允許省略 `()`。
+
+```python
+f +1 == f(+1)
+f + 1 == `+`(f, 1)
+f (1,) == f((1,))
+f(1,) == f(1)
+(f () -> ...) == f(() -> ...)
+(f() -> ...) == (f() -> ...)
+```
+
+## 左值,右值
+
+在 Erg 中,左側的值并不像 `=` 的左側那么簡單。
+事實上,`=` 左側有一個右值(非常令人困惑),而 `=` 右側有一個左值。
+右值中甚至可以有左值。
+
+```python
+# i 是左邊的值,Array(Int) 和 [1, 2, 3] 是右邊的值
+i: Array(Int) = [1, 2, 3]
+# `[1, 2, 3].iter().map i -> i + 1`是右邊的值,但是->左邊的i是左邊的值
+a = [1, 2, 3].iter().map i -> i + 1
+# {x = 1; y = 2} 是右側值,但 x, y 是左側值
+r = {x = 1; y = 2}
+```
+
+左側和右側值的精確定義是“如果它是可評估的,則為右側值,否則為左側值”。
+例如,考慮代碼 ``i = 1; i``,其中第二個 `i` 是右側值,因為它是可評估的,但第一個 `i` 是左側值。
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/refinement_subtyping.md b/doc/zh_TW/compiler/refinement_subtyping.md
new file mode 100644
index 00000000..5fb30dae
--- /dev/null
+++ b/doc/zh_TW/compiler/refinement_subtyping.md
@@ -0,0 +1,149 @@
+# 篩子類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/refinement_subtyping.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
+{I: Int | I >= 0}
+{S: StrWithLen N | N >= 1}
+{T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0}
+```
+
+Erg 通過將 Enum 和 Interval 類型轉換為篩選類型來實現類型確定。
+
+## 轉換為篩型
+
+在 [Sieve types] 一節中,我們說過區間類型和枚舉類型是 sieve 類型的語法糖。每個轉換如下。
+
+* {0} -> {I: Int | I == 0}
+* {0, 1} -> {I: Int | I == 0 or I == 1}
+* 1.._ -> {I: Int | I >= 1}
+* 1<.._ -> {I: Int | I > 1} -> {I: Int | I >= 2}
+* {0} or 1.._ -> {I: Int | I == 0 or I >= 1}
+* {0} or {-3, -2} or 1.._ -> {I: Int | I == 0 or (I == -2 or I == -3) or I >= 1}
+* {0} and {-3, 0} -> {I: Int | I == 0 and (I == -3 or I == 0)}
+* {0} not {-3, 0} or 1.._ -> {I: Int | I == 0 and not (I == -3 or I == 0) or I >= 1}
+
+## 篩型檢測
+
+描述了一種用于確定篩類型 A 是否是另一篩類型 B 的子類型的算法。正式地,(所有)子類型定義如下:
+
+```console
+A <: B <=> ?a∈A; a∈B
+```
+
+具體而言,應用以下推理規則。假定布爾表達式是簡化的。
+
+* 間隔規則(從類型定義自動完成)
+ * `Nat` => `{I: Int | I >= 0}`
+* 圍捕規則
+ * `{I: Int | I < n}` => `{I: Int | I <= n-1}`
+ * `{I: Int | I > n}` => `{I: Int | I >= n+1}`
+ * `{R: Ratio | R < n}` => `{R: Ratio | R <= n-ε}`
+ * `{R: Ratio | R > n}` => `{R: Ratio | R >= n+ε}`
+* 反轉規則
+ * `{A not B}` => `{A and (not B)}`
+* 德摩根規則
+ * `{not (A or B)}` => `{not A and not B}`
+ * `{not (A and B)}` => `{not A or not B}`
+* 分配規則
+ * `{A and (B or C)} <: D` => `{(A and B) or (A and C)} <: D` => `({A and B} <: D) and ( {A and C} <: D)`
+ * `{(A or B) and C} <: D` => `{(C and A) or (C and B)} <: D` => `({C and A} <: D) and ( {C and B} <: D)`
+ * `D <: {A or (B and C)}` => `D <: {(A or B) and (A or C)}` => `(D <: {A or B}) and ( D <: {A or C})`
+ * `D <: {(A and B) or C}` => `D <: {(C or A) and (C or B)}` => `(D <: {C or A}) and ( D <: {C or B})`
+ * `{A or B} <: C` => `({A} <: C) and ({B} <: C)`
+ * `A <: {B and C}` => `(A <: {B}) and (A <: {C})`
+* 終止規則
+ * {I: T | ...} <: T = True
+ * {} <: _ = True
+ * _ <: {...} = True
+ * {...} <: _ = False
+ * _ <: {} == False
+ * {I >= a and I <= b} (a < b) <: {I >= c} = (a >= c)
+ * {I >= a and I <= b} (a < b) <: {I <= d} = (b <= d)
+ * {I >= a} <: {I >= c or I <= d} (c >= d) = (a >= c)
+ * {I <= b} <: {I >= c or I <= d} (c >= d) = (b <= d)
+ * {I >= a and I <= b} (a <= b) <: {I >= c or I <= d} (c > d) = ((a >= c) or (b <= d ))
+ * 基本公式
+ * {I >= l} <: {I >= r} = (l >= r)
+ * {I <= l} <: {I <= r} = (l <= r)
+ * {I >= l} <: {I <= r} = False
+ * {I <= l} <: {I >= r} = False
+
+布爾表達式的簡化規則如下。 min, max 不能被刪除。此外,多個 or, and 被轉換為嵌套的 min, max。
+
+* 組合規則
+ * `I == a` => `I >= a 和 I <= a`
+ * `i != a` => `I >= a+1 或 I <= a-1`
+* 一致性規則
+ * `I >= a 或 I <= b (a < b)` == `{...}`
+* 恒常規則
+ * `I >= a 和 I <= b (a > b)` == `{}`
+* 替換規則
+ * 以 `I >= n` 和 `I <= n` 的順序替換順序表達式。
+* 擴展規則
+ * `I == n 或 I >= n+1` => `I >= n`
+ * `I == n 或 I <= n-1` => `I <= n`
+* 最大規則
+ * `I <= m 或 I <= n` => `I <= max(m, n)`
+ * `I >= m 和 I >= n` => `I >= max(m, n)`
+* 最低規則
+ * `I >= m 或 I >= n` => `I >= min(m, n)`
+ * `I <= m 和 I <= n` => `I <= min(m, n)`
+* 淘汰規則
+ * 當 `I >= a (n >= a)` 或 `I <= b (n <= b)` 或 `I == n` 在右側時,左側的 `I == n` 被刪除能夠。
+ * 如果無法消除所有左手方程,則為 False
+
+例如
+
+```python
+1.._<: Nat
+=> {I: Int | I >= 1} <: {I: Int | I >= 0}
+=> {I >= 1} <: {I >= 0}
+=> (I >= 0 => I >= 1)
+=> 1 >= 0
+=> True
+# {I >= l} <: {I >= r} == (l >= r)
+# {I <= l} <: {I <= r} == (l <= r)
+```
+
+```python
+{I: Int | I >= 0} <: {I: Int | I >= 1 or I <= -3}
+=> {I >= 0} <: {I >= 1 or I <= -3}
+=> {I >= 0} <: {I >= 1} or {I >= 0} <: {I <= -3}
+=> False or False
+=> False
+```
+
+```python
+{I: Int | I >= 0} <: {I: Int | I >= -3 and I <= 1}
+=> {I >= 0} <: {I >= -3 and I <= 1}
+=> {I >= 0} <: {I >= -3} and {I >= 0} <: {I <= 1}
+=> True and False
+=> False
+```
+
+```python
+{I: Int | I >= 2 or I == -2 or I <= -4} <: {I: Int | I >= 1 or I <= -1}
+=> {I >= 2 or I <= -4 or I == -2} <: {I >= 1 or I <= -1}
+=> {I >= 2 or I <= -4} <: {I >= 1 or I <= -1}
+ and {I == -2} <: {I >= 1 or I <= -1}
+=> {I >= 2} <: {I >= 1 or I <= -1}
+ and {I <= -4} <: {I >= 1 or I <= -1}
+ and
+ {I == -2} <: {I >= 1}
+ or {I == -2} <: {I <= -1}
+=> {I >= 2} <: {I >= 1}
+ or {I >= 2} <: {I <= -1}
+ and
+ {I <= -4} <: {I >= 1}
+ or {I <= -4} <: {I <= -1}
+ and
+ False or True
+=> True or False
+ and
+ False or True
+ and
+ True
+=> True and True
+=> True
+```
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/trait_method_resolving.md b/doc/zh_TW/compiler/trait_method_resolving.md
new file mode 100644
index 00000000..68fa15ec
--- /dev/null
+++ b/doc/zh_TW/compiler/trait_method_resolving.md
@@ -0,0 +1,97 @@
+# 解決補丁方法
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/trait_method_resolving.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`Nat` 是零個或多個`Int`,`Int` 的子類型。
+`Nat` 在 Python 類層次結構中不存在。 我想知道 Erg 是如何解決這個補丁方法的?
+
+```python
+1.times do:
+ log "hello world"
+```
+
+`.times` 是一種 `NatImpl` 補丁方法。
+由于`1`是`Int`的一個實例,首先通過跟蹤`Int`的MRO(方法解析順序)來搜索它。
+Erg 在 `Int` 的 MRO 中有 `Int`、`Object`。它來自 Python(Python 中的`int.__mro__ == [int, object]`)。
+`.times` 方法在它們中都不存在。現在讓我們探索那個子類型。
+
+~
+
+整數顯然應該在其超類型中包含實數、復數甚至整數,但這一事實并沒有出現在 Python 兼容層中。
+然而,`1 in Complex` 和 `1 in Num` 在 Erg 中實際上是 `True`。
+至于`Complex`,即使是與`Int`沒有繼承關系的類,也被判斷為類型兼容。這到底是怎么回事?
+
+~
+
+一個對象有無數種它所屬的類型。
+但是我們真的只需要考慮帶有方法的類型,即帶有名稱的類型。
+
+Erg 編譯器有一個補丁類型的哈希圖,其中包含所有提供的方法及其實現。
+每次定義新類型時都會更新此表。
+
+```python
+provided_method_table = {
+ ...
+ "foo": [Foo],
+ ...
+ ".times": [Nat, Foo],
+ ...
+}
+```
+
+具有 `.times` 方法的類型是 `Nat`、`Foo`。從這些中,找到與“{1}”類型匹配的一個。
+有兩種類型的符合性確定。它們是篩式判斷和記錄式判斷。這是通過篩子類型確定來完成的。
+
+##篩型確定
+
+檢查候選類型是否與 `1` 的類型 `{1}` 兼容。與“{1}”兼容的篩子類型有“{0, 1}”、“0..9”等。
+有限元代數類型,例如 `0..1 或 3..4`、`-1..2 和 0..3`,在聲明為基本類型(即 {0, 1, 3, 4}`,`{0, 1, 2}`)。
+在這種情況下,`Nat` 是 `0.._ == {I: Int | I >= 0}`,所以 `{1}` 與 `Nat` 兼容。
+
+## 確定記錄類型
+
+檢查候選類型是否與 `Int` 兼容,1 類。
+其他是`Int`的修復程序并且`Int`具有所有必需屬性的也是兼容的。
+
+~
+
+所以`Nat`適合。但是,如果 `Foo` 也匹配,則由 `Nat` 和 `Foo` 之間的包含關系決定。
+即,選擇子類型方法。
+如果兩者之間沒有包含關系,則會發生編譯錯誤(這是一種安全措施,防止違背程序員的意圖執行方法)。
+要消除錯誤,您需要明確指定補丁。
+
+```python
+o.method(x) -> P.method(o, x)
+```
+
+## 通用方法解析修補程序
+
+像這樣定義一個補丁:
+
+```python
+FnType T: Type = Patch T -> T
+FnType.type = T
+```
+
+在 `FnType` 補丁下可以使用如下代碼。 我想知道這將如何解決。
+
+```python
+assert (Int -> Int).type == Int
+```
+
+首先,`FnType(T)` 以下列格式注冊到`provided_method_table` 中。
+
+```python
+provided_method_table = {
+ ...
+ "type": [FnType(T)],
+ ...
+}
+```
+
+`FnType(T)` 檢查匹配類型。 在這種情況下,`FnType(T)` 補丁類型是 `Type -> Type`。
+這匹配 `Int -> Int`。 如果合適,進行單態化和替換(取 `T -> T` 和 `Int -> Int`、`{T => Int}` 的差異)。
+
+```python
+assert FnType(Int).type == Int
+```
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/transpile.md b/doc/zh_TW/compiler/transpile.md
new file mode 100644
index 00000000..5cffba68
--- /dev/null
+++ b/doc/zh_TW/compiler/transpile.md
@@ -0,0 +1,92 @@
+# Erg 代碼如何轉譯成 Python 代碼?
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/transpile.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+準確地說,Erg 代碼被轉譯為 Python 字節碼。
+但是,由于 Python 字節碼幾乎可以重構為 Python 代碼,因此這里以等效的 Python 代碼為例。
+順便說一句,這里展示的示例是低優化級別。
+更高級的優化消除了不需要實例化的東西。
+
+## 記錄,記錄類型
+
+它將被轉譯為一個命名元組。
+對于 namedtuple,請參閱 [此處](https://docs.python.jp/3/library/collections.html#collections.namedtuple)。
+有一個類似的函數,dataclass,但是由于 `__eq__` 和 `__hash__` 的自動實現,dataclass 的性能略有下降。
+
+```python
+Employee = Class {.name = Str; .id = Int}
+
+employee = Employee.new({.name = "John Smith"; .id = 100})
+
+assert employee.name == "John Smith"
+```
+
+```python
+from typing import NamedTuple
+
+class Employee(NamedTuple):
+ __records__ = ['name', 'id']
+ name: str
+ id: int
+
+employee = Employee('John Smith', 100)
+
+assert employee.name == 'John Smith'
+```
+
+如果可以進一步優化,它也將轉換為簡單的元組。
+
+## 多態類型
+
+> 在制品
+
+## 即時范圍
+
+如果沒有發生命名空間沖突,它只會被破壞和擴展。
+`x::y` 等名稱在字節碼中使用,不能與 Python 代碼關聯,但如果強制表示,則會如下所示。
+
+```python
+x =
+ y = 1
+ y+1
+```
+
+```python
+x::y = 1
+x = x::y + 1
+```
+
+萬一發生沖突,定義和使用只能在內部引用的函數。
+
+```python
+x =
+ y = 1
+ y+1
+```
+
+```python
+def _():
+ x=1
+ y = x
+ return y + 1
+x = _()
+```
+
+## 可見性
+
+它對公共變量沒有任何作用,因為它是 Python 的默認值。
+私有變量由 mangling 處理。
+
+```python
+x=1
+y =
+ x = 2
+ assert module::x == 2
+```
+
+```python
+module::x = 1
+y::x = 2
+assert module::x == 2
+y = None
+```
\ No newline at end of file
diff --git a/doc/zh_TW/compiler/type_var_normalization.md b/doc/zh_TW/compiler/type_var_normalization.md
new file mode 100644
index 00000000..fa6e704e
--- /dev/null
+++ b/doc/zh_TW/compiler/type_var_normalization.md
@@ -0,0 +1,41 @@
+# 歸一化
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/type_var_normalization.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+* Erg 的類型參數規范化基于 SymPy 的簡化函數。
+
+例如,當您定義 `concat: |T, M, N|([T; M], [T; N] -> [T; M+N])` 時,您可以匹配類型變量和參數而無需實例化它們.必須作出判斷。
+平等判斷自然有其局限性,但目前可能的判斷及其方法如下。
+
+* 加法/乘法對稱性:
+
+ `n+m == m+n`
+
+ 類型變量被排序和規范化為字符串。
+
+* 加法、乘法、減法和除法等價:
+
+ `n+n == 2*n`
+
+ 歸一化為 Σ[c] x == c*x,其中 c 是一個常數。
+ 常量通過將它們放在二進制操作的左側進行標準化。
+
+* 雙重表達式的相等性:
+
+ `n+m+l == m+n+l == l+m+n == ...`
+ `n+m*l == m*l+n`
+
+ 通過排序歸一化確定。
+ 乘法和除法塊放置在加法和減法的左側。通過比較最左側的類型變量對塊進行排序。
+
+* 基本不等式:
+
+ `n > m -> m + 1 > n`
+
+* 平等:
+
+ `n >= m 和 m >= n -> m == n`
+
+* 不等式的傳遞性:
+
+ `n > 0 -> n > -1`
\ No newline at end of file
diff --git a/doc/zh_TW/dev_guide/branches.md b/doc/zh_TW/dev_guide/branches.md
new file mode 100644
index 00000000..0d39107e
--- /dev/null
+++ b/doc/zh_TW/dev_guide/branches.md
@@ -0,0 +1,37 @@
+# 分支機構命名和運營策略
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/branches.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1)
+
+## main
+
+* 主要開發分支
+* 必須滿足以下條件
+
+* 編譯成功
+
+## beta(目前不創建)
+
+* 最新的 Beta 版本
+* 必須滿足以下條件
+
+* 編譯成功
+* 所有測試都會成功
+
+## feature-*
+
+* 開發特定功能的分支
+* 切開 main
+
+* 沒有條件
+
+## issue-*
+
+* 解決特定 issue 的分支
+
+* 沒有條件
+
+## fix-*
+
+* 修復特定錯誤的分支(如果該問題是一個錯誤,則代替`issue-*`創建)。
+
+* 沒有條件。
\ No newline at end of file
diff --git a/doc/zh_TW/dev_guide/build_features.md b/doc/zh_TW/dev_guide/build_features.md
new file mode 100644
index 00000000..49731e40
--- /dev/null
+++ b/doc/zh_TW/dev_guide/build_features.md
@@ -0,0 +1,23 @@
+# `erg` 構建功能
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/build_features.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 調試
+
+進入調試模式。結果,Erg 內部的行為順序顯示在日志中。
+獨立于 Rust 的 `debug_assertions` 標志。
+
+## japanese
+
+將系統語言設置為日語。
+Erg 內部選項、幫助(幫助、版權、許可證等)和錯誤顯示為日語。
+
+## simplified_chinese
+
+將系統語言設置為簡體中文。
+Erg 內部選項、幫助(幫助、版權、許可證等)和錯誤顯示為簡體中文。
+
+## traditional_chinese
+
+將系統語言設置為繁體中文。
+Erg 內部選項、幫助(幫助、版權、許可證等)和錯誤顯示為繁體中文。
\ No newline at end of file
diff --git a/doc/zh_TW/dev_guide/directories.md b/doc/zh_TW/dev_guide/directories.md
new file mode 100644
index 00000000..fa2cd397
--- /dev/null
+++ b/doc/zh_TW/dev_guide/directories.md
@@ -0,0 +1,26 @@
+# Erg存儲表結構
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/directories.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1)
+
+```console
+ └─┬ assets:圖片等
+ ├─ CODE_OF_CONDUCT:行為準則
+ ├─┬ compiler
+ │ ├─ erg_common:通用工具
+ │ ├─ erg_compiler
+ │ └─ erg_parser:解析器
+ ├─┬ doc: 文檔
+ │ ├─┬ CN
+ │ │ ├─ API:Erg標準API
+ │ │ ├─ compiler:關于編譯器實現
+ │ │ ├─ dev_guide:開發者和貢獻者指南
+ │ │ ├─ python:Erg開發必備的Python知識
+ │ │ ├─ syntax:Erg語法
+ │ │ └─ tools:Erg命令行工具
+ │ └─┬ JA
+ │ ...
+ ├─ examples:示例代碼
+ ├─ library:Erg腳本庫
+ ├─ src:main.rs和驅動所在目錄
+ └─ tests:測試代碼
+```
\ No newline at end of file
diff --git a/doc/zh_TW/dev_guide/doc_guideline.md b/doc/zh_TW/dev_guide/doc_guideline.md
new file mode 100644
index 00000000..30f29259
--- /dev/null
+++ b/doc/zh_TW/dev_guide/doc_guideline.md
@@ -0,0 +1,15 @@
+# 格式
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/doc_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+任何不符合以下規則的文件都將得到更正。
+
+* 以某種語氣寫代碼注釋或內部文檔。
+* 向外部(普通用戶)展示的文檔應該越來越多地編寫。
+* 始終包含定義、含義或文檔中首次出現的術語的鏈接。
+* 僅對理解正文所必需的補充句子使用括號作為附加條件,對于理解正文不是必需的句子使用腳注[1 ]( #1)。
+* 如果文檔內容過時,按照【此方法】更新(https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)。
+
+---
+
+1 參見這里了解如何編寫腳注。[?](#f1)
\ No newline at end of file
diff --git a/doc/zh_TW/dev_guide/env.md b/doc/zh_TW/dev_guide/env.md
new file mode 100644
index 00000000..43511997
--- /dev/null
+++ b/doc/zh_TW/dev_guide/env.md
@@ -0,0 +1,21 @@
+# 開發環境
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## 你需要安裝什么
+
+* Rust(與 rustup 一起安裝)
+
+ * 版本 >= 1.63.0
+ * 2021年版
+
+* [預提交](https://pre-commit.com/)
+
+* Python3 解釋器
+
+## 推薦
+
+* 編輯器:Visual Studio Code
+* VSCode 擴展:Rust-analyzer、GitLens、Git Graph、GitHub Pull Requests and Issues、Markdown All in One、markdownlint
+* 操作系統:Windows 10/11 | Ubuntu 20.04/22.04 | Mac OS Monterey
+* 其他:pyenv、模具
\ No newline at end of file
diff --git a/doc/zh_TW/dev_guide/faq_syntax.md b/doc/zh_TW/dev_guide/faq_syntax.md
new file mode 100644
index 00000000..68d760b8
--- /dev/null
+++ b/doc/zh_TW/dev_guide/faq_syntax.md
@@ -0,0 +1,106 @@
+# Erg design's "Why" and Answers
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/faq_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 當我們有所有權系統時,為什么要與 GC 共存?
+
+因為 Erg 推出所有權系統的動機并不是為了 Rust 那樣的“不依賴 GC 的內存管理”。最初,由于 Erg 是一種語言,目前使用 Python VM,因此最終仍使用 GC。Erg 引入產權系統的目標是“可變狀態的局部化”。在 Erg 中,可變對象具有所有權概念。這是根據共享可變狀態容易成為 bug 的溫床,甚至是類型安全性的侵犯(詳見)來判斷的。
+
+## 為什么類型參數周圍的括號不是 <> 或 []?
+
+因為在和中會發生語法沖突。
+
+```python
+# []版
+id[T: Type] [t]: [T] = t
+y = id[Int] # 這是一個功能嗎?
+# <>版
+id {t: T} = t
+y = (id 1) # 這是一個元組嗎?
+# {}版
+id{T: Type} {t: T} = t
+y = id{Int} # 這是一個功能嗎?
+# ||版
+id|T: Type| t: T = t
+y = id|Int| # OK
+```
+
+## {i=1} 的類型為 {i=Int},但在 OCaml 等環境中為 {i:Int}。為什么 Erg 采用前者的語法?
+
+Erg 設計為將類型本身也視為值。
+
+```python
+A = [Int; 3]
+assert A[2] == Int
+T = (Int, Str)
+assert T.1 == Str
+D = {Int: Str}
+assert D[Int] == Str
+S = {.i = Int}
+assert S.i == Int
+```
+
+## 你打算在 Erg 中實現宏嗎?
+
+目前沒有。宏觀大致分為四個目的。第一個是編譯時計算。這在 Erg 中由編譯時函數負責。第二,代碼執行的延遲。這可以用 do 塊來代替。第三個是處理通用化,對此多相關數和全稱類型是比宏觀更好的解決方案。第四個是自動生成代碼,但這會造成可讀性的下降,所以我們不敢在 Erg 中實現。因此,宏的大部分功能都由 Erg 型系統承擔,因此沒有動力進行部署。
+
+## 為什么 Erg 沒有例外機制?
+
+在許多情況下,錯誤處理類型是更好的解決方案。類型 是一種錯誤處理方法,通常在較新的編程語言中使用。
+
+在 Erg 中,運算符使你可以在不太注意錯誤的情況下編寫。
+
+```python
+read_file!() =
+ f = open!("foo.txt")? # 如果失敗則立即返回錯誤,所以 f 是文件類型
+ f.read_all!()
+
+# 也可以使用 try 過程捕獲類似的異常
+try!:
+ do!
+ s = read_file!()?
+ print! s
+ e =>
+ # 發生錯誤時執行的塊
+ print! e
+ exit 1
+```
+
+在引入 Python 函數時,缺省情況下,所有函數都被視為包含異常,返回類型為。如果你知道不調度異常,請在 中指明。
+
+此外,Erg 沒有引入異常機制的另一個原因是它計劃引入并行編程的功能。這是因為異常機制與并行執行不兼容(例如,如果并行執行導致多個異常,則很難處理)。
+
+## Erg 似乎消除了 Python 被認為是壞做法的功能,但為什么沒有取消繼承?
+
+Python 的庫中有一些類設計為繼承,如果完全取消繼承,這些操作就會出現問題。然而,由于 Erg 的類默認為 final,并且原則上禁止多重和多層繼承,因此繼承的使用相對安全。
+
+## 為什么多相關數的子類型推理默認指向記名trait?
+
+默認情況下,指向結構托盤會使類型指定變得復雜,并且可能會混合程序員的非預期行為。
+
+```python
+# 如果 T 是結構特征的子類型...
+# f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T
+f|T| x, y: T = x + y - x
+# T 是名義特征的子類型
+# g: |T <: Add() and Sub()| (T, T) -> T
+g|T| x, y: T = x + y - x
+```
+
+## Erg 是否實現了定義自己的運算符的功能?
+
+A:沒有那個計劃。最重要的原因是,如果允許定義自己的運算符,就會出現如何處理組合順序的問題。可以定義自己的運算符的 Scala 和 Haskell 等都有不同的對應,但這可以看作是可能產生解釋差異的語法的證據。此外,獨立運算符還有一個缺點,那就是可能產生可讀性較低的代碼。
+
+## 為什么 Erg 取消了 += 這樣的擴展賦值運算符?
+
+首先,Erg 中沒有變量的可變性。也就是不能重新賦值。一旦對象與一個變量關聯,它將一直綁定到該變量,直到它脫離作用域并被釋放。在 Erg 中,可變性是指對象的可變性。明白了這個,故事就簡單了。例如,表示 ,但由于變量是不可重新賦值的,因此這種語法是非法的。還有一個 Erg 的設計原則是運算符沒有副作用。Python 通常也是如此,但對于某些對象(如 Dict),擴展賦值運算符會更改對象的內部狀態。這算不上是一個很漂亮的設計。因此,擴展賦值運算符被完全廢棄。
+
+## 為什么 Erg 在語法上特別對待有副作用的過程?
+
+副作用的局部化是代碼維護的一個關鍵因素。
+
+但是,確實也不是沒有方法可以不在語言上特殊對待副作用。例如,可以用代數效果(類型系統上的功能)替代過程。但這樣的合一并不總是正確的。例如,Haskell 沒有對字符串進行特殊處理,只是一個字符數組,但這種抽象是錯誤的。
+
+什么情況下,可以說合一化是錯的?一個指標是“是否會因其合一而難以看到錯誤信息”。Erg 設計師發現,將副作用特殊處理會使錯誤消息更容易閱讀。
+
+Erg 有一個強大的類型系統,但并不是所有的類型都決定了它。如果這樣做了,你的下場就跟 Java 試圖用類來控制一切一樣。
\ No newline at end of file
diff --git a/doc/zh_TW/dev_guide/i18n_messages.md b/doc/zh_TW/dev_guide/i18n_messages.md
new file mode 100644
index 00000000..f02827b9
--- /dev/null
+++ b/doc/zh_TW/dev_guide/i18n_messages.md
@@ -0,0 +1,57 @@
+# 多語言錯誤信息
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/i18n_messages.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+Erg 正在推動消息(開始、選項、文檔、提示、警告、錯誤消息等)的多語言化。如果你不熟悉 Rust 或 Erg,也可以參與此項目。請務必配合。
+
+以下是多語種方法的說明。
+
+## 查找`switch_lang!`
+
+在 Erg 源代碼中找到(使用 grep 或編輯器的搜索功能)。我們應該能找到下面這樣的東西。
+
+```rust
+switch_lang!(
+ "japanese" => format!("この機能({name})はまだ正式に提供されていません"),
+ "english" => format!("this feature({name}) is not implemented yet"),
+),
+```
+
+此消息目前僅支持日語和英語。讓我們嘗試添加簡體消息。
+
+## 添加消息
+
+請在查看其他語言內容的同時添加翻譯消息。最后不要忘記逗號(,)。
+
+```rust
+switch_lang!(
+ "japanese" => format!("この機能({name})はまだ正式に提供されていません"),
+ "simplified_chinese" => format!("該功能({name})還沒有正式提供"),
+ "english" => format!("this feature({name}) is not implemented yet"),
+),
+```
+
+另外,英語是默認設置,一定要排在最后。
+
+`{name}`部分是 Rust 的格式化功能,允許你將變量的內容(`name`)嵌入到字符串中。
+
+## 構建
+
+現在,我們使用選項構建它。
+
+
+
+你做到了!
+
+## FAQ
+
+Q:像這樣的指定是什么意思?A:{RED} 及更高版本將顯示為紅色。重新啟動交互渲染。
+
+Q:如果想添加自己的語言,該如何替換部分?答:目前支持以下語言。
+
+* "english"(默認設置)
+* "japanese" (日語)
+* "simplified_chinese" (簡體中文)
+* "traditional_chinese" (繁體中文)
+
+如果你想添加其他語言,請提出請求。
\ No newline at end of file
diff --git a/doc/zh_TW/dev_guide/index.md b/doc/zh_TW/dev_guide/index.md
new file mode 100644
index 00000000..0e41be9e
--- /dev/null
+++ b/doc/zh_TW/dev_guide/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/index.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96)
+
diff --git a/doc/zh_TW/dev_guide/rust_code_guideline.md b/doc/zh_TW/dev_guide/rust_code_guideline.md
new file mode 100644
index 00000000..93811890
--- /dev/null
+++ b/doc/zh_TW/dev_guide/rust_code_guideline.md
@@ -0,0 +1,25 @@
+# Rust 代碼指南
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/rust_code_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+## 本地規則
+
+* 使用 `log!` 進行調試輸出(使用 `println!` 等進行輸出處理,這也是發布所必需的)。
+* 未使用或內部變量/方法(私有且僅用于特定功能)必須以 `_` 為前綴。如果要避免與保留字沖突,請在末尾添加一個`_`。
+
+## 推薦代碼
+
+* 定義和使用特定領域的枚舉而不是數字枚舉或布爾值。
+* 將訪問修飾符保持在最低限度。即使在發布時也要優先使用 `pub(mod)` 或 `pub(crate)`。
+* 將 for 表達式中的可迭代對象顯式轉換為迭代器(`for i in x.iter()` 而不是 `for i in x`)。
+* 懶惰的評價。例如,如果 `default` 不是文字,請使用 `unwrap_or_else` 而不是 `unwrap_or`。
+
+## 不鼓勵使用代碼
+
+* 大量使用返回類型重載。特別是使用大量非顯而易見的 `.into` 的代碼。這是因為類型推斷結果可能違反直覺。在這種情況下,建議使用 `from` 代替。
+* 大量使用 `Deref`。這有效地提出了與繼承相同的問題。
+
+## 根據上下文做出決策的代碼
+
+* 定義未使用的輔助方法。
+* 大量使用 `unwrap` 和 `clone`。在某些情況下,沒有什么比這樣做更好的了。
\ No newline at end of file
diff --git a/doc/zh_TW/dev_guide/terms.md b/doc/zh_TW/dev_guide/terms.md
new file mode 100644
index 00000000..a023bfb9
--- /dev/null
+++ b/doc/zh_TW/dev_guide/terms.md
@@ -0,0 +1,840 @@
+# 詞匯表
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 象征
+
+### !
+
+添加到標識符末尾的標記以指示它是過程,變量類型或變異運算符。
+
+### [#](../syntax/00_basic.md/# comment)
+
+### $
+
+### %
+
+### &
+
+### ′ (single quote)
+
+### ()
+
+### *
+
+### +
+
+### ,
+
+### −
+
+### ->
+
+### .
+
+### /
+
+### :
+
+### ::
+
+### ;
+
+### <
+
+### <:
+
+### <<
+
+### <=
+
+### =
+
+### ==
+
+### =>
+
+### >
+
+### >>
+
+### >=
+
+### ?
+
+### @
+
+### []
+
+### \
+
+### ^
+
+### ^^
+
+### _
+
+### ``
+
+### {}
+
+### {:}
+
+### {=}
+
+### |
+
+### ||
+
+### ~
+
+## A
+
+### [algebraic type]
+
+### [And]
+
+### [and]
+
+### [assert]
+
+### [attribute]
+
+## B
+
+### [Base]
+
+### [Bool]
+
+## C
+
+### [Class]
+
+## D
+
+### Deprecated
+
+### [distinct]
+
+## E
+
+### [enum type]
+
+### [Eq]
+
+### [Erg]
+
+## F
+
+### [for]
+
+## G
+
+## H
+
+## I
+
+### [if]
+
+### [import]
+
+### [in]
+
+### [Int]
+
+## J
+
+## K
+
+## L
+
+### let-polymorphism -> [rank 1 polymorphism]
+
+### [log]
+
+## M
+
+### [match]
+
+## N
+
+### [Nat]
+
+### Never
+
+### None
+
+### [Not]
+
+### [not]
+
+## O
+
+### [Option]
+
+### [Or]
+
+### [or]
+
+### [Ord]
+
+## P
+
+### panic
+
+### [print!](../syntax/../API/procs.md#print)
+
+### [Python]
+
+## Q
+
+## R
+
+### ref
+
+### ref!
+
+### [Result]
+
+### [rootobj]
+
+## S
+
+### self
+
+### [Self](../syntax/type/special.md)
+
+### [side-effect](../syntax/07_side_effect.md)
+
+### [Str]
+
+## T
+
+### Traits
+
+### [True]
+
+### [Type]
+
+### [type]
+
+## U
+
+## V
+
+## W
+
+### [while!]
+
+## X
+
+## Y
+
+## Z
+
+## A line
+
+### [Assertion]
+
+檢查(通常在運行時)代碼中的條件是否為真。 這是使用 `assert` 函數等來完成的。
+
+```python
+sum = !0
+for! 0..10, i =>
+ sum.add!i
+
+assert sum == 55
+```
+
+### 值對象
+
+在 Erg 中,相當于基礎對象。 它可以在編譯時進行評估,并且具有簡單的比較方法。
+
+### [附件補丁](../syntax/29_decorator.md#attach)
+
+為特征提供標準實現的補丁。
+
+### Ad hoc 多態性 -> [無重載](../syntax/type/overloading.md)
+
+具有所謂重載的多態性。
+
+### 屬性-> [屬性]
+
+`x.y` 標識符中的 `y` 部分。
+
+### Arity
+
+運算符需要多少個操作數。
+
+### [依賴類型](../syntax/type/dependent_type.md)
+
+參數是值的類型(習慣上說,不是類型)。
+
+### 不可變 -> [不可變]
+
+表示目標不會改變。
+其他語言中的變量也是不可變/可變的,但是在 Erg 中所有的變量都是不可變的。
+
+### 參數 -> [參數]
+
+### 實例
+
+由類創建的對象。 類類型的元素。
+
+### [即時封鎖](../syntax/00_basic.md#expression separator)
+
+```python
+x =
+ y = f(a)
+ z = g(b,c)
+ y+z
+```
+
+### 指數
+
+形式為“x[i]”,或其“i”部分。我們稱 `x` 為 Indexable 對象。
+
+### [縮進](../syntax/00_basic.md#indent)
+
+通過向空格移動將文本向右對齊。縮進。
+Ergs 通過縮進表示塊。這稱為越位規則。
+
+### 別名
+
+別名。
+
+### 錯誤
+
+規范中定義的異常情況。
+
+* [錯誤處理]
+
+### [運算符](../syntax/06_operator.md)
+
+將操作應用于其操作數的對象。或表示該對象的符號。
+
+* [運算符綁定強度]
+
+### 覆蓋
+
+在子類中覆蓋超類方法。
+在 Erg 中,您必須在覆蓋時添加 `Override` 裝飾器。
+
+### [不重載](../syntax/type/overloading.md)
+
+### 越位規則-> [縮進](../syntax/00_basic.md#indent)
+
+### [目的]
+
+* 面向對象
+
+### 操作數 -> [操作數](../syntax/06_operator.md)
+
+### 運算符 -> [運算符](../syntax/06_operator.md)
+
+##嘉線
+
+### [種類](../syntax/type/advanced/kind.md)
+
+所謂類型的類型。
+
+### [可見性]
+
+標識符是否可以被外部引用(超出范圍,或在另一個模塊或包中)的屬性。
+
+### [類型]
+
+對術語進行分組的對象。
+
+* [類型規格]
+* [類型擦除](../syntax/type/advanced/erasure.md)
+* [類型推斷]
+* [類型注釋](../syntax/type/conv_type.md)
+* [類型參數]
+* [類型添加](../syntax/type/advanced/erasure.md)
+* [類型變量](../syntax/type/type_variable.md)
+* [類型約束]
+
+### 監視
+
+### 封裝
+
+隱藏實現細節。
+
+### [多變的]
+
+不能是一成不變的。
+
+* [可變對象]
+* [多變的]
+* [變量參考]
+* [變量數組]
+* [可變參數]
+
+### [函數](../syntax/04_function.md)
+
+沒有副作用的子程序。
+
+* [函數式編程](../syntax/23_scope.md#避免可變狀態函數式編程)
+
+### 基本類型
+
+###主格
+
+通過名稱而不是對稱結構來區分。
+
+* [命名類型] -> [類](../syntax/type/04_class.md)
+* [報喜]
+* [名義子類型](../syntax/type/05_nst_vs_sst.md)
+
+### 捕獲-> [關閉]
+
+### [協變]
+
+在 Erg 中,如果 `T <: U` 則 `K(T) <: K(U)` 則稱 `K` 是協變的。
+
+### [關鍵字參數]
+
+`k` 以函數調用 `f(k: v)` 的形式出現。您可以通過形式參數名稱而不是按順序指定實際參數。
+
+### 空集 -> [{}]
+
+### 部分
+
+* [區間類型](../syntax/type/11_interval.md)
+* 區間運算符
+
+### 嵌入式
+
+Erg 標準 API 未在 .er 文件中實現。
+
+### [類](../syntax/type/04_class.md)
+
+具有繼承功能的結構/抽象數據類型。在 Erg 中,它是一種實現命名子類型化和覆蓋的類型。
+在 Erg 中,模塊是模塊對象負責,類型是類型對象,而其他語言可能負責模塊和類型。
+
+### [關閉]
+
+### [全局變量]
+
+### [克隆]
+
+### [繼承](../syntax/type/07_inheritance.md)
+
+定義一個類是另一個類的父類集。
+繼承的類稱為超類,繼承的類稱為子類。
+子類具有其超類的所有功能。
+
+### 高樓層
+
+* [高階種類](../syntax/type/advanced/kind.md)
+* 高階類型
+* 高階函數
+
+### [公共變量]
+
+### [結構子類型]
+
+### ~~后向引用~~ -> [后向引用]
+
+### [復制]
+
+### 評論
+
+### [集合](../syntax/10_array.md)
+
+### 冒號 -> [:]
+
+### [構造函數](../syntax/type/04_class.md)
+
+### 容器
+
+### 編譯器
+
+### [編譯時計算](../syntax/04_function.md#compile-time function)
+
+### 逗號 -> [,]
+
+## sa線
+
+### 遞歸
+
+參考自己。
+
+* 遞歸
+* [遞歸函數](../syntax/04_function.md#遞歸函數)
+
+### 下標 -> [索引]
+
+### [子類型多態性](../syntax/type/overloading.md)
+
+具有子類型的多態性。子類型對應于類型中的集合包含。
+
+### 子程序
+
+模塊化處理的對象。 Erg 中函數、過程和方法的通用術語。
+
+### [參考](../syntax/18_memory_management.md#borrowed)
+
+* 參考對象
+* [引用計數 (RC)](../syntax/18_memory_management.md#memory management)
+* 引用相等 -> [副作用](../syntax/07_side_effect.md)
+
+### [標識符](../syntax/02_variable.md/# 賦值)
+
+### 簽名
+
+* 類型簽名
+
+### [dict](../syntax/11_dict.md)
+
+### 自然數 -> Nat
+
+### 泛型 -> 泛型
+
+### 發電機
+
+### 投影類型
+
+### 借用-> [參考](../syntax/18_memory_management.md#borrowed)
+
+### [陰影](../syntax/02_name.md# variables)
+
+通過在內部范圍內定義具有相同名稱的變量來覆蓋對變量的引用。
+
+### kind -> [kind](../syntax/type/advanced/kind.md)
+
+大致類型的類型。
+
+### set -> set
+
+在 Erg 中,它表示一個 Set 對象。
+
+### 謂詞
+
+* 謂詞函數
+
+返回布爾類型的函數。
+
+### 條件分支
+
+### 所有權
+
+對象唯一性的概念。
+如果您擁有對象的所有權,則可以使用 mutable 參考它。
+
+### Boolean -> Bool
+
+### 單例
+
+從只能創建一個實例的類創建的實例。一種設計模式,可確保只創建一個類的一個實例。
+
+### [Symbol] -> [Identifier](../syntax/02_name.md)
+
+* 符號化
+
+### [腳本](../syntax/00_basic.md# 腳本)
+
+包含 Erg 程序的文件。
+
+### 范圍
+
+變量管理單元。外部作用域不能引用內部作用域中存在的變量。
+當范圍退出時,引用計數為 0 的對象將被釋放。
+
+### 擴展運算符 -> expansion assignment
+
+### [切片](../syntax/10_array.md#slice)
+
+表示數組子序列的對象,以 `x[a..b]` 的形式生成。
+
+### 控制字符
+
+### 整數 -> Int
+
+一組自然數加上負數。
+
+### [設置](../syntax/12_set.md)
+
+### 分號 -> ;
+
+### [聲明](../syntax/03_declaration.md)
+
+顯式類型變量。
+
+### 全名
+
+* 通用類型 -> [多態類型](../syntax/type/quantified.md)
+ * 封閉式通用
+ * 打開通用
+* 通用函數 -> 多相關函數
+* 通用量化
+
+### 前綴運算符
+
+運算符 `°` 以 `°x` 的形式應用。
+
+### 相互遞歸
+
+### 下標 -> index
+
+### 屬性
+
+* 屬性子類型
+
+## 塔線
+
+### [代數](../syntax/02_name.md)
+
+* [代數類型](../syntax/type/13_algebraic.md)
+* 代數數據類型
+
+### [賦值](../syntax/02_variable.md/#assignment)
+
+### 多
+
+* [多重繼承](../syntax/type/07_inheritance.md/#禁止多重繼承)
+* 多重賦值
+* 重載 -> [不重載]
+
+### 多態性
+
+* [多態類型](../syntax/type/quantified.md)
+* 多相關系數
+
+### 多態性 -> [多態性]
+
+### 鴨子類型
+
+### [元組](../syntax/11_tuple.md)
+
+### 單相
+
+* 單相
+* 單相型
+* 單相關系數
+
+### [延遲初始化]
+
+### 提取分配
+
+### 抽象語法樹 -> [AST]
+
+### 中綴運算符
+
+運算符 `°` 以 `x°y` 的形式應用。
+
+### [常數](../syntax/02_name.md/#constant)
+
+不可變的,編譯時可評估的代數。
+
+* [常量類型](../syntax/type/advanced/const.md)
+* [常量表達式](../syntax/type/advanced/const.md)
+
+### 定義
+
+分配與變量對應的對象。
+
+### 提供的屬性
+
+可作為 API 使用的屬性。特別是由特征自動實現的屬性。
+
+### 申請
+
+將參數傳遞給函數對象并獲取評估結果。
+
+### [裝飾器](../syntax/29_decorator.md)
+
+``` python
+@deco
+f x = ...
+```
+
+語法糖,或“裝飾”。大致等于`_f x = ...; f = 裝飾 _f`。 `deco` 本身只是一個高階子程序。
+
+### 析構函數
+
+對象被銷毀時調用的方法。
+
+### 程序 -> [procedure](../syntax/08_procedure.md)
+
+讀取和寫入可變狀態的子程序。
+有時會說程序的執行結果可以根據調用過程的順序而改變,但如果我們談論交換性,這是不正確的。
+例如,作為函數子類型的運算符通常不可交換。
+
+### [默認參數](../syntax/04_function.md/#default arguments default-parameters)
+
+通過指定形式參數的默認值,可以在調用時省略實際參數的指定的函數。
+
+### 擴張
+
+* 擴展運算符
+* 擴展分配
+
+### [特殊格式](../syntax/../API/special.md)
+
+不能作為實際參數傳遞的對象。
+
+### 匿名函數 -> [anonymous function](../syntax/20_lambda.md)
+
+由匿名函數運算符`->`創建的函數對象。可以在不定義名稱的情況下使用。
+
+### 點運算符 (`.`) -> attribute reference
+
+### 頂部
+
+* 頂部類型 -> [結構對象]
+* 頂級 -> [對象]
+
+### [特征](../syntax/type/03_trait.md)
+
+## na line
+
+### [理解](../syntax/27_comprehension.md)
+
+### ~~中綴運算符~~ -> 中綴運算符
+
+### 命名空間
+
+## 是一行
+
+### [數組](../syntax/10_array.md)
+
+### [派生類型](../syntax/type/variances.md/# 用戶定義的類型變體)
+
+### [模式(匹配)](../syntax/26_pattern_matching.md)
+
+### [包](../syntax/33_package_system.md)
+
+### hashmap -> [dict](../syntax/11_dict.md)
+
+### [補丁](../syntax/type/07_patch.md)
+
+### 公共變量-> [public variables](../syntax/19_visibility.md)
+
+### 參數 -> [argument](../syntax/04_function.md)
+
+### [參數多態](../syntax/type/overloading.md)
+
+### [逆變](../syntax/type/advanced/variance.md)
+
+### 相比
+
+* 比較運算符
+* 可比類型
+
+### [私有變量](../syntax/19_visibility.md)
+
+### 標準
+
+* 標準輸出
+* 標準輸入
+* 標準庫
+
+### [副作用](../syntax/07_side_effect.md)
+
+代碼應該/不應該讀/寫外部可變狀態。
+
+### 復數 -> 復數
+
+### 浮動 -> 浮動
+
+### 私有變量 -> 私有變量
+
+### 布爾代數-> Bool
+
+### [程序](../syntax/08_procedure.md)
+
+### [參數](../syntax/04_function.md)
+
+### 部分類型 -> Subtyping
+
+### [不可變]
+
+在 Erg 中,一個對象永遠不應該改變它的內容。
+
+* [不可變對象]
+* [不可變類型]
+* [不可變引用]
+
+### [篩子類型](../syntax/type/12_refinement.md)
+
+### [堵塞]
+
+### 解構賦值
+
+### [變量](../syntax/02_variable.md)
+
+### 底部
+
+* 底部類型 -> [{}]
+* 底層 -> [從不]
+
+### [多態性]
+
+## ma line
+
+### ~~ 前綴運算符 ~~ -> 前綴運算符
+
+### [標記類型](../syntax/type/advanced/marker_trait.md)
+
+### [匿名函數](../syntax/21_lambda.md)
+
+### 可變 -> [可變]
+
+### [移動]
+
+### 方法
+
+### 元字符
+
+### [模塊](../syntax/24_module.md)
+
+### [字符串] -> [字符串]
+
+* [字符串插值](../syntax/01_literal.md/#Str 字面量)
+
+### 返回值
+
+## 或行
+
+### [幻像類型](../syntax/type/advanced/phantom.md)
+
+### 請求屬性
+
+### [元素]
+
+### [稱呼]
+
+## 拉線
+
+### [圖書館]
+
+### lambda 表達式 -> [匿名函數](../syntax/20_lambda.md)
+
+### 排名
+
+* [rank2 多態性](../syntax/type/advanced/rank2type.md)
+
+### [文字](../syntax/01_literal.md)
+
+* [文字標識符](../syntax/18_naming_rule.md/#literal identifier)
+
+### [量化](../syntax/type/quantified.md)
+
+### [布局](../syntax/type/mut.md)
+
+### [枚舉](../syntax/type/10_enum.md)
+
+### [記錄](../syntax/12_record.md)
+
+* [記錄類型]
+* 記錄多態 -> Column Polymorphism
+
+### 列多態
+
+### [局部變量](../syntax/19_visibility.md)
+
+## 線
+
+### 通配符
\ No newline at end of file
diff --git a/doc/zh_TW/dev_guide/unify_terms.md b/doc/zh_TW/dev_guide/unify_terms.md
new file mode 100644
index 00000000..d1d804dc
--- /dev/null
+++ b/doc/zh_TW/dev_guide/unify_terms.md
@@ -0,0 +1,58 @@
+# 術語統一
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/unify_terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 可訪問性,可見性
+
+使用可見性。
+
+## 類型綁定,類型約束
+
+給定量化和細化類型的謂詞表達式列表。使用類型邊界。
+
+## 子程序、例程、子程序
+
+使用子程序。
+
+## 引用透明/不透明,有/沒有副作用
+
+使用有/無副作用。
+
+## 標識符、代數、變量、名稱、符號
+
+就其本義而言,
+
+* 符號:在源代碼中實心編寫的字符(符號、控制字符等除外),不是字符串對象(未包含在“”中)。符號在 Ruby、Lisp 等中作為原始類型存在,但在 Erg 中它們不被視為對象。
+* 標識符:(并且可以)引用某個對象的符號,而不是保留字。例如,在 Python 中 class 和 def 不能用作標識符。由于 Erg 沒有保留字,所以除了某些符號外,所有符號都可以用作標識符。
+* 名稱:與標識符的含義幾乎相同。它有時與 Erg 中的代數同義使用。
+* 代數名稱:相當于Erg中的標識符。在 C 中,函數名稱是標識符,而不是代數名稱。 “代數”指的是語言特性本身,它允許您使用 `=`(變量賦值運算符)或 `=`(常量賦值運算符)來分配對象。
+
+```python
+代數名稱<:(名稱==標識符)??<:符號
+變量 + 常數 == 代數
+```
+
+然而,應該稱為“代數”的東西,往往被稱為“變量”。這就是數學術語的效果。
+值內容可以改變的變量是可變變量,值內容不改變的變量是不可變變量。
+請注意,常量始終是不可變的。
+
+Erg 中不使用代數名稱和名稱,使用統一標識符。
+但是,一般來說,具有 `v = 1` 的 `v` 稱為“變量 v”,而具有 `C = 1` 的 `C` 稱為“常量 C”。 .
+
+## 屬性、字段、屬性
+
+使用屬性。順便說一句,記錄是一個函數,它可以定義一個沒有類的具有元素屬性的對象。
+
+## 應用程序,調用
+
+為子例程對象提供參數并獲得結果。
+使用呼叫。這是因為Application有“應用軟件”的用法。
+
+## 數組列表
+
+使用數組。 Erg 數組(通常)在內存中是連續的。
+List 是指所謂的鏈表,或者說列表作為 Python 數據類型。
+
+## lambda 函數、lambda 表達式、匿名函數
+
+與匿名函數統一。在英文中,可以使用 Lambda 來縮短字符數,但正式名稱是 Anonymous function。
\ No newline at end of file
diff --git a/doc/zh_TW/faq_general.md b/doc/zh_TW/faq_general.md
new file mode 100644
index 00000000..b687922b
--- /dev/null
+++ b/doc/zh_TW/faq_general.md
@@ -0,0 +1,39 @@
+# Erg常見問題
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_general.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
+This FAQ is intended for the general Erg beginner.
+For individual (common) technical issues, please refer to [here](./faq_technical.md) for individual (common) technical issues, and
+[Here](./dev_guide/faq_syntax.md) for more information.
+
+## Erg 是 Python 兼容語言是什么意思?
+
+~~A:Erg的可執行系統EVM(Erg VirtualMachine)執行Erg字節碼,是Python字節碼的擴展。它在 Python 字節碼中引入了靜態類型系統和其他特性(例如向不帶參數的指令引入參數,以及在自由編號中實現唯一指令)。這讓 Erg 可以無縫調用 Python 代碼并快速執行。~~
+
+A: Erg 代碼被轉譯成 Python 字節碼。也就是說,它運行在與 Python 相同的解釋器上。最初,我們計劃開發一個兼容 Cpython 的解釋器,并將其與編譯器結合起來形成“Erg”。但是,由于處理系統的發展遠遠落后于編譯器,我們決定提前只發布編譯器(但解釋器仍在開發中)。
+
+## 哪些語言影響了Erg?
+
+我們受到的語言多于我們雙手所能指望的數量,但 Python、Rust、Nim 和 Haskell 的影響最大。
+我們從 Python 繼承了許多語義,從 Rust 繼承了面向表達式和 trait,從 Nim 繼承了過程,從 Haskell 繼承了函數式編程相關的特性。
+
+## 可以調用 Python 的語言包括 Julia。你為什么創建 Erg?
+
+答:Erg 設計的動機之一是擁有一種易于使用且具有強大類型系統的語言。即具有類型推斷、種類、依賴類型等的語言。
+Julia 是可以有類型的,但它確實是一種動態類型語言,不具備靜態類型語言的編譯時錯誤檢測優勢。
+
+## Erg 支持多種編程風格,包括函數式和面向對象的編程。這不是與 Python 的“應該有一種——最好只有一種——明顯的方法”相反嗎?
+
+答:在 Erg 中,該術語是在更狹窄的上下文中使用的。例如,Erg API 中一般沒有別名;在這種情況下,Erg是“唯一一種方式”。
+在更大的上下文中,例如 FP 或 OOP,只有一種做事方式并不一定很方便。
+例如,JavaScript 有幾個庫可以幫助創建不可變的程序,而 C 有幾個用于垃圾收集的庫。
+然而,即使是這樣的基本功能也有多個庫不僅需要時間來選擇,而且在集成使用不同庫的代碼時也會產生很大的困難。
+即使在純函數式語言 Haskell 中,也有支持 OOP 的庫。
+如果程序員沒有一些東西,他們會自己創造它們。因此,我們認為將它們作為標準提供會更好。
+這也符合 Python 的“含電池”概念。
+
+## Erg 這個名字的由來是什么?
+
+它以cgs單位系統中的能量單位erg命名。它具有雙重含義:一種為程序員提供能量的符合人體工程學的語言。
+
+還有其他幾個候選者,但之所以選擇它是因為它最短(根據 Ruby 的開發者 Matz 的說法,語言名稱越短越好)并且具有相當高的可搜索性。
\ No newline at end of file
diff --git a/doc/zh_TW/faq_technical.md b/doc/zh_TW/faq_technical.md
new file mode 100644
index 00000000..61fcc532
--- /dev/null
+++ b/doc/zh_TW/faq_technical.md
@@ -0,0 +1,35 @@
+# 技術常見問題
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_technical.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e)
+
+本節回答有關使用 Erg 語言的技術問題。換句話說,它包含以 What 或 Which 開頭的問題,以及可以用 Yes/No 回答的問題。
+
+有關如何確定語法的更多信息,請參閱 [此處](./dev_guide/faq_syntax.md) 了解基礎語法決策,以及 [此處](./dev_guide/../faq_general.md)。
+
+## Erg 中有異常機制嗎?
+
+答:不會。Erg 使用 `Result` 類型代替。請參閱 [此處](./dev_guide/faq_syntax.md) 了解 Erg 沒有異常機制的原因。
+
+## Erg 是否有與 TypeScript 的 `Any` 等價的類型?
+
+答:不,沒有。所有對象都至少屬于 `Object` 類,但是這種類型只提供了一組最小的屬性,所以你不能像使用 Any 那樣對它做任何你想做的事情。
+`Object` 類通過`match` 等動態檢查轉換為所需的類型。它與Java 和其他語言中的`Object` 是同一種。
+在 Erg 世界中,沒有像 TypeScript 那樣的混亂和絕望,其中 API 定義是“Any”。
+
+## Never、{}、None、()、NotImplemented 和 Ellipsis 有什么區別?
+
+A:`Never` 是一種“不可能”的類型。產生運行時錯誤的子例程將“Never”(或“Never”的合并類型)作為其返回類型。該程序將在檢測到這一點后立即停止。盡管 `Never` 類型在定義上也是所有類型的子類,但 `Never` 類型的對象永遠不會出現在 Erg 代碼中,也永遠不會被創建。 `{}` 等價于 `Never`。
+`Ellipsis` 是一個表示省略號的對象,來自 Python。
+`NotImplemented` 也來自 Python。它被用作未實現的標記,但 Erg 更喜歡產生錯誤的 `todo` 函數。
+`None` 是 `NoneType` 的一個實例。它通常與 `Option` 類型一起使用。
+`()` 是一個單元類型和它自己的一個實例。當您想要返回“無意義的值”(例如過程的返回值)時使用它。
+
+## 為什么 `x = p!()` 有效但 `f() = p!()` 會導致 EffectError?
+
+`!` 不是副作用產品的標記,而是可能導致副作用的對象。
+過程 `p!` 和可變類型 `T!` 會引起副作用,但如果 `p!()` 的返回值是 `Int` 類型,它本身就不再引起副作用。
+
+## 當我嘗試使用 Python API 時,對于在 Python 中有效的代碼,我在 Erg 中收到類型錯誤。這是什么意思?
+
+A:Erg API 的類型盡可能接近 Python API 規范,但有些情況無法完全表達。
+此外,根據規范有效但被認為不合需要的輸入(例如,在應該輸入 int 時輸入浮點數)可能會被 Erg 開發團隊酌情視為類型錯誤。
\ No newline at end of file
diff --git a/doc/zh_TW/improved_points.md b/doc/zh_TW/improved_points.md
new file mode 100644
index 00000000..3c8383d5
--- /dev/null
+++ b/doc/zh_TW/improved_points.md
@@ -0,0 +1,50 @@
+# Python 的改進
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/improved_points.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
+## 執行靜態分析(靜態類型檢查、變量和屬性檢查)
+
+靜態類型檢查的好處現在怎么強調都不為過,但是檢查變量和屬性的存在也是相當重要的一部分。
+
+## 嚴格范圍處理
+
+在 Python 中,語句沒有范圍。
+因此,在 `for` 或 `if` 中定義的變量具有外部影響。 不能隨便命名變量。
+
+```python
+for i in range(10):
+ x = 1
+ print(i + x)
+print(x) # 1
+```
+
+在 Erg 中,所有塊都有范圍并且是完全隔離的。
+
+## 明確區分可變對象和不可變對象
+
+Python并不清楚可變和不可變/堆和值對象之間的區別,因此您必須記住元組是不可變的但列表是可變的......您需要記住元組是不可變的,但列表是可變的 ... 等等。
+另外,如果你想讓你自己的類不可變,你必須經歷一個乏味的過程。
+
+```python
+# 你能相信這段代碼對過去的 Python 版本有效嗎?
+i = 256
+assert i is 256
+i = 257
+assert i is not 257
+```
+
+## Traits
+
+就像 Java 的接口一樣,你可以進行基于契約的編程。
+
+Python 也有 ABC(抽象基類),但這種結構最適合靜態類型。
+
+## 靜態解決依賴關系
+
+這可以防止長時間運行程序然后由于缺少模塊而出現錯誤的煩人體驗。
+
+## 內置包管理器
+
+具有標準化目錄結構和構建文件的可重現構建。
+當然提供了鎖定文件生成和版本控制。
+無需為每個項目選擇或混合anaconda、pyenv、詩歌等。
diff --git a/doc/zh_TW/index.md b/doc/zh_TW/index.md
new file mode 100644
index 00000000..f97500ce
--- /dev/null
+++ b/doc/zh_TW/index.md
@@ -0,0 +1,27 @@
+# 索引
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/index.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
+## [API/](./API/index.md)
+
+ 本節介紹 Erg 的內置或標準庫提供的子程序、類型、常量等的規范。
+
+## [compiler/](./compiler/index.md)
+
+ 描述 Erg 編譯器的設計(厘米)
+
+## [dev_guide/](./dev_guide/index.md)
+
+ 它解釋了項目的發展政策,如何做出貢獻等。
+
+## [python/](./python/index.md)
+
+ 解釋了開發 Erg 所需的 Python 知識。
+
+## [syntax/](./syntax/00_basic.md)
+
+ Erg 的語法進行了解釋。
+
+## [tools/](./tools/index.md)
+
+ 解釋如何使用 Erg 的外圍工具和命令選項。
\ No newline at end of file
diff --git a/doc/zh_TW/migration_from_py.md b/doc/zh_TW/migration_from_py.md
new file mode 100644
index 00000000..74abaa03
--- /dev/null
+++ b/doc/zh_TW/migration_from_py.md
@@ -0,0 +1,27 @@
+# 從 Python 遷移到 Erg 的提示
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/migration_from_py.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## 我想將字符串轉換為 int 等。
+
+使用 `Str` 類的 `parse` 方法。 它返回一個 `Result` 類型。
+
+```python
+s: str
+i: int = int(s)
+```
+
+```python
+s: Str
+res: Result(Int, IntParseError) = s. parse Int
+i: Int = res.unwrap()
+f: Result(Float, FloatParseError) = s. parse Float
+```
+
+您還可以使用 `try_from` 方法。
+
+```python
+s: Str
+i: Int = Int.try_from(s).unwrap()
+f: Float = Float.try_from(s).unwrap()
+```
\ No newline at end of file
diff --git a/doc/zh_TW/python/bytecode_instructions.md b/doc/zh_TW/python/bytecode_instructions.md
new file mode 100644
index 00000000..35715f37
--- /dev/null
+++ b/doc/zh_TW/python/bytecode_instructions.md
@@ -0,0 +1,118 @@
+# Python 字節碼指令
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_instructions.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+Python 字節碼變量操作命令通過 名稱索引(名稱索引)訪問。 這是為了在 Python 中實現動態變量訪問(可以使用 eval 等作為字符串訪問)。
+一條指令為 2 個字節,指令和參數以 little endian 形式存儲。
+不帶參數的指令也使用 2 個字節(參數部分為 0)。
+
+## STORE_NAME(名稱索引)
+
+```python
+globals[namei] = stack.pop()
+```
+
+## LOAD_NAME(名稱索引)
+
+```python
+stack.push(globals[namei])
+```
+
+Only called at top level.
+
+## LOAD_GLOBAL(名稱索引)
+
+```python
+stack.push(globals[namei])
+```
+
+用于加載內部作用域頂層的STORE_NAME,但頂層的`名稱索引`不一定與某個作用域的代碼對象中的名稱索引相同(名稱相同,名稱索引不一定)
+
+## LOAD_CONST(名稱索引)
+
+```python
+stack.push(consts[namei])
+```
+
+在常量表中加載常量。
+目前(Python 3.9),在 CPython 中,每個 lambda 函數都是 MAKE_FUNCTION,名稱為“\”
+
+```console
+>>> dis.dis("[1,2,3].map(lambda x: x+1)")
+1 0 LOAD_CONST 0 (1)
+ 2 LOAD_CONST 1 (2)
+ 4 LOAD_CONST 2 (3)
+ 6 BUILD_LIST 3
+ 8 LOAD_ATTR 0 (map)
+ 10 LOAD_CONST 3 ( at 0x7f272897fc90, file "", line 1>)
+ 12 LOAD_CONST 4 ('')
+ 14 MAKE_FUNCTION 0
+ 16 CALL_FUNCTION 1
+ 18 RETURN_VALUE
+```
+
+## STORE_FAST(名稱索引)
+
+fastlocals[namei] = stack.pop()
+可能對應于頂層的 STORE_NAME
+假定未引用(或單個)變量由此存儲
+全局空間有自己的指令是為了優化嗎?
+
+## LOAD_FAST(名稱索引)
+
+```python
+stack.push(fastlocals[namei])
+```
+fastlocals 是變量名嗎?
+
+## LOAD_CLOSURE(名稱索引)
+
+```python
+cell = freevars[namei]
+stack. push(cell)
+```
+
+然后調用 BUILD_TUPLE
+它只在閉包內被調用,并且 cellvars 應該在閉包內存儲引用。
+與 LOAD_DEREF 不同,每個單元格(填充有引用的容器)都被推入堆棧
+
+## STORE_DEREF(名稱索引)
+
+```python
+cell = freevars[namei]
+cell.set(stack.pop())
+```
+
+在內部范圍內沒有引用的變量是 STORE_FAST,但引用的變量是 STORE_DEREF
+在 Python 中,引用計數在該指令內遞增和遞減
+
+## LOAD_DEREF(名稱索引)
+
+```python
+cell = freevars[namei]
+stack.push(cell.get())
+```
+
+## 名稱列表
+
+### 變量名
+
+fast_locals 對應的函數內部變量名稱列表
+即使名稱中有同名的變量,它們也基本不一樣(新創建的和外部變量不能從那個范圍訪問)
+即沒有在范圍內定義的外部引用的變量進入 varnames
+
+### 名字
+
+與全局兼容
+范圍內使用的外部常量(僅引用)的名稱列表(在頂層,即使是普通變量也包含在名稱中)
+即在范圍之外定義的常量進入名稱
+
+## 自由變量
+
+與免費變量兼容
+閉包捕獲的變量。它在同一個函數實例中靜態地運行。
+
+## 單元格變量
+
+對應于 cellvars
+在函數內捕獲到內部閉包函數的變量。 由于制作了副本,因此原始變量保持原樣。
\ No newline at end of file
diff --git a/doc/zh_TW/python/bytecode_specification.md b/doc/zh_TW/python/bytecode_specification.md
new file mode 100644
index 00000000..8606d9c6
--- /dev/null
+++ b/doc/zh_TW/python/bytecode_specification.md
@@ -0,0 +1,145 @@
+# Python bytecode specification
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_specification.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)
+
+## Format
+
+* 0~3 byte(u32): magic number (see common/bytecode.rs for details)
+* 4~7 byte(u32): 0 padding
+* 8~12 byte(u32): timestamp
+* 13~ byte(PyCodeObject): code object
+
+## PyCodeObject
+
+* 0 byte(u8): '0xe3' (prefix, this means code's 'c')
+* 01~04 byte(u32): number of args (co_argcount)
+* 05~08 byte(u32): number of position-only args (co_posonlyargcount)
+* 09~12 byte(u32): number of keyword-only args (co_kwonlyargcount)
+* 13~16 byte(u32): number of locals (co_nlocals)
+* 17~20 byte(u32): stack size (co_stacksize)
+* 21~24 byte(u32): flags (co_flags) ()
+* ? byte: bytecode instructions, ends with '0x53', '0x0' (83, 0): RETURN_VALUE (co_code)
+* ? byte(PyTuple): constants used in the code (co_consts)
+* ? byte(PyTuple): names used in the code (co_names)
+* ? byte(PyTuple): variable names defined in the code, include params (PyTuple) (co_varnames)
+* ? byte(PyTuple): variables captured from the outer scope (co_freevars)
+* ? byte(PyTuple): variables used in the inner closure (co_cellvars)
+* ? byte(PyUnicode or PyShortAscii): file name, where it was loaded from (co_filename)
+* ? byte(PyUnicode or PyShortAscii): the name of code itself, default is \ (co_name)
+* ?~?+3 byte(u32): number of first line (co_firstlineno)
+* ? byte(bytes): line table, represented by PyStringObject? (co_lnotab)
+
+## PyTupleObject
+
+* 0 byte: 0x29 (means ')')
+* 01~04 byte(u32): number of tuple items
+* ? byte(PyObject): items
+
+## PyStringObject
+
+* If I use a character other than ascii, does it become PyUnicode?
+* "あ", "??", and "α" are PyUnicode (no longer used?)
+
+* 0 byte: 0x73 (means 's')
+* 1~4 byte: length of string
+* 5~ byte: payload
+
+## PyUnicodeObject
+
+* 0 byte: 0x75 (means 'u')
+* 1~4 byte: length of string
+* 5~ byte: payload
+
+## PyShortAsciiObject
+
+* This is called short, but even if there are more than 100 characters, this will still short
+* or rather, there is no ascii that is not short (is short a data type?)
+
+* 0 byte: 0xFA (means 'z')
+* 1~4 byte: length of string
+* 5~ byte: payload
+
+## PyInternedObject
+
+* interned objects are registered in a dedicated map and can be compared with is
+* String, for example, can be compared in constant time regardless of its length
+
+* 0 byte: 0x74 (means 't')
+
+## PyShortAsciiInternedObject
+
+* 0 byte: 0xDA (means 'Z')
+* 1~4 byte: length of string
+* 5~ byte: payload
+
+# Python 字節碼規范
+
+## 格式
+
+* 0~3 byte(u32):幻數(詳見common/bytecode.rs)
+* 4~7 byte(u32): 0 padding
+* 8~12 byte(u32): 時間戳
+* 13~ byte(PyCodeObject): 代碼對象
+
+## PyCode 對象
+
+* 0 byte(u8): '0xe3' (前綴,這意味著代碼的'c')
+* 01~04 byte(u32): args個數(co_argcount)
+* 05~08 byte(u32): position-only args 的數量 (co_posonlyargcount)
+* 09~12 byte(u32):僅關鍵字參數的數量(co_kwonlyargcount)
+* 13~16 byte(u32): 本地數 (co_nlocals)
+* 17~20 byte(u32): 棧大小(co_stacksize)
+* 21~24 byte(u32):標志(co_flags)()
+* ? byte:字節碼指令,以'0x53'、'0x0'結尾(83, 0):RETURN_VALUE(co_code)
+* ? byte(PyTuple):代碼中使用的常量(co_consts)
+* ? byte(PyTuple):代碼中使用的名稱(co_names)
+* ? byte(PyTuple):代碼中定義的變量名,包括params (PyTuple) (co_varnames)
+* ? byte(PyTuple):從外部范圍捕獲的變量(co_freevars)
+* ? byte(PyTuple):內部閉包中使用的變量(co_cellvars)
+* ? byte(PyUnicode 或 PyShortAscii):文件名,它是從哪里加載的(co_filename)
+* ? byte(PyUnicode or PyShortAscii): 代碼本身的名字,默認是\ (co_name)
+* ?~?+3 byte(u32): 第一行數 (co_firstlineno)
+* ? byte(bytes):行表,用 PyStringObject? (co_lnotab)
+
+## PyTupleObject
+
+* 0 byte: 0x29 (意思是:')')
+* 01~04 byte(u32): 元組項數
+* ? byte(PyObject):項目
+
+## PyString 對象
+
+* 如果我使用 ascii 以外的字符,它會變成 PyUnicode 嗎?
+* “あ”、“??”和“α”是 PyUnicode(不再使用?)
+
+* 0 byte:0x73(表示's')
+* 1~4 byte:字符串長度
+* 5~ byte:有效載荷
+
+## PyUnicode 對象
+
+* 0 byte:0x75(表示“u”)
+* 1~4 byte:字符串長度
+* 5~ byte:有效載荷
+
+## PyShortAsciiObject
+
+* 這叫短,但是即使超過100個字符,仍然會保持在短的狀態
+* 或者更確切地說,沒有不短的 ascii(短數據類型嗎?)
+
+* 0 byte:0xFA(表示“z”)
+* 1~4 byte:字符串長度
+* 5~ byte:有效載荷
+
+## PyInternedObject
+
+* 實習對象注冊在專用地圖中,可以與is進行比較
+* 例如字符串,無論其長度如何,都可以在恒定時間內進行比較
+
+* 0 byte:0x74(表示't')
+
+## PyShortAsciiInternedObject
+
+* 0 byte:0xDA(表示“Z”)
+* 1~4 byte:字符串長度
+* 5~ byte:有效載荷
\ No newline at end of file
diff --git a/doc/zh_TW/python/class_system.md b/doc/zh_TW/python/class_system.md
new file mode 100644
index 00000000..63606bbd
--- /dev/null
+++ b/doc/zh_TW/python/class_system.md
@@ -0,0 +1,96 @@
+# Python 類系統(與 Erg 比較)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/class_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 方法
+
+方法可以被前向引用,但這不是一種特殊的技術。
+這是因為動態檢查方法的存在。
+(在 Erg 中,方法存在是靜態檢查的。對于前向引用,函數必須是常量。)
+
+```python
+>>> class C:
+... def f(self, x):
+... if x == 0: return 0
+... else: return self.g(x)
+... def g(self, x): return self.f(x - 1)
+```
+
+## 繼承,覆蓋
+
+一些被覆蓋的方法 m 被簡單地覆蓋,就像變量重新分配一樣。
+在父類中引用 m 的方法將在子類中引用被覆蓋的 m。
+
+```python
+>>> class C:
+... def f(self): return 1
+... def g(self): return self.f()
+...
+>>> class D(C):
+... def f(self): return 2
+...
+>>>> D().g()
+2
+```
+
+因此,即使它顯然被錯誤地覆蓋,直到運行時才會出錯。
+
+```python
+>>>> class C:
+... def f(self): return 1
+... def g(self): return self.f() + 1
+...
+>>> class D(C):
+... def f(self): return "a"
+...
+>>> D().g()
+Traceback (most recent call last):
+ File "", line 1, in ", line 3, in g
+類型錯誤:只能將str(不是“int”)連接到str
+```
+
+Erg 靜態檢查與父類的一致性。
+重寫時必須給出“Override”裝飾器,并且重寫函數的類型必須是被重寫函數類型的子類型。
+
+```python
+>>> C = Class()
+... .f self = 1
+... .g self = self.f() + 1
+...
+>>> D = Inherit C
+... .f self = "a"
+...
+錯誤[#XX]:文件“”,第 5 行,在 D 中
+要覆蓋 f,必須添加 `Override` 裝飾器,其類型必須是 `Self.() -> Nat` 或其子類型
+f(self) 已在 C 中定義。要覆蓋 f,必須添加 `Override` 裝飾器,其類型必須為 `Self. 要覆蓋,必須給它一個 `Override` 裝飾器,并且它的類型必須是 `Self.() -> Nat` 或 that.f(self) 的子類型。
+```
+
+## 類型檢查
+
+類型檢查通常都是關于檢查函數參數的類型。
+在 Python 中,大多數操作都是方法調用。 如果對象所屬的類在調用時沒有附加方法,就是這樣。
+
+```python
+def f(x):
+ return x.m()
+
+class C:
+ def m(self): return None
+
+c = C()
+f(c)
+f(1) # 類型錯誤
+```
+
+```python
+# f: |T, X <: {.m = Self.() -> T}| X -> T
+f(x) = x.m()
+
+C = Class()
+C.m(self) = None
+
+c = C.new()
+f(c)
+f(1) # 類型錯誤:f 將具有方法 `.m` 的類型作為參數,但傳遞了 Nat
+```
diff --git a/doc/zh_TW/python/index.md b/doc/zh_TW/python/index.md
new file mode 100644
index 00000000..2168ad9d
--- /dev/null
+++ b/doc/zh_TW/python/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/index.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)
+
diff --git a/doc/zh_TW/syntax/00_basic.md b/doc/zh_TW/syntax/00_basic.md
new file mode 100644
index 00000000..03aa32e7
--- /dev/null
+++ b/doc/zh_TW/syntax/00_basic.md
@@ -0,0 +1,148 @@
+# 基本
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+> __Warning__:本文檔不完整。 它未經校對(樣式、正確鏈接、誤譯等)。 此外,Erg 的語法可能在版本 0.* 期間發生破壞性更改,并且文檔可能沒有相應更新。 請事先了解這一點。
+> 如果您在本文檔中發現任何錯誤,請報告至 [此處的表單](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我們將不勝感激您的建議。
+
+本文檔描述 Erg 的基本語法。 [標準 API](./API/index.md) 和 [Erg 貢獻者的內部文檔](./dev_guide/index.md) 位于另一個目錄中。
+
+## 你好,世界!
+
+首先,讓我們做“Hello World”。
+
+```python
+print!("Hello, World!")
+```
+
+這與 Python 和同一家族中的其他語言幾乎相同。 最顯著的特征是`!`,后面會解釋它的含義。
+在 Erg 中,括號 `()` 可以省略,除非在解釋上有一些混淆。
+括號的省略與 Ruby 類似,但不能省略可以以多種方式解釋的括號。
+
+```python
+print! "Hello, World!" # OK
+print! "Hello,", "World!" # OK
+print!() # OK
+print! # OK, 但這并不意味著調用,只是將 `print!` 作為可調用對象
+
+print! f x # OK, 解釋為 `print!(f(x))`
+print!(f(x, y)) # OK
+print! f(x, y) # OK
+print! f(x, g y) # OK
+print! f x, y # NG, 可以理解為 `print!(f(x), y)` 或 `print!(f(x, y))` print!
+print!(f x, y) # NG, 可以表示“print!(f(x),y)”或“print!(f(x,y))”
+print! f(x, g y, z) # NG, 可以表示“print!(x,g(y),z)”或“print!(x,g(y,z))”
+```
+
+## 腳本
+
+Erg 代碼稱為腳本。 腳本可以以文件格式 (.er) 保存和執行。
+
+## REPL/文件執行
+
+要啟動 REPL,只需鍵入:
+
+```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!
+```
+
+## 注釋
+
+`#` 之后的代碼作為注釋被忽略。 使用它來解釋代碼的意圖或暫時禁用代碼。
+
+```python
+# 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 `]#`
+]#
+```
+
+## 表達式,分隔符
+
+腳本是一系列表達式。 表達式是可以計算或評估的東西,在 Erg 中幾乎所有東西都是表達式。
+每個表達式由分隔符分隔 - 新行或分號 `;`-。
+Erg 腳本基本上是從左到右、從上到下進行評估的。
+
+```python
+n = 1 # 賦值表達式
+f(1, 2) # 函數調用表達式
+1 + 1 # 運算符調用表達式
+f(1, 2); 1 + 1
+```
+
+如下所示,有一種稱為 Instant block 的語法,它將塊中評估的最后一個表達式作為變量的值。
+這與沒有參數的函數不同,它不添加 `()`。 請注意,即時塊僅在運行中評估一次
+
+```python
+i =
+ x = 1
+ x + 1
+assert i == 2
+```
+
+這不能用分號 (`;`) 完成。
+
+```python
+i = (x = 1; x + 1) # 語法錯誤:不能在括號中使用 `;`
+```
+
+## 縮進
+
+Erg 和 Python 一樣,使用縮進來表示塊。 有五個運算符(特殊形式)觸發塊的開始:`=`、`->`、`=>`、`do` 和 `do!`(此外,`:` 和 `|` ,雖然不是運算符,但也會產生縮進)。 每個的含義將在后面描述。
+
+```python
+f x, y =
+ x + y
+
+for! 0..9, i =>
+ print!
+
+for! 0..9, i =>
+ print! i; print! i
+
+ans = match x:
+ 0 -> "zero"
+ _: 0..9 -> "1 dight"
+ _: 10..99 -> "2 dights"
+ _ -> "unknown"
+```
+
+如果一行太長,可以使用 `\` 將其斷開
+
+```python
+# 這不是表示 `x + y + z` 而是表示 `x; +y; +z`
+X
++ y
++ z
+
+# 這意味著`x + y + z`
+x \
++ y \
++ z
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/01_literal.md b/doc/zh_TW/syntax/01_literal.md
new file mode 100644
index 00000000..25bc6f1b
--- /dev/null
+++ b/doc/zh_TW/syntax/01_literal.md
@@ -0,0 +1,151 @@
+# 字面量
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/01_literal.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 基本字面量
+
+### 整數字面量
+
+```python
+0, -0, 1, -1, 2, -2, 3, -3, ...
+```
+
+### 比率文字
+
+```python
+0.00, -0.0, 0.1, 400.104, ...
+```
+
+如果“比率”文字的整數或小數部分為`0`,則可以省略`0`
+
+```python
+assert 1.0 == 1.
+assert 0.5 == .5
+```
+
+> __注意__:這個函數 `assert` 用于表明 `1.0` 和 `1.` 相等。
+后續文檔可能會使用 `assert` 來表示結果是相等的。
+
+### 字符串字面量
+
+可以使用任何 Unicode 可表示的字符串。
+與 Python 不同,引號不能包含在 `'` 中。 如果要在字符串中使用 `"`,請使用 `\"`。
+
+```python
+"", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "?????????? ??????????", ...
+```
+
+`{}` 允許您在字符串中嵌入表達式。 這稱為字符串插值。
+如果要輸出 `{`、`}` 本身,請使用 `\{`、`\}`。
+
+```python
+assert "1 + 1 is 2" == "{1} + {1} is {1+1}"
+s = "1+1"
+assert "\{1+1}\" == "\{{s}\}"
+```
+
+### 指數字面量
+
+這是學術計算中常用的表示指數符號的文字。 它是“比率”類型的一個實例。
+該符號與 Python 中的符號相同。
+
+```python
+1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ...
+```
+
+```python
+assert 1e-10 == 0.0000000001
+```
+
+## 復合字面量
+
+這些文字中的每一個都有自己的文檔分別描述它們,因此請參閱該文檔以獲取詳細信息。
+
+### [數組字面量](./10_array.md)
+
+```python
+[], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ...
+```
+
+### [字典字面量](./11_dict.md)
+
+```python
+{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
+```
+
+### [元組字面量](./12_tuple.md)
+
+```python
+(), (1, 2, 3), (1, "hello", True), ...
+```
+
+### [Record 字面量](./13_record.md)
+
+```python
+{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
+```
+
+### [Set 字面量](./14_set.md)
+
+```python
+{}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ...
+```
+
+與 `Array` 字面量不同的是,`Set` 中刪除了重復元素
+
+```python
+assert {1, 2, 1} == {1, 2}
+```
+
+### 看起來像文字但不是
+
+## 布爾對象
+
+```python
+True, False
+```
+
+### None 對象
+
+```python
+None
+```
+
+## Range 對象
+
+```python
+assert 0..5 == {1, 2, 3, 4, 5}
+assert 0..10 in 5
+assert 0..<10 notin 10
+assert 0..9 == 0..<10
+```
+
+## Float 對象
+
+```python
+assert 0.0f64 == 0
+assert 0.0f32 == 0.0f64
+```
+
+浮點對象是通過將 `Ratio` 對象乘以 `f64` 構造的,后者是 `Float 64` 單位對象
+
+## Complex 對象
+
+```python
+1+2im, 0.4-1.2im, 0im, im
+```
+
+一個“復雜”對象只是一個虛數單位對象`im`的算術組合
+
+## *-less 乘法
+
+在 Erg 中,您可以省略 `*` 來表示乘法,只要解釋上沒有混淆即可。 但是,運算符的組合強度設置為強于 `*`。
+
+```python
+# same as `assert (1*m) / (1*s) == 1*(m/s)`
+assert 1m / 1s == 1 (m/s)
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/02_name.md b/doc/zh_TW/syntax/02_name.md
new file mode 100644
index 00000000..5feed6d3
--- /dev/null
+++ b/doc/zh_TW/syntax/02_name.md
@@ -0,0 +1,166 @@
+# 多變的
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+變量是一種代數; Erg 中的代數 - 如果沒有混淆,有時簡稱為變量 - 指的是命名對象并使它們可從代碼的其他地方引用的功能。
+
+變量定義如下。
+`n` 部分稱為變量名(或標識符),`=` 是賦值運算符,`1` 部分是賦值。
+
+```python
+n = 1
+```
+
+以這種方式定義的“n”此后可以用作表示整數對象“1”的變量。 該系統稱為分配(或綁定)。
+我們剛剛說過`1`是一個對象。 稍后我們將討論對象是什么,但現在我們假設它是可以賦值的,即在賦值運算符的右側(`=` 等)。
+
+如果要指定變量的“類型”,請執行以下操作。 類型大致是一個對象所屬的集合,后面會解釋。
+這里我們指定`n`是自然數(`Nat`)類型。
+
+```python
+n: Nat = 1
+```
+
+請注意,與其他語言不同,不允許多次分配
+
+```python
+# NG
+l1 = l2 = [1, 2, 3] # 語法錯誤:不允許多重賦值
+# OK
+l1 = [1, 2, 3]
+l2 = l1.clone()
+```
+
+也不能重新分配給變量。 稍后將描述可用于保存可變狀態的語法
+
+```python
+i = 1
+i = i + 1 # 分配錯誤:不能分配兩次
+```
+
+您可以在內部范圍內定義具有相同名稱的變量,但您只是覆蓋它,而不是破壞性地重寫它的值。 如果您返回外部范圍,該值也會返回。
+請注意,這是與 Python “語句”范圍不同的行為。
+這種功能通常稱為陰影。 但是,與其他語言中的陰影不同,您不能在同一范圍內進行陰影。
+
+```python
+x = 0
+# x = 1 # 賦值錯誤:不能賦值兩次
+if x.is_zero(), do:
+ x = 1 # 與同名的外部 x 不同
+ assert x == 1
+assert x == 0
+```
+
+乍一看,以下內容似乎可行,但仍然不可能。 這是一個設計決定,而不是技術限制。
+
+```python
+x = 0
+if x.is_zero(), do:
+ x = x + 1 # 名稱錯誤:無法定義變量引用同名變量
+ assert x == 1
+assert x == 0
+```
+
+## 常量
+
+常數也是一種代數。 如果標識符以大寫字母開頭,則將其視為常量。 它們被稱為常量,因為一旦定義,它們就不會改變。
+`N` 部分稱為常量名(或標識符)。 否則,它與變量相同。
+
+```python
+N = 0
+if True, do:
+ N = 1 # 賦值錯誤:常量不能被遮蔽
+ pass()
+```
+
+常量在定義的范圍之外是不可變的。 他們不能被遮蔽。 由于這個屬性,常量可以用于模式匹配。 模式匹配在后面解釋。
+
+例如,常量用于數學常量、有關外部資源的信息和其他不可變值。
+
+除了 [types](./type/01_type_system.md) 之外的對象標識符使用全大寫(所有字母大寫的樣式)是常見的做法。
+
+```python
+PI = 3.141592653589793
+URL = "https://example.com"
+CHOICES = ["a", "b", "c"]
+```
+
+```python
+PI = 3.141592653589793
+match! x:
+ PI => print! "π"
+ other => print! "other"
+```
+
+當 `x` 為 `3.141592653589793` 時,上面的代碼會打印 `π`。 如果 `x` 更改為任何其他數字,它會打印 `other`。
+
+有些對象不能綁定為常量。 例如,可變對象。 可變對象是其狀態可以改變的對象,后面會詳細介紹。
+這是因為只有常量表達式才能分配給常量的規則。 常量表達式也將在后面討論。
+
+```python
+X = 1 # OK
+X = !1 # 類型錯誤:無法定義 Int! 對象作為常量
+```
+
+## 刪除變量
+
+您可以使用 `Del` 函數刪除變量。 依賴于變量的所有其他變量(即直接引用變量值的變量)也將被刪除。
+
+```python
+x = 1
+y = 2
+Z = 3
+f a = x + a
+
+assert f(2) == 3
+Del x
+Del y, Z
+
+f(2) # 名稱錯誤:f 未定義(在第 6 行中刪除)
+```
+
+注意 `Del` 只能刪除用戶自定義模塊中定義的變量。 無法刪除諸如“True”之類的內置常量。
+
+```python
+Del True # 類型錯誤:無法刪除內置常量
+Del print! # TypeError: 無法刪除內置變量
+```
+
+## 附錄:賦值和等價
+
+請注意,當 `x = a` 時,`x == a` 不一定為真。 一個例子是`Float.NaN`。 這是 IEEE 754 定義的浮點數的正式規范。
+
+```python
+x = Float.NaN
+assert x ! = NaN
+assert x ! = x
+```
+
+還有其他對象首先沒有定義等價關系。
+
+```python
+f = x -> x**2 + 2x + 1
+g = x -> (x + 1)**2
+f == g # 類型錯誤:無法比較函數對象
+
+C = Class {i: Int}
+D = Class {i: Int}
+C == D # 類型錯誤:無法比較類對象
+```
+
+嚴格來說,`=` 不會將右側的值直接分配給左側的標識符。
+在函數和類對象的情況下,執行“修改”,例如將變量名稱信息賦予對象。 但是,結構類型并非如此。
+
+```python
+f x = x
+print! f # <函數 f>
+g x = x + 1
+print! g # <函數 g>
+
+C = Class {i: Int}
+print! C # <類 C>
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/03_declaration.md b/doc/zh_TW/syntax/03_declaration.md
new file mode 100644
index 00000000..b984c65a
--- /dev/null
+++ b/doc/zh_TW/syntax/03_declaration.md
@@ -0,0 +1,49 @@
+# 宣言(Declaration)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/03_declaration.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+聲明是用于指定要使用的變量類型的語法。
+可以在代碼中的任何地方進行聲明,但單獨的聲明并不引用變量。 它們必須被初始化。
+分配后,可以檢查聲明以確保類型與分配它的對象兼容。
+
+```python
+i: Int
+# 可以與賦值同時聲明,如 i: Int = 2
+i = 2
+i: Num
+i: Nat
+i: -2..2
+i: {2}
+```
+
+賦值后的聲明類似于`assert`的類型檢查,但具有在編譯時檢查的特點。
+在運行時通過`assert`進行類型檢查可以檢查“可能是Foo類型”,但是在編譯時通過`:`進行類型檢查是嚴格的:如果類型未確定為“類型Foo”,則不會通過 檢查會出現錯誤。
+
+```python
+i = (-1..10).sample!
+assert i in Nat # 這可能會通過
+i: Int # 這會通過
+i: Nat # 這不會通過(-1 不是 Nat 的元素)
+```
+
+函數可以用兩種不同的方式聲明。
+
+```python
+f: (x: Int, y: Int) -> Int
+f: (Int, Int) -> Int
+```
+
+如果顯式聲明參數名稱,如果在定義時名稱不同,則會導致類型錯誤。 如果你想給參數名稱任意命名,你可以用第二種方式聲明它們。 在這種情況下,類型檢查只會看到方法名稱及其類型。
+
+```python
+T = Trait {
+ .f = (x: Int, y: Int): Int
+}
+
+C = Class(U, Impl := T)
+C.f(a: Int, b: Int): Int = ... # 類型錯誤:`.f` 必須是 `(x: Int, y: Int) -> Int` 的類型,而不是 `(a: Int, b: Int) -> Int`
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/04_function.md b/doc/zh_TW/syntax/04_function.md
new file mode 100644
index 00000000..3fb06cd5
--- /dev/null
+++ b/doc/zh_TW/syntax/04_function.md
@@ -0,0 +1,292 @@
+# 功能
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/04_function.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+函數是一個塊,它接受一個“參數”,對其進行處理,并將其作為“返回值”返回。 定義如下。
+
+```python
+add x, y = x + y
+# 或者
+add(x, y) = x + y
+```
+
+在函數名之后指定的名稱稱為參數。
+相反,傳遞給函數的對象稱為參數。
+函數 `add` 是一個以 `x` 和 `y` 作為參數并返回它們之和的函數,`x + y`。
+可以按如下方式調用(應用/調用)定義的函數。
+
+```python
+add 1, 2
+# or
+add(1, 2)
+```
+
+## 冒號應用風格
+
+函數像`f x, y, ...`一樣被調用,但是如果單行參數太多,可以使用`:`(冒號)來應用它們。
+
+```python
+f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4
+```
+
+```python
+f some_long_name_variable_1 + some_long_name_variable_2:
+ some_long_name_variable_3 * some_long_name_variable_4
+```
+
+```python
+f:
+ some_long_name_variable_1 + some_long_name_variable_2
+ some_long_name_variable_3 * some_long_name_variable_4
+```
+
+以上三個代碼的含義相同。 例如,這種風格在使用 `if` 函數時也很有用
+
+```python
+result = if Bool.sample!():
+ do:
+ log "True was chosen"
+ 1
+ do:
+ log "False was chosen"
+ 0
+```
+
+在 `:` 之后,除了注釋之外,不得編寫任何代碼,并且必須始終在新行上
+
+## 關鍵字參數
+
+如果使用大量參數定義函數,則存在以錯誤順序傳遞參數的危險。
+在這種情況下,使用關鍵字參數調用函數是安全的。
+
+```python
+f x, y, z, w, v, u: Int = ...
+```
+
+上面定義的函數有很多參數,并且排列順序混亂。 您不應該創建這樣的函數,但是在使用別人編寫的代碼時可能會遇到這樣的代碼。 因此,我們使用關鍵字參數。 如果使用關鍵字參數,則值會從名稱傳遞到正確的參數,即使它們的順序錯誤。
+
+```python
+f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3
+```
+
+請注意,緊跟在 `:` 之后的關鍵字參數和新行被視為冒號調用樣式
+
+```python
+# 意思是 `f(x: y)`
+f x: y
+
+# 意思是 `f(x, y)`
+f x:
+ y
+```
+
+## 定義錯誤參數
+
+當某些參數大部分是固定的并且您希望能夠省略它們時,使用默認參數。
+
+默認參數由`:=`(walrus運算符)指定。 如果未指定 `base`,則將 `math.E` 分配給 `base`。
+
+```python
+math_log x: Ratio, base := math.E = ...
+
+assert math_log(100, 10) == 2
+assert math_log(100) == math_log(100, math.E)
+```
+
+請注意,不指定參數和指定`None`是有區別的
+
+```python
+p! x := 0 = print!
+p!(2) # 2
+p!() # 0
+p!(None) # None
+```
+
+也可以與類型規范和模式一起使用
+
+```python
+math_log x, base: Ratio := math.E = ...
+f [x, y] := [1, 2] = ...
+```
+
+但是,在默認參數中,不能調用過程(稍后描述)或分配可變對象
+
+```python
+f x := p! 1 = ... # NG
+```
+
+此外,剛剛定義的參數不能用作傳遞給默認參數的值
+
+```python
+f x := 1, y := x = ... # NG
+```
+
+## 可變長度參數
+
+輸出其參數的日志(記錄)的 `log` 函數可以采用任意數量的參數。
+
+```python
+記錄“你好”、“世界”、“!” # 你好世界 !
+```
+
+要定義這樣的函數,請將 `...` 添加到參數中。 這樣,函數將參數作為可變長度數組接收
+
+```python
+f ...x =
+ for x, i ->
+ log i
+
+# x == [1, 2, 3, 4, 5]
+f 1, 2, 3, 4, 5
+```
+
+## 具有多種模式的函數定義
+
+```python
+fib n: Nat =
+ match n:
+ 0 -> 0
+ 1 -> 1
+ n -> fib(n - 1) + fib(n - 2)
+```
+
+像上面這樣的函數,其中 `match` 直接出現在定義下,可以重寫如下
+
+```python
+fib 0 = 0
+fib 1 = 1
+fib(n: Nat): Nat = fib(n - 1) + fib(n - 2)
+```
+
+注意一個函數定義有多個模式不是所謂的重載(multiple definition); 一個函數只有一個定義。 在上面的示例中,“n”必須與“0”或“1”屬于同一類型。 此外,與 `match` 一樣,模式匹配是從上到下完成的。
+
+如果不同類的實例混合在一起,最后一個定義必須指定函數參數的類型為`Or`
+
+```python
+f "aa" = ...
+f 1 = ...
+# `f x = ... ` 無效
+f x: Int or Str = ...
+```
+
+此外,像 `match` 一樣,它也必須是詳盡的。
+
+```python
+fib 0 = 0
+fib 1 = 1
+# 模式錯誤:fib 參數的模式并不詳盡
+```
+
+但是,可以通過使用稍后描述的 [refinement type](./type/12_refinement.md) 顯式指定類型來使其詳盡無遺。
+
+```python
+fib: 0..1 -> 0..1
+fib 0 = 0
+fib 1 = 1
+# OK
+```
+
+## 遞歸函數
+
+遞歸函數是在其定義中包含自身的函數。
+
+作為一個簡單的例子,讓我們定義一個執行階乘計算的函數`factorial`。 階乘是“將所有小于或等于的正數相乘”的計算。
+5 的階乘是 `5*4*3*2*1 == 120`。
+
+```python
+factorial 0 = 1
+factorial 1 = 1
+factorial(n: Nat): Nat = n * factorial(n - 1)
+```
+
+首先,從階乘的定義來看,0和1的階乘都是1。
+反過來,2的階乘是`2*1 == 2`,3的階乘是`3*2*1 == 6`,4的階乘是`4*3*2*1 == 24 `。
+如果我們仔細觀察,我們可以看到一個數 n 的階乘是前一個數 n-1 乘以 n 的階乘。
+將其放入代碼中,我們得到 `n * factorial(n - 1)`。
+由于 `factorial` 的定義包含自身,`factorial` 是一個遞歸函數。
+
+提醒一下,如果您不添加類型規范,則會這樣推斷。
+
+```python
+factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int
+factorial 0 = 1
+factorial 1 = 1
+factorial n = n * factorial(n - 1)
+```
+
+但是,即使您可以推理,您也應該明確指定遞歸函數的類型。 在上面的例子中,像“factorial(-1)”這樣的代碼可以工作,但是
+
+```python
+factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ...
+```
+
+并且這種計算不會停止。 遞歸函數必須仔細定義值的范圍,否則您可能會陷入無限循環。
+所以類型規范也有助于避免接受意外的值。
+
+## 編譯時函數
+
+函數名以大寫字母開頭,表示編譯時函數。 用戶定義的編譯時函數必須將所有參數作為常量,并且必須指定它們的類型。
+編譯時函數的功能有限。 在編譯時函數中只能使用常量表達式,即只有一些運算符(例如求積、比較和類型構造操作)和編譯時函數。 要傳遞的參數也必須是常量表達式。
+作為回報,優點是計算可以在編譯時完成。
+
+```python
+Add(X, Y: Nat): Nat = X + Y
+assert Add(1, 2) == 3
+
+Factorial 0 = 1
+Factorial(X: Nat): Nat = X * Factorial(X - 1)
+assert Factorial(10) == 3628800
+
+math = import "math"
+Sin X = math.sin X # 常量錯誤:此函數在編譯時不可計算
+```
+
+編譯時函數也用于多態類型定義。
+
+```python
+Option T: Type = T or NoneType
+Option: Type -> Type
+```
+
+## 附錄:功能對比
+
+Erg 沒有為函數定義 `==`。 這是因為通常沒有函數的結構等價算法。
+
+```python
+f = x: Int -> (x + 1)**2
+g = x: Int -> x**2 + 2x + 1
+
+assert f == g # 類型錯誤:無法比較函數
+```
+
+盡管 `f` 和 `g` 總是返回相同的結果,但要做出這樣的決定是極其困難的。 我們必須向編譯器教授代數。
+所以 Erg 完全放棄了函數比較,并且 `(x -> x) == (x -> x)` 也會導致編譯錯誤。 這是與 Python 不同的規范,應該注意
+
+```python
+# Python,奇怪的例子
+f = lambda x: x
+assert f == f
+assert (lambda x: x) ! = (lambda x: x)
+```
+
+## Appendix2: ()-completion
+
+```python
+f x: Object = ...
+# 將完成到
+f(x: Object) = ...
+
+f a
+# 將完成到
+f(a)
+
+f a, b # 類型錯誤:f() 接受 1 個位置參數,但給出了 2 個
+f(a, b) # # 類型錯誤:f() 接受 1 個位置參數,但給出了 2 個
+f((a, b)) # OK
+```
+
+函數類型`T -> U`實際上是`(T,) -> U`的語法糖。
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/05_builtin_funcs.md b/doc/zh_TW/syntax/05_builtin_funcs.md
new file mode 100644
index 00000000..1df9023d
--- /dev/null
+++ b/doc/zh_TW/syntax/05_builtin_funcs.md
@@ -0,0 +1,51 @@
+# 內置函數
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/05_builtin_funcs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 如果
+
+`if` 是一個根據條件改變處理的函數。
+
+```python
+result: Option Int = if! Bool.sample!(), do:
+ log "True was chosen"
+ 1
+print! result # None (or 1)
+```
+
+`.sample!()` 返回一組隨機值。 如果返回值為真,`print! “真”`被執行。
+如果條件為假,您還可以指定要執行的操作; 第二個 do 塊稱為 else 塊。
+
+```python
+result: Nat = if Bool.sample!():
+ do:
+ log "True was chosen"
+ 1
+ do:
+ log "False was chosen"
+ 0
+print! result # 1 (or 0)
+```
+
+如果進程是單行,則可以省略縮進。
+
+```python
+result = if Bool.sample!():
+ do 1
+ do 0
+```
+
+## for
+
+你可以使用 `for` 來編寫一個重復的過程。
+
+```python
+match_s(ss: Iterator(Str), pat: Pattern): Option Str =
+ for ss, s ->
+ if pat.match(s).is_some():
+ break s
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/06_operator.md b/doc/zh_TW/syntax/06_operator.md
new file mode 100644
index 00000000..84e7d71f
--- /dev/null
+++ b/doc/zh_TW/syntax/06_operator.md
@@ -0,0 +1,31 @@
+# 運算符
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/06_operator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+運算符是表示操作的符號。 操作數是運算符(左)右側的東西。
+
+運算符是一種函數,因此它們本身就是可以綁定到變量的一流對象。 綁定時,需要用```括起來。
+對于`+`(和`-`),有一元和二元運算符,所以必須指定`_+_`(二元運算)/`+_`(一元運算)。
+
+```python
+add = `+` # 語法錯誤:指定 `_+_` 或 `+_`
+add=`_+_`
+assert f(1, 2) == 3
+assert f("a", "b") == "ab"
+
+g = `*` # OK, 這只是二進制
+assert g(1, 2) == 2
+```
+
+一些稱為特殊形式的基本運算符不能被綁定。
+
+```python
+def = `=` # 語法錯誤:無法綁定 `=` 運算符,這是一種特殊形式
+# NG: def x, 1
+function = `->` # 語法錯誤:無法綁定 `->` 運算符,這是一種特殊形式
+# NG: function x, x + 1
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/07_side_effect.md b/doc/zh_TW/syntax/07_side_effect.md
new file mode 100644
index 00000000..35722f81
--- /dev/null
+++ b/doc/zh_TW/syntax/07_side_effect.md
@@ -0,0 +1,123 @@
+# 副作用和程序
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/07_side_effect.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+我們一直忽略了解釋“!”的含義,但現在它的含義終于要揭曉了。 這個 `!` 表示這個對象是一個帶有“副作用”的“過程”。 過程是具有副作用的函數。
+
+```python
+f x = print! x # EffectError: 不能為函數分配有副作用的對象
+# 提示:將名稱更改為 'f!'
+```
+
+上面的代碼會導致編譯錯誤。 這是因為您在函數中使用了過程。 在這種情況下,您必須將其定義為過程。
+
+```python
+p! x = print! x
+```
+
+`p!`, `q!`, ... 是過程的典型變量名。
+以這種方式定義的過程也不能在函數中使用,因此副作用是完全隔離的。
+
+## 方法
+
+函數和過程中的每一個都可以是方法。 函數式方法只能對`self`進行不可變引用,而程序性方法可以對`self`進行可變引用。
+`self` 是一個特殊的參數,在方法的上下文中是指調用對象本身。 引用 `self` 不能分配給任何其他變量。
+
+```python
+C!.
+ method ref self =
+ x = self # 所有權錯誤:無法移出`self`
+ x
+```
+
+程序方法也可以采取 `self` 的 [ownership](./18_ownership.md)。 從方法定義中刪除 `ref` 或 `ref!`
+
+```python
+n = 1
+s = n.into(Str) # '1'
+n # 值錯誤:n 被 .into 移動(第 2 行)
+```
+
+在任何給定時間,只有一種程序方法可以具有可變引用。 此外,在獲取可變引用時,不能從原始對象獲取更多可變引用。 從這個意義上說,`ref!` 會對`self` 產生副作用。
+
+但是請注意,可以從可變引用創建(不可變/可變)引用。 這允許在程序方法中遞歸和 `print!` 的`self`。
+
+```python
+T -> T # OK (move)
+T -> Ref T # OK (move)
+T => Ref! T # OK (only once)
+Ref T -> T # NG
+Ref T -> Ref T # OK
+Ref T => Ref!
+T -> Ref T # NG
+T -> Ref T # OK
+T => Ref!
+```
+
+## 附錄:副作用的嚴格定義
+
+代碼是否具有副作用的規則無法立即理解。
+直到你能理解它們,我們建議你暫時把它們定義為函數,如果出現錯誤,添加`!`將它們視為過程。
+但是,對于那些想了解該語言的確切規范的人,以下是對副作用的更詳細說明。
+
+首先,必須聲明返回值的等價與 Erg 中的副作用無關。
+有些過程對于任何給定的 `x` 都會導致 `p!(x) == p!(x)`(例如,總是返回 `None`),并且有些函數會導致 `f(x) ! = f(x)`。
+
+前者的一個例子是`print!`,后者的一個例子是下面的函數。
+
+```python
+nan _ = Float.NaN
+assert nan(1) ! = nan(1)
+```
+
+還有一些對象,例如類,等價確定本身是不可能的
+
+```python
+T = Structural {i = Int}
+U = Structural {i = Int}
+assert T == U
+
+C = Class {i = Int}
+D = Class {i = Int}
+assert C == D # 類型錯誤:無法比較類
+```
+
+言歸正傳:Erg 中“副作用”的準確定義是
+
+* 訪問可變的外部信息。
+
+“外部”一般是指外部范圍; Erg 無法觸及的計算機資源和執行前/執行后的信息不包含在“外部”中。 “訪問”包括閱讀和寫作。
+
+例如,考慮 `print!` 過程。 乍一看,`print!` 似乎沒有重寫任何變量。 但如果它是一個函數,它可以重寫外部變量,例如,使用如下代碼:
+
+```python
+camera = import "some_camera_module"
+ocr = import "some_ocr_module"
+
+n = 0
+_ =
+ f x = print x # 假設我們可以使用 print 作為函數
+ f(3.141592)
+cam = camera.new() # 攝像頭面向 PC 顯示器
+image = cam.shot!()
+n = ocr.read_num(image) # n = 3.141592
+```
+
+將“camera”模塊視為為特定相機產品提供 API 的外部庫,將“ocr”視為用于 OCR(光學字符識別)的庫。
+直接的副作用是由 `cam.shot!()` 引起的,但顯然這些信息是從 `f` 泄露的。 因此,`print!` 本質上不可能是一個函數。
+
+然而,在某些情況下,您可能希望臨時檢查函數中的值,而不想為此目的在相關函數中添加 `!`。 在這種情況下,可以使用 `log` 函數。
+`log` 打印整個代碼執行后的值。 這樣,副作用就不會傳播。
+
+```python
+log "this will be printed after execution"
+print! "this will be printed immediately"
+# 這將立即打印
+# 這將在執行后打印
+```
+
+如果沒有反饋給程序,或者換句話說,如果沒有外部對象可以使用內部信息,那么信息的“泄漏”是可以允許的。 只需要不“傳播”信息。
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/08_procedure.md b/doc/zh_TW/syntax/08_procedure.md
new file mode 100644
index 00000000..d0f5408b
--- /dev/null
+++ b/doc/zh_TW/syntax/08_procedure.md
@@ -0,0 +1,14 @@
+# 程序
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/08_procedure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+處理可變對象時需要過程,但將可變對象作為參數并不一定使其成為過程。
+這是一個函數接受一個可變對象(不是過程)。
+
+```python
+peek_str s: Str! = log s
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/09_builtin_procs.md b/doc/zh_TW/syntax/09_builtin_procs.md
new file mode 100644
index 00000000..67130a36
--- /dev/null
+++ b/doc/zh_TW/syntax/09_builtin_procs.md
@@ -0,0 +1,16 @@
+# 內置程序
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/09_builtin_procs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## id!
+
+返回對象的唯一標識號。
+盡管在純 Erg 語義中,結構相同的對象之間沒有區別,但實際上對象在內存中具有不同的位置。
+`id!` 返回一個代表這個位置的數字。
+
+```python
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/10_array.md b/doc/zh_TW/syntax/10_array.md
new file mode 100644
index 00000000..cad38bb1
--- /dev/null
+++ b/doc/zh_TW/syntax/10_array.md
@@ -0,0 +1,54 @@
+# Array
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/10_array.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+數組是最基本的__collection(聚合)__。
+集合是一個可以在其中包含多個對象的對象。
+
+```python
+a = [1, 2, 3]
+a: [Int; 3] # 類型說明:分號后的數字為元素個數
+# 如果元素個數未知,可以省略
+a: [Int]
+
+mut_a = [!1, !2, !3]
+mut_a[0].inc!()
+assert mut_a == [2, 2, 3]
+```
+
+通常,數組不能包含不同類型的對象。
+
+```python.
+[1, "a"] # 類型錯誤:第一個元素是 Int,但第二個元素是 Str
+```
+
+但是,您可以通過像這樣顯式指定類型來繞過限制。
+
+```python
+[1, "a"]: [Int or Str].
+```
+
+## 切片
+
+一個數組也可以同時取出多個值。 這稱為切片。
+
+```python
+l = [1, 2, 3, 4]
+# 與 Python 中的 l[1:3] 相同
+assert l[1.. <3] == [2, 3]
+assert l[1..2] == [2, 3]
+# 與 l[1] 相同
+assert l[1..1] == [2]
+# 與 Python 中的 l[::2] 相同
+assert l[..].step(2) == [2, 4]
+```
+
+通過切片獲得的對象是數組的(不可變的)副本
+
+```python
+print! Typeof l[1..2] # [Int; 4]
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/11_tuple.md b/doc/zh_TW/syntax/11_tuple.md
new file mode 100644
index 00000000..0b35dc97
--- /dev/null
+++ b/doc/zh_TW/syntax/11_tuple.md
@@ -0,0 +1,118 @@
+# 元組
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/11_tuple.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+元組類似于數組,但可以保存不同類型的對象。
+這樣的集合稱為不等集合。 相比之下,同構集合包括數組、集合等。
+
+```python
+t = (1, True, "a")
+(i, b, s) = t
+assert(i == 1 and b == True and s == "a")
+```
+
+元組`t`可以以`t.n`的形式檢索第n個元素; 請注意,與 Python 不同,它不是 `t[n]`。
+這是因為訪問元組元素更像是一個屬性(在編譯時檢查元素的存在,并且類型可以根據 `n` 改變)而不是方法(數組的 `[]` 是一種方法)。
+
+```python
+assert t.0 == 1
+assert t.1 == True
+assert t.2 == "a"
+```
+
+括號 `()` 在不嵌套時是可選的。
+
+```python
+t = 1, True, "a"
+i, b, s = t
+```
+
+元組可以保存不同類型的對象,因此它們不能像數組一樣被迭代。
+
+```python
+t: ({1}, {2}, {3}) = (1, 2, 3)
+(1, 2, 3).iter().map(x -> x + 1) # 類型錯誤:類型 ({1}, {2}, {3}) 沒有方法 `.iter()`
+# 如果所有類型都相同,則可以像數組一樣用`(T; n)`表示,但這仍然不允許迭代
+t: (Int; 3) = (1, 2, 3)
+assert (Int; 3) == (Int, Int, Int)
+```
+
+但是,非同質集合(如元組)可以通過向上轉換、相交等方式轉換為同質集合(如數組)。
+這稱為均衡。
+
+```python
+(Int, Bool, Str) can be [T; 3] where T :> Int, T :> Bool, T :> Str
+```
+
+```python
+t: (Int, Bool, Str) = (1, True, "a") # 非同質
+a: [Int or Bool or Str; 3] = [1, True, "a"] # 同質的
+_a: [Show; 3] = [1, True, "a"] # 同質的
+_a.iter().map(x -> log x) # OK
+t.try_into([Show; 3])? .iter().map(x -> log x) # OK
+```
+
+## 單元
+
+零元素的元組稱為 __unit__。 一個單元是一個值,但也指它自己的類型。
+
+```python
+unit = ()
+(): ()
+```
+
+Unit 是所有元素 0 元組的父類。
+
+```python
+() > (Int; 0)
+() > (Str; 0)
+```
+
+該對象的用途是用于沒有參數和沒有返回值的過程等。Erg 子例程必須有參數和返回值。 但是,在某些情況下,例如過程,可能沒有有意義的參數或返回值,只有副作用。 在這種情況下,我們將單位用作“無意義的正式值”
+
+```python
+# ↓ Actually, this parenthesis is a unit
+p!() =.
+ # `print!` does not return a meaningful value
+ print! "Hello, world!"
+p!: () => ()
+```
+
+但是,在這種情況下,Python 傾向于使用“無”而不是單位。
+在 Erg 中,當您從一開始就確定操作不會返回有意義的值(例如在過程中)時,您應該使用 `()`,并且當操作可能失敗并且您可能會返回 `None` 將一無所獲,例如在檢索元素時。
+
+## 參數和元組
+
+實際上,Erg 的所有 `Callable` 對象都是一個參數和一個返回值; 一個接受 N 個參數的子例程只是接收“一個具有 N 個元素的元組”作為參數。
+
+```python
+# f x = ... 被隱式假設為 f(x) = ... 被認為是
+f x = x
+assert f(1) == 1
+f(1, 2, 3) # 參數錯誤:f 接受 1 個位置參數,但給出了 3 個
+g x: Int, . . y: Int = y
+assert (2, 3) == g 1, 2, 3
+```
+
+這也解釋了函數類型。
+
+```python
+assert f in T: {(T,) -> T | T}
+assert g in {(Int, ... (Int; N)) -> (Int; N) | N: Nat}
+```
+
+準確地說,函數的輸入不是元組,而是“具有默認屬性的命名元組”。 這是一個特殊的元組,只能在函數參數中使用,可以像記錄一樣命名,并且可以有默認值。
+
+```python
+f(x: Int, y=0) = x + y
+f: (Int, y=Int) -> Int
+
+f(x=0, y=1)
+f(y=1, x=0)
+f(x=0)
+f(0)
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/12_dict.md b/doc/zh_TW/syntax/12_dict.md
new file mode 100644
index 00000000..a8ff4003
--- /dev/null
+++ b/doc/zh_TW/syntax/12_dict.md
@@ -0,0 +1,69 @@
+# 字典
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/12_dict.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Dict 是鍵/值對的集合。
+
+```python
+ids = {"Alice": 145, "Bob": 214, "Charlie": 301}
+assert ids["Alice"] == 145
+```
+
+如果鍵是“哈希”對象,則鍵不必是字符串。
+
+```python
+# 不推薦使用范圍對象作為鍵(與切片混淆)
+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 與 Set 類似。
+您可以說 Dict 是具有值的 Set。
+
+```python
+{"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214}
+```
+
+從 dict 文字生成 dict 時,會檢查重復鍵。
+任何重復都會導致編譯錯誤。
+
+```python
+{"Alice": 145, "Alice": 1} # Key錯誤:重復鍵`Alice`
+```
+
+空字典是用 `{:}` 創建的。 請注意,`{}` 表示一個空集。
+
+```python
+mut_dict = !{:}
+mut_dict.insert! "Alice", 145
+mut_dict.insert! "Bob", 214
+assert mut_dict["Alice"] == 145
+```
+
+## 異構字典
+
+不需要有單一的鍵/值類型。 這樣的字典稱為 __heterogenous dict_。
+
+```python
+d: {Str: Int, Int: Str} = {"a": 1, 1: "a"}
+assert d["a"] == 1
+assert d[1] == "a"
+```
+
+但是,不能將相同類型的值分配給不同類型的鍵,或者將不同類型的值分配給相同類型的鍵。
+在這種情況下,請改用 Or 類型。
+
+```python
+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}
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/13_record.md b/doc/zh_TW/syntax/13_record.md
new file mode 100644
index 00000000..0c713680
--- /dev/null
+++ b/doc/zh_TW/syntax/13_record.md
@@ -0,0 +1,201 @@
+# 記錄(Record)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/13_record.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+記錄是一個集合,它結合了通過鍵訪問的 Dict 和在編譯時檢查其訪問的元組的屬性。
+如果您了解 JavaScript,請將其視為一種(更增強的)對象字面量表示法。
+
+```python
+john = {.name = "John"; .age = 21}
+
+assert john.name == "John"
+assert john.age == 21
+assert john in {.name = Str; .age = Nat}
+john["name"] # 錯誤:john 不可訂閱
+```
+
+`.name` 和 `.age` 部分稱為屬性,而 `"John"` 和 `21` 部分稱為屬性值。
+
+與 JavaScript 對象字面量的區別在于它們不能作為字符串訪問。 也就是說,屬性不僅僅是字符串。
+這是因為對值的訪問是在編譯時確定的,而且字典和記錄是不同的東西。 換句話說,`{"name": "John"}` 是一個字典,`{name = "John"}` 是一個記錄。
+那么我們應該如何使用字典和記錄呢?
+一般來說,我們建議使用記錄。 記錄具有在編譯時檢查元素是否存在以及能夠指定 __visibility_ 的優點。
+指定可見性等同于在 Java 和其他語言中指定公共/私有。 有關詳細信息,請參閱 [可見性](./15_visibility.md) 了解詳細信息。
+
+```python
+a = {x = 1; .y = x + 1}
+a.x # 屬性錯誤:x 是私有的
+# 提示:聲明為 `.x`。
+assert a.y == 2
+```
+
+對于熟悉 JavaScript 的人來說,上面的示例可能看起來很奇怪,但簡單地聲明 `x` 會使其無法從外部訪問
+
+您還可以顯式指定屬性的類型
+
+```python
+anonymous = {
+ .name: Option! Str = !
+ .age = 20
+}
+anonymous.name.set! "John"
+```
+
+一個記錄也可以有方法。
+
+```python
+o = {
+ .i = !0
+ .inc! ref! self = self.i.inc!()
+}
+
+assert o.i == 0
+o.inc!()
+assert o.i == 1
+```
+
+關于記錄有一個值得注意的語法。 當記錄的所有屬性值都是類(不是結構類型)時,記錄本身表現為一個類型,其自身的屬性作為必需屬性。
+這種類型稱為記錄類型。 有關詳細信息,請參閱 [記錄] 部分。
+
+```python
+# 記錄
+john = {.name = "John"}
+# 記錄 type
+john: {.name = Str}
+Named = {.name = Str}
+john: Named
+
+greet! n: Named =
+ print! "Hello, I am {n.name}"
+john # “你好,我是約翰 print!
+
+Named.name # Str
+```
+
+## 解構記錄
+
+記錄可以按如下方式解構。
+
+```python
+record = {x = 1; y = 2}
+{x = a; y = b} = record
+assert a == 1
+assert b == 2
+
+point = {x = 2; y = 3; z = 4}
+match point:
+ {x = 0; y = 0; z = 0} -> "origin"
+ {x = _; y = 0; z = 0} -> "on the x axis"
+ {x = 0; ...} -> "x = 0"
+ {x = x; y = y; z = z} -> "({x}, {y}, {z})"
+```
+
+當存在與屬性同名的變量時,`x = ...`也可以縮寫為`x`,例如`x = x`或`x = .x`到`x`,和` .x = .x` 或 `.x = x` 到 `.x`。
+但是,當只有一個屬性時,必須在其后加上`;`以與集合區分開來。
+
+```python
+x = 1
+y = 2
+xy = {x; y}
+a = 1
+b = 2
+ab = {.a; .b}
+assert ab.a == 1
+assert ab.b == 2
+
+record = {x;}
+tuple = {x}
+assert tuple.1 == 1
+```
+
+此語法可用于解構記錄并將其分配給變量
+
+```python
+# 一樣 `{x = x; y = y} = xy`
+{x; y} = xy
+assert x == 1
+assert y == 2
+# 一樣 `{.a = a; .b = b} = ab`
+{a; b} = ab
+assert a == 1
+assert b == 2
+```
+
+## 空記錄
+
+空記錄由`{=}`表示。 空記錄也是它自己的類,如 Unit
+
+```python
+empty_record = {=}
+empty_record: {=}
+# Object: Type = {=}
+empty_record: Object
+empty_record: Structural {=}
+{x = 3; y = 5}: Structural {=}
+```
+
+空記錄不同于空 Dict `{:}` 或空集 `{}`。 特別要注意的是,它與 `{}` 的含義相反(在 Python 中,`{}` 是一個空字典,而在 Erg 中它是 Erg 中的 `!{:}`)。
+作為枚舉類型,`{}` 是一個空類型,其元素中不包含任何內容。 `Never` 類型是這種類型的一個分類。
+相反,記錄類 `{=}` 沒有必需的實例屬性,因此所有對象都是它的元素。 `Object` 是 this 的別名。
+一個`Object`(`Object`的一個補丁)是`的一個元素。 __sizeof__` 和其他非常基本的提供方法。
+
+```python
+AnyPatch = Patch Structural {=}
+ . __sizeof__ self = ...
+ .clone self = ...
+ ...
+Never = Class {}
+```
+
+請注意,沒有其他類型或類在結構上與 `{}`、`Never` 類型等效,如果用戶在右側使用 `{}`、`Class {}` 定義類型,則會出錯。
+這意味著,例如,`1..10 或 -10。 -1`,但 `1..10 和 -10... -1`。 例如,當它應該是 1..10 或 -10...-1 時是 `-1`。
+此外,如果您定義的類型(例如 `Int 和 Str`)會導致組合 `Object`,則會警告您只需將其設置為 `Object`。
+
+## 即時封鎖
+
+Erg 有另一種語法 Instant 塊,它只返回最后評估的值。 不能保留屬性。
+
+```python
+x =
+ x = 1
+ y = x + 1
+ y ** 3
+assert x == 8
+
+y =
+ .x = 1 # 語法錯誤:無法在實體塊中定義屬性
+```
+
+## 數據類
+
+如果您嘗試自己實現方法,則必須直接在實例中定義裸記錄(由記錄文字生成的記錄)。
+這是低效的,并且隨著屬性數量的增加,錯誤消息等變得難以查看和使用。
+
+```python
+john = {
+ name = "John Smith"
+ age = !20
+ .greet! ref self = print! "Hello, my name is {self::name} and I am {self::age} years old."
+ .inc_age! ref! self = self::age.update! x -> x + 1
+}
+john + 1
+# 類型錯誤:{name = Str; 沒有實現 + 年齡=詮釋; 。迎接! =參考(自我)。 () => 無; inc_age! =參考! () => 無}, 整數
+```
+
+因此,在這種情況下,您可以繼承一個記錄類。 這樣的類稱為數據類。
+這在 [class](./type/04_class.md) 中有描述。
+
+```python
+Person = Inherit {name = Str; age = Nat}
+Person.
+ greet! ref self = print! "Hello, my name is {self::name} and I am {self::age} years old."
+ inc_age! ref! self = self::age.update! x -> x + 1
+
+john = Person.new {name = "John Smith"; age = 20}
+john + 1
+# 類型錯誤:Person、Int 沒有實現 +
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/14_set.md b/doc/zh_TW/syntax/14_set.md
new file mode 100644
index 00000000..0591a777
--- /dev/null
+++ b/doc/zh_TW/syntax/14_set.md
@@ -0,0 +1,47 @@
+# Set
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/14_set.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+一個Set代表一個集合,它在結構上是一個重復的無序數組。
+
+```python
+assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3}
+assert {1, 2} == {1, 1, 2} # 重復的被自動刪除
+assert {1, 2} == {2, 1}
+```
+
+Set可以執行集合操作。
+
+```python
+assert 1 in {1, 2, 3}
+assert not 1 in {}
+assert {1} or {2} == {1, 2}
+assert {1, 2} and {2, 3} == {2}
+assert {1, 2} not {2} == {1}
+```
+
+Set是同質集合。 為了使不同類的對象共存,它們必須同質化
+
+```python
+s: {Int or Str} = {"a", 1, "b", -1}
+```
+
+## Sets為類型
+Sets也可以被視為類型。 這種類型稱為 _枚舉類型_。
+
+```python
+i: {1, 2, 3} = 1
+assert i in {1, 2, 3}
+```
+
+Set的元素直接是類型的元素。
+請注意,這些Set本身是不同的。
+
+```python
+mut_set = {1, 2, 3}.into {Int; !3}
+mut_set.insert!(4)
+```
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/15_type.md b/doc/zh_TW/syntax/15_type.md
new file mode 100644
index 00000000..c547d3bd
--- /dev/null
+++ b/doc/zh_TW/syntax/15_type.md
@@ -0,0 +1,9 @@
+# 類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/15_type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+類型是 Erg 中一個非常重要的特性,所以我們有一個 [dedicated section](./type/01_type_system.md)。 請看那里。
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/16_iterator.md b/doc/zh_TW/syntax/16_iterator.md
new file mode 100644
index 00000000..bbd0a511
--- /dev/null
+++ b/doc/zh_TW/syntax/16_iterator.md
@@ -0,0 +1,91 @@
+# 迭代器
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/16_iterator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+迭代器是用于檢索容器元素的對象。
+
+```python
+for! 0..9, i =>
+ print! i
+```
+
+此代碼打印數字 0 到 9。
+每個數字(=Int 對象)都分配給`i`,并執行以下操作(=`print!i`)。 這種重復執行稱為__iteration__。
+
+現在讓我們看看 `for!` 過程的類型簽名。
+
+```python
+for!: |T: Type, I <: Iterable T| (I, T => None) => None
+```
+
+第一個參數似乎接受“Iterable”類型的對象。
+
+`Iterable` 是一個具有`.Iterator` 屬性的類型,`.iter` 方法在request 方法中。
+
+```python
+Iterable T = Trait {
+ .Iterator = {Iterator}
+ .iter = Self(T). () -> Self.Iterator T
+}
+```
+
+`.Iterator` 屬性的類型 `{Iterator}` 是所謂的 set-kind(kind 在 [here](./type/advanced/kind.md) 中描述)
+
+```python
+assert [1, 2, 3] in Iterable(Int)
+assert 1..3 in Iterable(Int)
+assert [1, 2, 3].Iterator == ArrayIterator
+assert (1..3).Iterator == RangeIterator
+
+log [1, 2, 3].iter() # <數組迭代器對象>
+log (1..3).iter() #
+```
+
+`ArrayIterator` 和 `RangeIterator` 都是實現 `Iterator` 的類,它們的存在只是為了提供 `Array` 和 `Range` 迭代函數。
+這種設計模式稱為伴生類 [1 ](#1)。
+而“IteratorImpl”補丁是迭代功能的核心。 `Iterator` 只需要一個`.next` 方法,`IteratorImpl` 確實提供了幾十種方法。 `ArrayIterator`和`RangeIterator`只需實現`.next`方法就可以使用`IteratorImpl`的實現方法。 為了方便起見,標準庫實現了許多迭代器。
+
+```mermaid
+classDiagram
+ class Array~T~ {
+ ...
+ iter() ArrayIterator~T~
+ }
+ class Range~T~ {
+ ...
+ iter() RangeIterator~T~
+ }
+ class Iterable~T~ {
+ <>
+ iter() Iterator~T~
+ }
+ Iterable~T~ <|.. Array~T~: Impl
+ Iterable~T~ <|.. Range~T~: Impl
+ class ArrayIterator~T~ {
+ array: Array~T~
+ next() T
+ }
+ class RangeIterator~T~ {
+ range: Range~T~
+ next() T
+ }
+ class Iterator~T~ {
+ <>
+ next() T
+ }
+ Iterator~T~ <|.. ArrayIterator~T~: Impl
+ Iterator~T~ <|.. RangeIterator~T~: Impl
+
+ Array <-- ArrayIterator
+ Range <-- RangeIterator
+```
+
+諸如 `Iterable` 之類的以靜態分派但統一的方式提供用于處理特征(在本例中為 `Iterator`)的接口的類型稱為伴生類適配器。
+
+---
+
+1 這個模式似乎沒有統一的名稱,但是在 Rust 中,有 [companion struct 模式]( https://gist.github.com/qnighy/be99c2ece6f3f4b1248608a04e104b38#:~:text=%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82 %8B%E3%80%82-,companion%20struct,-%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A8%E3%80% 81%E3 %81%9D%E3%81%AE),并以此命名。 [?](#f1)
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/17_mutability.md b/doc/zh_TW/syntax/17_mutability.md
new file mode 100644
index 00000000..339cb1cf
--- /dev/null
+++ b/doc/zh_TW/syntax/17_mutability.md
@@ -0,0 +1,105 @@
+# 可變性
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/17_mutability.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+正如我們已經看到的,所有 Erg 變量都是不可變的。 但是,Erg 對象具有可變性的概念。
+以下面的代碼為例。
+
+```python
+a = [1, 2, 3]
+a = a + [4, 5, 6]
+print! a # [1, 2, 3, 4, 5, 6]
+```
+
+上面的代碼實際上不能被 Erg 執行。 這是因為它不可重新分配。
+
+可以執行此代碼。
+
+```python
+b = ![1, 2, 3]
+b.concat! [4, 5, 6]
+print! b # [1, 2, 3, 4, 5, 6]
+```
+
+`a, b` 的最終結果看起來一樣,但它們的含義卻大不相同。
+雖然 `a` 是表示 `Nat` 數組的變量,但第一行和第二行指向的對象是不同的。 名稱`a`相同,但內容不同。
+
+```python
+a = [1, 2, 3]
+print! id! a # 0x000002A798DFE940
+_a = a + [4, 5, 6]
+print! id! _a # 0x000002A798DFE980
+```
+
+`id!` 過程返回對象駐留的內存地址。
+
+`b` 是一個 `Nat` “動態” 數組。 對象的內容發生了變化,但變量指向的是同一個東西
+
+```python
+b = ![1, 2, 3]
+print! id! b # 0x000002A798DFE220
+b.concat! [4, 5, 6]
+print! id! b # 0x000002A798DFE220
+```
+
+```python
+i = !0
+if! True. do!
+ do! i.inc!() # or i.add!(1)
+ do pass
+print! i # 1
+```
+
+`!` 是一個特殊的運算符,稱為 __mutation 運算符__。 它使不可變對象可變。
+標有“!”的對象的行為可以自定義。
+
+```python
+Point = Class {.x = Int; .y = Int}
+
+# 在這種情況下 .x 是可變的,而 .y 保持不變
+Point! = Class {.x = Int!; .y = Int}
+Point!.
+ inc_x! ref!(self) = self.x.update! x -> x + 1
+
+p = Point!.new {.x = !0; .y = 0}
+p.inc_x!()
+print! p.x # 1
+```
+
+## 常量
+
+與變量不同,常量在所有范圍內都指向同一事物。
+常量使用 `=` 運算符聲明。
+
+```python
+PI = 3.141592653589
+match! x:
+ PI => print! "this is pi"
+```
+
+常量在全局以下的所有范圍內都是相同的,并且不能被覆蓋。因此,它們不能被 ``=`` 重新定義。此限制允許它用于模式匹配。
+`True` 和 `False` 可以用于模式匹配的原因是因為它們是常量。
+此外,常量總是指向不可變對象。諸如 `Str!` 之類的類型不能是常量。
+所有內置類型都是常量,因為它們應該在編譯時確定。可以生成非常量的類型,但不能用于指定類型,只能像簡單記錄一樣使用。相反,類型是其內容在編譯時確定的記錄。
+
+## 變量、名稱、標識符、符號
+
+讓我們理清一些與 Erg 中的變量相關的術語。
+
+變量是一種為對象賦予名稱以便可以重用(或指向該名稱)的機制。
+標識符是指定變量的語法元素。
+符號是表示名稱的語法元素、記號。
+
+只有非符號字符是符號,符號不稱為符號,盡管它們可以作為運算符的標識符。
+例如,`x` 是一個標識符和一個符號。 `x.y` 也是一個標識符,但它不是一個符號。 `x` 和 `y` 是符號。
+即使 `x` 沒有綁定到任何對象,`x` 仍然是一個符號和一個標識符,但它不會被稱為變量。
+`x.y` 形式的標識符稱為字段訪問器。
+`x[y]` 形式的標識符稱為下標訪問器。
+
+變量和標識符之間的區別在于,如果我們在 Erg 的語法理論意義上談論變量,則兩者實際上是相同的。
+在 C 中,類型和函數不能分配給變量; int 和 main 是標識符,而不是變量(嚴格來說可以賦值,但有限制)。
+然而,在Erg語中,“一切都是對象”。不僅函數和類型,甚至運算符都可以分配給變量。
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/18_ownership.md b/doc/zh_TW/syntax/18_ownership.md
new file mode 100644
index 00000000..39656902
--- /dev/null
+++ b/doc/zh_TW/syntax/18_ownership.md
@@ -0,0 +1,112 @@
+#所有權制度
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/18_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+由于 Erg 是一種使用 Python 作為宿主語言的語言,因此內存管理的方法取決于 Python 的實現。
+但語義上 Erg 的內存管理與 Python 的不同。 一個顯著的區別在于所有權制度和禁止循環引用。
+
+## 所有權
+
+Erg 有一個受 Rust 啟發的所有權系統。
+Rust 的所有權系統通常被認為是深奧的,但 Erg 的所有權系統被簡化為直觀。
+在 Erg 中,__mutable objects__ 是擁有的,并且在所有權丟失后無法引用。
+
+```python
+v = [1, 2, 3].into [Int; !3]
+
+push! vec, x =
+ vec.push!(x)
+ vec
+
+# v ([1, 2, 3])的內容歸w所有
+w = push! v, 4
+print! v # 錯誤:v 被移動了
+print!w # [1, 2, 3, 4]
+```
+
+例如,當一個對象被傳遞給一個子程序時,就會發生所有權轉移。
+如果您想在贈送后仍然擁有所有權,則需要克隆、凍結或借用。
+但是,如后所述,可以借用的情況有限。
+
+## 復制
+
+復制一個對象并轉移其所有權。 它通過將 `.clone` 方法應用于實際參數來做到這一點。
+復制的對象與原始對象完全相同,但相互獨立,不受更改影響。
+
+復制相當于 Python 的深拷貝,由于它完全重新創建相同的對象,因此計算和內存成本通常高于凍結和借用。
+需要復制對象的子例程被稱為“參數消耗”子例程。
+
+```python
+capitalize s: Str!=
+ s. capitalize!()
+ s
+
+s1 = !"hello"
+s2 = capitalize s1.clone()
+log s2, s1 # !"HELLO hello"
+```
+
+## 凍結
+
+我們利用了不可變對象可以從多個位置引用的事實,并將可變對象轉換為不可變對象。
+這稱為凍結。 例如,在從可變數組創建迭代器時會使用凍結。
+由于您不能直接從可變數組創建迭代器,請將其轉換為不可變數組。
+如果您不想破壞數組,請使用 [`.freeze_map` 方法](./type/mut.md)。
+
+```python
+# 計算迭代器產生的值的總和
+sum|T <: Add + HasUnit| i: Iterator T = ...
+
+x = [1, 2, 3].into [Int; !3]
+x.push!(4)
+i = x.iter() # 類型錯誤:[Int; !4] 沒有方法 `iter`
+y = x.freeze()
+i = y.iter()
+assert sum(i) == 10
+y # y 仍然可以被觸摸
+```
+
+## 借
+
+借用比復制或凍結便宜。
+可以在以下簡單情況下進行借款:
+
+```python
+peek_str ref(s: Str!) =
+ log s
+
+s = !"hello"
+peek_str s
+```
+
+借來的值稱為原始對象的 __reference__。
+您可以“轉租”對另一個子例程的引用,但您不能使用它,因為您只是借用它。
+
+```python
+steal_str ref(s: Str!) =
+ # 由于日志函數只借用參數,所以可以轉租
+ log s
+ # 錯誤,因為丟棄函數消耗了參數
+ discard s # OwnershipError: 不能消費借來的值
+ # 提示:使用 `clone` 方法
+```
+
+```python
+steal_str ref(s: Str!) =
+ # 這也不好(=消耗右邊)
+ x = s # OwnershipError: 不能消費借來的值
+ x
+```
+
+Erg 的引用比 Rust 的更嚴格。 引用是語言中的一等對象,但不能顯式創建,它們只能指定為通過 `ref`/`ref!` 傳遞的參數。
+這意味著您不能將引用填充到數組中或創建將引用作為屬性的類。
+
+但是,這樣的限制是語言中的自然規范,一開始就沒有引用,而且它們并沒有那么不方便。
+
+## 循環引用
+
+Erg 旨在防止無意的內存泄漏,如果內存檢查器檢測到循環引用,則會發出錯誤。 在大多數情況下,這個錯誤可以通過弱引用 `Weak` 來解決。 但是,由于無法生成循環圖等具有循環結構的對象,因此我們計劃實現一個 API,可以將循環引用作為不安全操作生成。
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/19_visibility.md b/doc/zh_TW/syntax/19_visibility.md
new file mode 100644
index 00000000..e6d5090b
--- /dev/null
+++ b/doc/zh_TW/syntax/19_visibility.md
@@ -0,0 +1,193 @@
+# 可見性
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/19_visibility.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg 變量具有 __visibility__ 的概念。
+到目前為止,我們看到的所有變量都稱為 __private variables__。 這是一個外部不可見的變量。
+例如,`foo` 模塊中定義的私有變量不能被另一個模塊引用。
+
+```python
+# foo.er
+x = "this is an invisible variable"
+```
+
+```python
+#bar.er
+foo = import "foo"
+foo.x # AttributeError: 模塊 'foo' 沒有屬性 'x' ('x' 是私有的)
+```
+
+另一方面,也有__public variables__,可以從外部引用。
+公共變量用`.`定義。
+
+```python
+# foo.er
+.x = "this is a visible variable"
+```
+
+```python
+#bar.er
+foo = import "foo"
+assert foo.x == "this is a visible variable"
+```
+
+您不需要向私有變量添加任何內容,但您也可以添加 `::` 或 `self::`(用于類型等的`Self::`)以表明它們是私有的。 增加。 如果它是一個模塊,它也可以是 `module::`
+
+```python
+::x = "this is an invisible variable"
+assert ::x == x
+assert self ::x == ::x
+assert module::x == ::x
+```
+
+In the context of purely sequential execution, private variables are almost synonymous with local variables. It can be referenced from the inner scope.
+
+```python
+::x = "this is a private variable"
+y =
+ x + 1 # 完全是 module::x
+```
+
+通過使用`::`,可以區分作用域內同名的變量。
+在左側指定要引用的變量的范圍。 為頂層指定 `module`。
+如果未指定,則照常引用最里面的變量。
+
+```python
+::x = 0
+assert x == 0
+y =
+ ::x = 1
+ assert x == 1
+ z =
+ ::x = 2
+ assert ::x == 2
+ assert z::x == 2
+ assert y::x == 1
+ assert module::x == 0
+```
+
+在匿名子程序作用域中,`self` 指定了它自己的作用域
+
+```python
+x = 0
+f = x ->
+ log module::x, self::x
+f1# 0 1
+```
+
+`::` 還負責訪問私有實例屬性。
+
+```python
+x = 0
+C = Class {x = Int}
+C.
+ # 頂級 x 被引用(警告使用 module::x)
+ f1 self = x
+ # 實例屬性 x 被引用
+ f2 self = self::x
+```
+
+## 外部模塊中的可見性
+
+在一個模塊中定義的類實際上可以定義來自外部模塊的方法。
+
+```python
+# foo.er
+.Foo = Class()
+```
+
+```python
+#bar.er
+{Foo; ...} = import "foo"
+
+Foo::
+ private self = pass
+Foo.
+ public self = self::private()
+
+.f() =
+ foo = Foo.new()
+ foo.public()
+ foo::private() # 屬性錯誤
+```
+
+但是,這兩種方法都只在該模塊中可用。
+外部定義的私有方法對 Foo 類的方法僅在定義模塊內可見。
+公共方法暴露在類之外,但不在模塊之外。
+
+```python
+# baz.er
+{Foo; ...} = import "foo"
+
+foo = Foo.new()
+foo.public() # 屬性錯誤:“Foo”沒有屬性“public”(“public”在模塊“bar”中定義)
+```
+
+此外,方法不能在要重新導出的類型中定義。
+這是為了避免混淆方法是否找到,具體取決于導入方法的模塊。
+
+```python
+#bar.er
+{.Foo; ...} = import "foo"
+
+.Foo::
+ private self = pass # 錯誤
+Foo.
+ public self = self::private() # 錯誤
+```
+
+如果你想做這樣的事情,定義一個 [patch](./type/07_patch.md)。
+
+```python
+#bar.er
+{Foo; ...} = import "foo"
+
+FooImpl = Patch Foo
+FooImpl :=:
+ private self = pass
+Foo Impl.
+ public self = self::private()
+```
+
+```python
+# baz.er
+{Foo; ...} = import "foo"
+{FooImpl; ...} = import "bar"
+
+foo = Foo.new()
+foo.public()
+```
+
+## 受限公共變量
+
+可變可見性不限于完全公共/私有。
+您也可以有限制地發布。
+
+```python
+# foo.er
+.record = {
+ .a = {
+ .(.record)x = 0
+ .(module)y = 0
+ .z = 0
+ }
+ _ = .a.x # OK
+ _ = .a.y # OK
+ _ = .a.z # OK
+}
+
+_ = .record.a.x # 可見性錯誤
+_ = .record.a.y # OK
+_ = .record.a.z # OK
+```
+
+```python
+foo = import "foo"
+_ = foo.record.a.x # 可見性錯誤
+_ = foo.record.a.y # 可見性錯誤
+_ = foo.record.a.z # OK
+```
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/20_naming_rule.md b/doc/zh_TW/syntax/20_naming_rule.md
new file mode 100644
index 00000000..640c1262
--- /dev/null
+++ b/doc/zh_TW/syntax/20_naming_rule.md
@@ -0,0 +1,52 @@
+# 命名約定
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/20_naming_rule.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+如果要將變量用作常量表達式,請確保它以大寫字母開頭。 兩個或多個字母可能是小寫的。
+
+```python
+i: Option Type = Int
+match i:
+ t: Type -> log "type"
+ None -> log "None"
+```
+
+具有副作用的對象總是以 `!` 結尾。 程序和程序方法,以及可變類型。
+然而,`Proc` 類型本身是不可變的。
+
+```python
+# Callable == Func or Proc
+c: Callable = print!
+match c:
+ p! -> log "proc" # `: Proc` 可以省略,因為它是不言自明的
+ f -> log "func"
+```
+
+如果您想向外界公開一個屬性,請在開頭使用 `.` 定義它。 如果你不把`.`放在開頭,它將是私有的。 為避免混淆,它們不能在同一范圍內共存。
+
+```python
+o = {x = 1; .x = 2} # 語法錯誤:同名的私有變量和公共變量不能共存
+```
+
+## 文字標識符
+
+可以通過將字符串括在單引號 ('') 中來規避上述規則。 也就是說,程序對象也可以在沒有 `!` 的情況下分配。 但是,在這種情況下,即使該值是常量表達式,也不會被視為常量。
+像這樣用單引號括起來的字符串稱為文字標識符。
+這在調用Python等其他語言的API(FFI)時使用。
+
+```python
+bar! = pyimport("foo").'bar'
+```
+
+在 Erg 中也有效的標識符不需要用 '' 括起來。
+
+此外,文字標識符可以包含符號和空格,因此通常不能用作標識符的字符串可以用作標識符。
+
+```python
+'?/?t' y
+'test 1: pass x to y'()
+```
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/21_lambda.md b/doc/zh_TW/syntax/21_lambda.md
new file mode 100644
index 00000000..6b240482
--- /dev/null
+++ b/doc/zh_TW/syntax/21_lambda.md
@@ -0,0 +1,97 @@
+# 匿名函數
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/21_lambda.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+匿名函數是一種無需命名即可動態創建函數對象的語法。
+
+```python
+# `->` 是匿名函數操作符
+# 同 `f x, y = x + y`
+f = (x, y) -> x + y
+# same as `g(x, y: Int): Int = x + y`
+g = (x, y: Int): Int -> x + y
+```
+
+如果只有一個參數,您可以省略 `()`。
+
+```python
+assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4]
+assert ((i, j) -> [i, j])(1, 2) == [1, 2]
+```
+
+在下面的情況下,它是 `0..9, (i -> ...)` 而不是 `(0..9, i) -> ...`
+`->` 在左側只接受一個參數。 多個參數作為單個元組接收
+
+```python
+for 0..9, i: Int ->
+ ...
+```
+
+在匿名函數中,由于空格,解析存在差異
+
+```python
+# 在這種情況下,解釋為 `T(() -> Int)`
+i: T() -> Int
+# 在這種情況下,它被解釋為 (U()) -> Int
+k: U() -> Int
+```
+
+匿名函數可以不帶參數使用。
+
+```python
+# `=>` 是一個匿名過程操作符
+p! = () => print! # `p!` 被調用
+# `() ->`, `() =>` 有語法糖 `do`, `do!`
+# p! = do! print! "`p!` 被調用
+p!() # `p!` 被調用
+```
+
+無參數函數可用于延遲初始化
+
+```python
+time = import "time"
+date = import "datetime"
+now = if! True:
+ do!:
+ time. sleep! 1000
+ date.now!()
+ do date.new("1970", "1", "1", "00", "00")
+```
+
+您還可以鍵入和模式匹配。 正因為如此,`match` 函數大多是借助匿名函數的力量來實現的。
+作為 `match` 函數的參數給出的匿名函數從頂部開始按順序嘗試。 因此,您應該在頂部描述特殊情況,在底部描述更一般的情況。 如果你弄錯了順序,編譯器會發出警告(如果可能的話)
+
+```python
+n = (Complex or Ratio or Int).sample!()
+i = matchn:
+ PI -> PI # 如果等于常數 PI
+ For (i: 1..10) -> i # 整數從 1 到 10
+ (i: Int) -> i # Int
+ (c: Complex) -> c.real() # 對于復雜。 Int < Complex,但可以回退
+ _ -> panic "cannot convert to Int" # 如果以上都不適用。 match 必須涵蓋所有模式
+```
+
+錯誤處理通常也使用 `?` 或 `match` 完成。
+
+```python
+res: ParseResult Int
+matchres:
+ i: Int -> i
+ err: Error -> panic err.msg
+
+res2: Result Int, Error
+match res2:
+ ok: Not Error -> log Type of ok
+ err: Error -> panic err.msg
+```
+
+## 匿名多相關系數
+
+```python
+# 與此相同 id|T|x:T = x
+id = |T| x: T -> x
+```
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/22_subroutine.md b/doc/zh_TW/syntax/22_subroutine.md
new file mode 100644
index 00000000..29f7b790
--- /dev/null
+++ b/doc/zh_TW/syntax/22_subroutine.md
@@ -0,0 +1,64 @@
+# 子程序簽名
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/22_subroutine.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 函數
+
+```python
+some_func(x: T, y: U) -> V
+some_func: (T, U) -> V
+```
+
+## 過程
+
+```python
+some_proc!(x: T, y: U) => V
+some_proc!: (T, U) => V
+```
+
+## 函數方法
+
+方法類型不能用`Self`在外部指定
+
+```python
+.some_method(self, x: T, y: U) => ()
+# Self.(T, U) => () 擁有 self 的所有權
+.some_method: Ref(Self). (T, U) => ()
+```
+
+## 過程方法(依賴)
+
+在下文中,假設類型 `T!` 采用類型參數 `N: Nat`。 要在外部指定它,請使用類型變量
+
+```python
+T!: Nat -> Type
+# ~> 表示應用前后類型參數的狀態(此時self必須是變量引用)
+T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => ()
+```
+
+注意,`.some_method` 的類型是 `Ref!(T(N ~> N+X))。 ({X}) => () | N,X:Nat`。
+對于沒有 `ref!` 的方法,即在應用后被剝奪所有權,不能使用類型參數轉換(`~>`)。
+
+如果取得所有權,則如下所示。
+
+```python
+# 如果不使用N,可以用_省略。
+# .some_method!: |N, X: Nat| T!(N).({X}) => T!(N+X)
+.some_method!|N, X: Nat|(self(N), X: Nat) => T!(N+X)
+```
+
+## 運算符
+
+可以通過用 ` 括起來將其定義為普通函數。
+
+中性字母運算符,例如 `and` 和 `or` 可以通過用 ` 括起來定義為中性運算符。
+
+```python
+and(x, y, z) = x and y and z
+`_+_`(x: Foo, y: Foo) = x.a + y.a
+`-_`(x: Foo) = Foo.new(-x.a)
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/23_closure.md b/doc/zh_TW/syntax/23_closure.md
new file mode 100644
index 00000000..f8586ffa
--- /dev/null
+++ b/doc/zh_TW/syntax/23_closure.md
@@ -0,0 +1,98 @@
+# 關閉
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/23_closure.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg 子例程有一個稱為“閉包”的功能,可以捕獲外部變量。
+
+```python
+outer = 1
+f x = outer + x
+assert f(1) == 2
+```
+
+與不可變對象一樣,可變對象也可以被捕獲。
+
+```python
+sum = !0
+for! 1..10, i =>
+ sum.add!i
+assert sum == 45
+
+p!x=
+ sum.add!x
+p!(1)
+assert sum == 46
+```
+
+但是請注意,函數不能捕獲可變對象。
+如果可以在函數中引用可變對象,則可以編寫如下代碼。
+
+```python
+# !!! 這段代碼實際上給出了一個錯誤!!!
+i = !0
+f x = i + x
+assert f 1 == 1
+i.add! 1
+assert f 1 == 2
+```
+
+該函數應該為相同的參數返回相同的值,但假設被打破了。
+請注意,`i` 僅在調用時進行評估。
+
+如果您想在定義函數時獲取可變對象的內容,請調用`.clone`
+
+```python
+i = !0
+immut_i = i.clone().freeze()
+fx = immut_i + x
+assert f 1 == 1
+i.add! 1
+assert f 1 == 1
+```
+
+## avoid mutable state, functional programming
+
+```python
+# Erg
+sum = !0
+for! 1..10, i =>
+ sum.add!i
+assert sum == 45
+```
+
+上面的等效程序可以用 Python 編寫如下:
+
+```python
+# Python
+sum = 0
+for i in range(1, 10):
+ sum += i
+assert sum == 45
+```
+
+但是,Erg 建議使用更簡單的表示法。
+與其使用子例程和可變對象來傳遞狀態,不如使用一種使用函數來定位狀態的風格。這稱為函數式編程
+
+```python
+# 功能風格
+sum = (1..10).sum()
+assert sum == 45
+```
+
+上面的代碼給出了與之前完全相同的結果,但是您可以看到這個代碼要簡單得多。
+
+`fold` 函數可以用來做比 sum 更多的事情。
+`fold` 是一個迭代器方法,它為每次迭代執行參數 `f`。
+累加結果的計數器的初始值在 `init` 中指定,并在 `acc` 中累加。
+
+```python
+# 從0開始,結果會
+sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i)
+assert sum == 45
+```
+
+Erg 被設計為對使用不可變對象進行編程的自然簡潔描述。
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/24_module.md b/doc/zh_TW/syntax/24_module.md
new file mode 100644
index 00000000..8d18f7bc
--- /dev/null
+++ b/doc/zh_TW/syntax/24_module.md
@@ -0,0 +1,44 @@
+# module
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/24_module.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg allows you to think of the file itself as a single record. This is called a module.
+
+```python: foo.er
+# foo.er
+.i = 1
+```
+
+```python
+# 定義 foo 模塊與定義這條記錄幾乎相同
+foo = {.i = 1}
+```
+
+```python: bar.er
+#bar.er
+foo = import "foo"
+print! foo #
+assert foo.i == 1
+```
+
+由于模塊類型也是記錄類型,因此可以進行解構賦值
+
+```python
+{sin; cos; ...} = import "math"
+```
+
+## 模塊可見性
+
+```console
+└─┬ ./src
+ ├─ lib.er
+ ├─ foo.er
+ ├─bar.er
+ └─┬ bar
+ ├─ baz.er
+ └─ qux.er
+```
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/25_object_system.md b/doc/zh_TW/syntax/25_object_system.md
new file mode 100644
index 00000000..bca97d5b
--- /dev/null
+++ b/doc/zh_TW/syntax/25_object_system.md
@@ -0,0 +1,84 @@
+# 目的
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/25_object_system.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+可以分配給變量的所有數據。 `Object` 類的屬性如下。
+
+* `.__repr__`:返回對象的(非豐富)字符串表示
+* `.__sizeof__`:返回對象的大小(包括堆分配)
+* `.__dir__`: 返回對象屬性列表
+* `.__hash__`:返回對象的哈希值
+* `.__getattribute__`: 獲取并返回對象的屬性
+* `.clone`:創建并返回一個對象的克隆(在內存中有一個獨立的實體)
+* `.copy`:返回對象的副本(指向內存中的同一事物)
+
+## 記錄
+
+由記錄文字(`{attr = value; ...}`)生成的對象。
+這個對象有基本的方法,比如`.clone`和`.__sizeof__`。
+
+```python
+obj = {.x = 1}
+assert obj.x == 1
+
+obj2 = {...x; .y = 2}
+assert obj2.x == 1 and obj2.y == 2
+```
+
+## 屬性
+
+與對象關聯的對象。 特別是,將 self (`self`) 作為其隱式第一個參數的子例程屬性稱為方法。
+
+```python
+# 請注意,private_attr 中沒有`.`
+record = {.public_attr = j; private_attr = 2; .method = self -> self.i + 1}
+record. public_attr == 2
+record.private_attr # AttributeError: private_attr 是私有的
+assert record.method() == 3
+```
+
+## 元素
+
+屬于特定類型的對象(例如,“1”是“Int”類型的元素)。所有對象至少是`{=}`類型的元素。
+類的元素有時稱為實例。
+
+## 子程序
+
+表示作為函數或過程(包括方法)實例的對象。代表子程序的類是“子程序”。
+實現 `.__call__` 的對象通常稱為 `Callable`。
+
+## 可調用
+
+一個實現`.__call__`的對象。它也是 `Subroutine` 的超類。
+
+## 類型
+
+定義需求屬性并使對象通用化的對象。
+主要有兩種類型:多態類型和單態類型。典型的單態類型有`Int`、`Str`等,多態類型有`Option Int`、`[Int; 3]`等
+此外,定義改變對象狀態的方法的類型稱為 Mutable 類型,需要在變量屬性中添加 `!`(例如動態數組:`[T; !_]`)。
+
+## 班級
+
+具有 `.__new__`、`.__init__` 方法等的類型。實現基于類的面向對象。
+
+## 功能
+
+對外部變量(不包括靜態變量)有讀權限但對外部變量沒有讀/寫權限的子程序。換句話說,它沒有外部副作用。
+Erg 函數的定義與 Python 的不同,因為它們不允許副作用。
+
+## 程序
+
+它對外部變量具有讀取和“自我”權限,對靜態變量具有讀/寫權限,并允許使用所有子例程。它可能有外部副作用。
+
+## 方法
+
+隱式將“self”作為第一個參數的子例程。它與簡單的函數/過程是不同的類型。
+
+## 實體
+
+不是子例程和類型的對象。
+單態實體(`1`、`"a"` 等)也稱為值對象,多態實體(`[1, 2, 3], {"a": 1}`)也稱為容器對象。
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/26_pattern_matching.md b/doc/zh_TW/syntax/26_pattern_matching.md
new file mode 100644
index 00000000..411650fd
--- /dev/null
+++ b/doc/zh_TW/syntax/26_pattern_matching.md
@@ -0,0 +1,195 @@
+# 模式匹配,可反駁
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/26_pattern_matching.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+## Erg 中可用的模式
+
+### 變量模式
+
+```python
+# 基本任務
+i = 1
+# 有類型
+i: Int = 1
+# 匿名類型
+i: {1, 2, 3} = 2
+
+# 功能
+fn x = x + 1
+# 等于
+fn x: Add(Int) = x + 1
+# (匿名)函數
+fn = x -> x + 1
+fn: Int -> Int = x -> x + 1
+
+# 高階類型
+a: [Int; 4] = [0, 1, 2, 3]
+# or
+a: Array Int, 4 = [0, 1, 2, 3]
+```
+
+### 文字字面量
+
+```python
+# 如果在編譯時無法確定 `i` 為 1,則引發 TypeError。
+# 省略 `_: {1} = i`
+1 = i
+
+# 簡單的模式匹配
+match x:
+ 1 -> "1"
+ 2 -> "2"
+ _ -> "other"
+
+# 斐波那契函數
+fib0 = 0
+fib1 = 1
+fibn: Nat = fibn-1 + fibn-2
+```
+
+### 常量模式
+
+```python
+cond=False
+match! cond:
+ True => print! "cond is True"
+ _ => print! "cond is False"
+
+PI = 3.141592653589793
+E = 2.718281828459045
+num = PI
+name = match num:
+ PI -> "pi"
+ E -> "e"
+ _ -> "unnamed"
+```
+
+### 篩子圖案
+
+```python
+# 這兩個是一樣的
+Array(T, N: {N | N >= 3})
+Array(T, N | N >= 3)
+
+f M, N | M >= 0, N >= 1 = ...
+f(1, 0) # 類型錯誤:N(第二個參數)必須為 1 或更多
+```
+
+### 丟棄(通配符)模式
+
+```python
+_ = 1
+_: Int = 1
+zero_ = 0
+right(_, r) = r
+```
+
+### 可變長度模式
+
+它與稍后描述的元組/數組/記錄模式結合使用。
+
+```python
+[i,...j] = [1, 2, 3, 4]
+assert j == [2, 3, 4]
+first|T|(fst: T, ...rest: T) = fst
+assert first(1, 2, 3) == 1
+```
+
+### 元組模式
+
+```python
+(i, j) = (1, 2)
+((k, l), _) = ((1, 2), (3, 4))
+# 如果不嵌套,() 可以省略(1, 2 被視為(1, 2))
+m, n = 1, 2
+
+f(x, y) = ...
+```
+
+### 數組模式
+
+```python
+[i, j] = [1, 2]
+[[k, l], _] = [[1, 2], [3, 4]]
+
+length[] = 0
+length[_, ...rest] = 1 + lengthrest
+```
+
+#### record 模式
+
+```python
+record = {i = 1; j = 2; k = 3}
+{j; ...} = record # i, k 將被釋放
+
+{sin; cos; tan; ...} = import "math"
+{*} = import "math" # import all
+
+person = {name = "John Smith"; age = 20}
+age = match person:
+ {name = "Alice"; _} -> 7
+ {_; age} -> age
+
+f {x: Int; y: Int} = ...
+```
+
+### 數據類模式
+
+```python
+Point = Inherit {x = Int; y = Int}
+p = Point::{x = 1; y = 2}
+Point::{x; y} = p
+
+Nil T = Class Impl := Phantom T
+Cons T = Inherit {head = T; rest = List T}
+List T = Enum Nil(T), Cons(T)
+List T.
+ first self =
+ match self:
+ Cons::{head; ...} -> x
+ _ -> ...
+ second self =
+ match self:
+ Cons::{rest=Cons::{head; ...}; ...} -> head
+ _ -> ...
+```
+
+### 枚舉模式
+
+* 其實只是枚舉類型
+
+```python
+match x:
+ i: {1, 2} -> "one or two: {i}"
+ _ -> "other"
+```
+
+### Range 模式
+
+* 實際上,它只是一個區間類型。
+
+```python
+# 0 < i < 1
+i: 0<..<1 = 0.5
+# 1 < j <= 2
+_: {[I, J] | I, J: 1<..2} = [1, 2]
+# 1 <= i <= 5
+match i
+ i: 1..5 -> ...
+```
+
+### 不是模式的東西,不能被模式化的東西
+
+模式是可以唯一指定的東西。 在這方面,模式匹配不同于普通的條件分支。
+
+條件規格不是唯一的。 例如,要檢查數字 `n` 是否為偶數,正統是 `n % 2 == 0`,但也可以寫成 `(n / 2).round() == n / 2`。
+非唯一形式無論是正常工作還是等效于另一個條件都不是微不足道的。
+
+#### Set
+
+沒有固定的模式。 因為集合沒有辦法唯一地檢索元素。
+您可以通過迭代器檢索它們,但不能保證順序。
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/27_comprehension.md b/doc/zh_TW/syntax/27_comprehension.md
new file mode 100644
index 00000000..9ba5b6fc
--- /dev/null
+++ b/doc/zh_TW/syntax/27_comprehension.md
@@ -0,0 +1,67 @@
+# Comprehension
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/27_comprehension.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Array 和 `[expr | (name <- iterable)+ (predicate)*]`,
+set 和 `{expr | (name <- iterable)+ (predicate)*}`,
+你可以創建一個字典 `{key: value | (name <- iterable)+ (predicate)*}`.
+
+由`|`分隔的子句的第一部分稱為布局子句(位置子句),第二部分稱為綁定子句(綁定子句),第三部分稱為保護子句(條件子句)。
+保護子句可以省略,但綁定子句不能省略,保護子句不能在綁定子句之前。
+
+理解示例
+
+```python
+# 布局子句是 i
+# 綁定子句是 i <- [0, 1, 2]
+assert [i | i <- [0, 1, 2]] == [0, 1, 2]
+
+# 布局子句是 i / 2
+# 綁定子句是 i <- 0..2
+assert [i/2 | i <- 0..2] == [0.0, 0.5, 1.0]
+
+# 布局子句是 (i, j)
+# 綁定子句 i <- 0..2, j <- 0..2
+# 保護子句是 (i + j) % 2 == 0
+assert [(i, j) | i <- 0..2; j <- 0..2; (i + j) % 2 == 0] == [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)]
+
+assert {i % 2 | i <- 0..9} == {0, 1}
+assert {k: v | k <- ["a", "b"]; v <- [1, 2]} == {"a": 1, "b": 2}
+```
+
+Erg推導式受到 Haskell 的啟發,但有一些不同。
+對于 Haskell 列表推導,變量的順序會對結果產生影響,但在 Erg 中這并不重要。
+
+``` haskell
+-- Haskell
+[(i, j) | i <- [1..3], j <- [3..5]] == [(1,3),(1,4),(1,5),(2 ,3),(2,4),(2,5),(3,3),(3,4),(3,5)]
+[(i, j) | j <- [3..5], i <- [1..3]] == [(1,3),(2,3),(3,3),(1 ,4),(2,4),(3,4),(1,5),(2,5),(3,5)]
+```
+
+```python
+# Erg
+assert [(i, j) | i <- 1..<3; j <- 3..<5] == [(i, j) | j <- 3..<5; i <- 1.. <3]
+```
+
+該規范與 Python 的規范相同。
+
+```python
+# Python
+assert [(i, j) for i in range(1, 3) for j in range(3, 5)] == [(i, j) for j in range(3, 5) for i in range(1, 3)]
+```
+
+## 篩子類型
+
+與推導類似的是篩類型。 篩子類型是以`{Name: Type | Predicate}`創建的(枚舉類型)
+sieve類型的情況下,只能指定一個Name,不能指定布局(但是如果是tuple類型可以處理多個值),Predicate可以在編譯時計算,即 ,只能指定一個常量表達式。
+
+```python
+Nat = {I: Int | I >= 0}
+# 如果謂詞表達式只有and,可以替換為:
+# Nat2D = {(I, J): (Int, Int) | I >= 0; J >= 0}
+Nat2D = {(I, J): (Int, Int) | I >= 0 and J >= 0}
+```
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/28_spread_syntax.md b/doc/zh_TW/syntax/28_spread_syntax.md
new file mode 100644
index 00000000..60630b96
--- /dev/null
+++ b/doc/zh_TW/syntax/28_spread_syntax.md
@@ -0,0 +1,44 @@
+# 傳播賦值
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/28_spread_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+在分解賦值中,將 `...` 放在變量前面會將所有剩余元素展開到該變量中。 這稱為擴展賦值。
+
+```python
+[x,...y] = [1, 2, 3]
+assert x == 1
+assert y == [2, 3]
+x, ...y = (1, 2, 3)
+assert x == 1
+assert y == (2, 3)
+```
+
+## 提取賦值
+
+如果在 `...` 之后沒有寫入任何內容,則忽略并分配剩余的元素。 這種類型的擴展賦值具體稱為抽取賦值。
+提取分配是一種方便的語法,用于本地化模塊或記錄中的特定屬性。
+
+```python
+{sin; cos; tan; ..} = import "math"
+```
+
+After that, you can use `sin, cos, tan` locally.
+
+You can do the same with records.
+
+```python
+record = {x = 1; y = 2}
+{x; y; ...} = record
+```
+
+If you want to expand all, use `{*} = record`. It is `open` in OCaml.
+
+```python
+record = {x = 1; y = 2}
+{*} = records
+assert x == 1 and y == 2
+```
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/29_decorator.md b/doc/zh_TW/syntax/29_decorator.md
new file mode 100644
index 00000000..97e94d02
--- /dev/null
+++ b/doc/zh_TW/syntax/29_decorator.md
@@ -0,0 +1,122 @@
+# 裝飾器(修飾符)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/29_decorator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+裝飾器用于向類型或函數添加或演示特定狀態或行為。
+裝飾器的語法如下。
+
+```python
+@deco
+X=...
+```
+
+你可以有多個裝飾器,只要它們不沖突。
+
+裝飾器不是一個特殊的對象,它只是一個單參數函數。 裝飾器等價于下面的偽代碼。
+
+```python
+X=...
+X = deco(X)
+```
+
+Erg 不允許重新分配變量,因此上面的代碼不起作用。
+對于簡單的變量,它與`X = deco(...)` 相同,但對于即時塊和子例程,你不能這樣做,所以你需要一個裝飾器。
+
+```python
+@deco
+f x =
+ y = ...
+ x + y
+
+# 還可以防止代碼變成水平的
+@LongNameDeco1
+@LongNameDeco2
+C = Class...
+```
+
+下面是一些常用的內置裝飾器。
+
+## 可繼承
+
+指示定義類型是可繼承的類。 如果為參數 `scope` 指定 `"public"`,甚至可以繼承外部模塊的類。 默認情況下它是`"private"`,不能被外部繼承。
+
+## 最后
+
+使該方法不可覆蓋。 將它添加到類中使其成為不可繼承的類,但由于它是默認值,因此沒有意義。
+
+## 覆蓋
+
+覆蓋屬性時使用。 默認情況下,如果您嘗試定義與基類相同的屬性,Erg 將拋出錯誤。
+
+## 實現
+
+表示參數 trait 已實現。
+
+```python
+Add = Trait {
+ .`_+_` = Self.(Self) -> Self
+}
+Sub = Trait {
+ .`_-_` = Self.(Self) -> Self
+}
+
+C = Class({i = Int}, Impl := Add and Sub)
+C.
+ @Impl Add
+ `_+_` self, other = C.new {i = self::i + other::i}
+ @Impl Sub
+ `_-_` self, other = C.new {i = self::i - other::}
+```
+
+## 附
+
+指定默認情況下隨 trait 附帶的附件補丁。
+這允許您重現與 Rust 特征相同的行為。
+
+```python
+# foo.er
+Add R = Trait {
+ .AddO = Type
+ .`_+_` = Self.(R) -> Self.AddO
+}
+@Attach AddForInt, AddForOdd
+ClosedAdd = Subsume Add(Self)
+
+AddForInt = Patch(Int, Impl := ClosedAdd)
+AddForInt.AddO = Int
+AddForOdd = Patch(Odd, Impl := ClosedAdd)
+AddForOdd.AddO = Even
+```
+
+當從其他模塊導入特征時,這將自動應用附件補丁。
+
+```Python
+# 本來應該同時導入IntIsBinAdd和OddIsBinAdd,但是如果是附件補丁可以省略
+{BinAdd; ...} = import "foo"
+
+assert Int. AddO == Int
+assert Odd.AddO == Even
+```
+
+在內部,它只是使用 trait 的 .attach 方法附加的。 可以使用 trait 的 `.detach` 方法消除沖突。
+
+```python
+@Attach X
+T = Trait...
+assert X in T. attaches
+U = T.detach(X).attach(Y)
+assert X not in U. attaches
+assert Y in U. attaches
+```
+
+## 已棄用
+
+指示變量規范已過時且不推薦使用。
+
+## 測試
+
+表示這是一個測試子例程。 測試子程序使用 `erg test` 命令運行。
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/30_error_handling.md b/doc/zh_TW/syntax/30_error_handling.md
new file mode 100644
index 00000000..c58e6dd7
--- /dev/null
+++ b/doc/zh_TW/syntax/30_error_handling.md
@@ -0,0 +1,110 @@
+# 錯誤處理系統
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/30_error_handling.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+主要使用Result類型。
+在 Erg 中,如果您丟棄 Error 類型的對象(頂層不支持),則會發生錯誤。
+
+## 異常,與 Python 互操作
+
+Erg 沒有異常機制(Exception)。 導入 Python 函數時
+
+* 將返回值設置為 `T 或 Error` 類型
+* `T or Panic` 類型(可能導致運行時錯誤)
+
+有兩個選項,`pyimport` 默認為后者。 如果要作為前者導入,請使用
+在 `pyimport` `exception_type` 中指定 `Error` (`exception_type: {Error, Panic}`)。
+
+## 異常和結果類型
+
+`Result` 類型表示可能是錯誤的值。 `Result` 的錯誤處理在幾個方面優于異常機制。
+首先,從類型定義中可以看出子程序可能會報錯,實際使用時也很明顯。
+
+```python
+# Python
+try:
+ x = foo().bar()
+ y = baz()
+ qux()
+except e:
+ print(e)
+```
+
+在上面的示例中,僅憑此代碼無法判斷哪個函數引發了異常。 即使回到函數定義,也很難判斷函數是否拋出異常。
+
+```python
+# Erg
+try!:
+ do!:
+ x = foo!()?.bar()
+ y = baz!()
+ qux!()?
+ e =>
+ print! e
+```
+
+另一方面,在這個例子中,我們可以看到 `foo!` 和 `qux!` 會引發錯誤。
+確切地說,`y` 也可能是 `Result` 類型,但您最終必須處理它才能使用里面的值。
+
+使用 `Result` 類型的好處不止于此。 `Result` 類型也是線程安全的。 這意味著錯誤信息可以(輕松)在并行執行之間傳遞。
+
+## 語境
+
+由于 `Error`/`Result` 類型本身不會產生副作用,不像異常,它不能有發送位置(Context)等信息,但是如果使用 `.context` 方法,可以將信息放在 `錯誤`對象。 可以添加。 `.context` 方法是一種使用 `Error` 對象本身并創建新的 `Error` 對象的方法。 它們是可鏈接的,并且可以包含多個上下文。
+```python
+f() =
+ todo() \
+ .context "to be implemented in ver 1.2" \
+ .context "and more hints ..."
+
+f()
+# Error: not implemented yet
+# hint: to be implemented in ver 1.2
+# hint: and more hints ...
+```
+
+請注意,諸如 `.msg` 和 `.kind` 之類的 `Error` 屬性不是次要的,因此它們不是上下文,并且不能像最初創建時那樣被覆蓋。
+
+## 堆棧跟蹤
+
+`Result` 類型由于其方便性在其他語言中經常使用,但與異常機制相比,它的缺點是難以理解錯誤的來源。
+因此,在 Erg 中,`Error` 對象具有名為 `.stack` 的屬性,并再現了類似偽異常機制的堆棧跟蹤。
+`.stack` 是調用者對象的數組。 每次 Error 對象被`return`(包括通過`?`)時,它都會將它的調用子例程推送到`.stack`。
+如果它是 `?`ed 或 `.unwrap`ed 在一個不可能 `return` 的上下文中,它會因為回溯而恐慌。
+
+```python
+f x =
+ ...
+ y = foo.try_some(x)?
+ ...
+
+g x =
+ y = f(x)?
+ ...
+
+i = g(1)?
+# Traceback (most recent call first):
+# ...
+# Foo.try_some, line 10, file "foo.er"
+# 10 | y = foo.try_some(x)?
+# module::f, line 23, file "foo.er"
+# 23 | y = f(x)?
+# module::g, line 40, file "foo.er"
+# 40 | i = g(1)?
+# Error: ...
+```
+
+## 恐慌
+
+Erg 還有一種處理不可恢復錯誤的機制,稱為 __panicing__。
+不可恢復的錯誤是由外部因素引起的錯誤,例如軟件/硬件故障、嚴重到無法繼續執行代碼的錯誤或程序員未預料到的錯誤。 等如果發生這種情況,程序將立即終止,因為程序員的努力無法恢復正常運行。 這被稱為“恐慌”。
+
+恐慌是通過 `panic` 功能完成的。
+
+```python
+panic "something went wrong!"
+```
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/31_pipeline.md b/doc/zh_TW/syntax/31_pipeline.md
new file mode 100644
index 00000000..4d1f736e
--- /dev/null
+++ b/doc/zh_TW/syntax/31_pipeline.md
@@ -0,0 +1,34 @@
+# 管道運算符
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/31_pipeline.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+管道運算符的使用方式如下:
+
+```python
+assert f(g(x)) == (x |> g |> f)
+assert f(g(x, y)) == ((x, y) |> g |> f)
+```
+
+換句話說,`Callable(object)` 的順序可以更改為 `object |> Callable`。
+管道運算符也可用于方法。 對于方法,`object.method(args)` 更改為 `object |>.method(args)`。
+它看起來只是更多的`|>`,但由于粘合強度較低,您可以減少`()`的數量。
+
+```python
+rand = -1.0..1.0 |>.sample!()
+log rand # 0.2597...
+
+1+1*2 |>.times do log("a", end := "") # aaa
+
+evens = 1..100 |>.iter |>.filter i -> i % 2 == 0 |>.collect Array
+# 在沒有管道操作符的情況下實現,
+_evens = (1..100).iter().filter(i -> i % 2 == 0).collect(Array)
+# or
+__evens = 1..100 \
+ .iter() \
+ .filter i -> i % 2 == 0 \
+ .collect Array
+```
+
+
+ 上一頁 | 下一頁
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/32_integration_with_Python.md b/doc/zh_TW/syntax/32_integration_with_Python.md
new file mode 100644
index 00000000..3649c674
--- /dev/null
+++ b/doc/zh_TW/syntax/32_integration_with_Python.md
@@ -0,0 +1,84 @@
+# 與 Python 集成
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/32_integration_with_Python.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 導出到 Python
+
+編譯 Erg 腳本時,會生成一個 .pyc 文件,可以簡單地將其作為 Python 模塊導入。
+但是,無法從 Python 訪問在 Erg 端設置為私有的變量。
+
+```python
+# foo.er
+.public = "this is a public variable"
+private = "this is a private variable"
+```
+
+```console
+erg --compile foo.er
+```
+
+```python
+import foo
+
+print(foo.public)
+print(foo.private) # 屬性錯誤:
+```
+
+## 從 Python 導入
+
+默認情況下,從 Python 導入的所有對象都是“Object”類型。 由于此時無法進行比較,因此有必要細化類型。
+
+## 標準庫中的類型規范
+
+Python 標準庫中的所有 API 都是由 Erg 開發團隊指定的類型。
+
+```python
+time = pyimport "time"
+time.sleep! 1
+```
+
+## 用戶腳本的類型規范
+
+創建一個類型為 Python `foo` 模塊的 `foo.d.er` 文件。
+Python 端的類型提示被忽略,因為它們不是 100% 保證的。
+
+```python
+# foo.py
+X = ...
+def bar(x):
+ ...
+def baz():
+ ...
+...
+```
+
+```python
+# foo.d.er
+foo = pyimport "foo"
+.X = declare foo.'X', Int
+.bar = declare foo.'bar', Int -> Int
+.baz! = declare foo.'baz', () => Int
+```
+
+```python
+foo = pyimport "foo"
+assert foo.bar(1) in Int
+```
+
+這通過在運行時執行類型檢查來確保類型安全。 ``declare`` 函數大致如下工作
+
+```python
+declare|S: Subroutine| sub!: S, T =
+ # 實際上,=> 可以強制轉換為沒有塊副作用的函數
+ x =>
+ assert x in T.Input
+ y = sub!(x)
+ assert y in T.Output
+ y
+```
+
+由于這是運行時開銷,因此計劃使用 Erg 的類型系統對 Python 腳本進行靜態類型分析
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/33_package_system.md b/doc/zh_TW/syntax/33_package_system.md
new file mode 100644
index 00000000..7946a2c8
--- /dev/null
+++ b/doc/zh_TW/syntax/33_package_system.md
@@ -0,0 +1,85 @@
+# 打包系統
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/33_package_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Erg包大致可以分為app包,即應用程序,以及lib包,即庫。
+應用包的入口點是`src/app.er`。 `app.er` 中定義的`main` 函數被執行。
+lib 包的入口點是`src/lib.er`。導入包相當于導入 `lib.er`。
+
+一個包有一個稱為模塊的子結構,在 Erg 中是一個 Erg 文件或由 Erg 文件組成的目錄。外部 Erg 文件/目錄是作為模塊對象的可操作對象。
+
+為了將目錄識別為模塊,有必要在目錄中放置一個“(目錄名稱).er”文件。
+這類似于 Python 的 `__init__.py`,但與 `__init__.py` 不同的是,它放在目錄之外。
+
+例如,考慮以下目錄結構。
+
+```console
+└─┬ ./src
+ ├─ app.er
+ ├─ foo.er
+ ├─ bar.er
+ └─┬ bar
+ ├─ baz.er
+ └─ qux.er
+```
+
+您可以在 `app.er` 中導入 `foo` 和 `bar` 模塊。由于 `bar.er` 文件,`bar` 目錄可以被識別為一個模塊。
+`foo` 模塊是由文件組成的模塊,`bar` 模塊是由目錄組成的模塊。 `bar` 模塊還包含 `baz` 和 `qux` 模塊。
+該模塊只是 `bar` 模塊的一個屬性,可以從 `app.er` 訪問,如下所示。
+
+```python
+# app.er
+foo = import "foo"
+bar = import "bar"
+baz = bar.baz
+# or `baz = import "bar/baz"`
+
+main args =
+ ...
+```
+
+請注意用于訪問子模塊的 `/` 分隔符。 這是因為可以有諸如 `bar.baz.er` 之類的文件名。
+不鼓勵使用此類文件名,因為 `.er` 前綴在 Erg 中是有意義的。
+例如,用于測試的模塊。 以 `.test.er` 結尾的文件是一個(白盒)測試模塊,它在運行測試時執行一個用 `@Test` 修飾的子例程。
+
+```console
+└─┬ ./src
+ ├─ app.er
+ ├─ foo.er
+ └─ foo.test.er
+./src
+
+```python
+# app.er
+foo = import "foo"
+
+main args =
+ ...
+```
+
+此外,以 .private.er 結尾的文件是私有模塊,只能由同一目錄中的模塊訪問。
+
+```console
+└─┬
+ ├─ foo.er
+ ├─ bar.er
+ └─┬ bar
+ ├─ baz.private.er
+ └─ qux.er
+```
+
+```python
+# foo.er
+bar = import "bar"
+bar.qux
+bar.baz # AttributeError: module 'baz' is private
+```
+
+```python
+# qux.er
+baz = import "baz"
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/34_generator.md b/doc/zh_TW/syntax/34_generator.md
new file mode 100644
index 00000000..e6c55854
--- /dev/null
+++ b/doc/zh_TW/syntax/34_generator.md
@@ -0,0 +1,37 @@
+# 生成器
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/34_generator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+生成器是在塊中使用 `yield!` 過程的特殊過程。
+
+```python
+g!() =
+ yield! 1
+ yield! 2
+ yield! 3
+```
+
+`yield!` 是在調用`self!.yield!` 的子程序塊中定義的過程。 和`return`一樣,它把傳遞給它的值作為返回值返回,但它具有保存block當前執行狀態,再次調用時從頭開始執行的特性。
+生成器既是過程又是迭代器; Python 生成器是一個創建迭代器的函數,而 Erg 直接迭代。 過程本身通常不是可變對象(沒有`!`),但生成器是可變對象,因為它自己的內容可以隨著每次執行而改變。
+
+```python
+# Generator!
+g!: Generator!((), Int)
+assert g!() == 1
+assert g!() == 2
+assert g!() == 3
+```
+
+Python 風格的生成器可以定義如下。
+
+```python
+make_g() = () =>
+ yield! 1
+ yield! 2
+ yield! 3
+make_g: () => Generator!
+```
+
+
+ 上一頁 | Next
+
diff --git a/doc/zh_TW/syntax/SUMMARY.md b/doc/zh_TW/syntax/SUMMARY.md
new file mode 100644
index 00000000..01f84f51
--- /dev/null
+++ b/doc/zh_TW/syntax/SUMMARY.md
@@ -0,0 +1,71 @@
+# 概括
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/SUMMARY.md&commit_hash=2ce482b1c8407332b3b74f4c3e5596f373f9a657)
+
+- [基礎](./00_basic.md)
+- [文字](./01_literal.md)
+- [名稱](02_name.md)
+- [聲明](./03_declaration.md)
+- [函數](./04_function.md)
+- [內置函數](./05_builtin_funcs.md)
+- [操作員](./06_operator.md)
+- [副作用](./07_side_effect.md)
+- [程序](./08_procedure.md)
+- [內置程序](./09_builtin_procs.md)
+- [數組](./10_array.md)
+- [元組](./11_tuple.md)
+- [字典](./12_dict.md)
+- [記錄](./13_record.md)
+- [設置](./14_set.md)
+- [類型](./15_type.md)
+ - [類型系統](./type/01_type_system.md)
+ - [基礎](./type/02_basic.md)
+ - [特質](./type/03_trait.md)
+ - [類](./type/04_class.md)
+ - [繼承](./type/05_inheritance.md)
+ - [NST 與 SST](./type/06_nst_vs_sst.md)
+ - [補丁](./type/07_patch.md)
+ - [值類型](./type/08_value.md)
+ - [屬性類型](./type/09_attributive.md)
+ - [間隔類型](./type/10_interval.md)
+ - [枚舉類型](./type/11_enum.md)
+ - [細化類型](./type/12_refinement.md)
+ - [代數類型](./type/13_algebraic.md)
+ - [依賴類型](./type/14_dependent.md)
+ - [量化類型](./type/15_quantified.md)
+ - [子類型](./type/16_subtyping.md)
+ - [類型轉換](./type/17_type_casting.md)
+ - [可變類型](./type/18_mut.md)
+ - [高級](./type/advanced.md)
+ - [默認參數](./type/advanced/default_param.md)
+ - [類型擦除](./type/advanced/erasure.md)
+ - [存在](./type/advanced/existential.md)
+ - [GADTs](./type/advanced/GADTs.md)
+ - [關鍵字參數](./type/advanced/keyword_param.md)
+ - [種類](./type/advanced/kind.md)
+ - [標記特征](./type/advanced/marker_trait.md)
+ - [可變結構](./type/advanced/mut_struct.md)
+ - [幻象類型](./type/advanced/phantom.md)
+ - [投影類型](./type/advanced/projection.md)
+ - [量化依賴類型](./type/advanced/quantified_dependent.md)
+ - [共享](./type/advanced/shared.md)
+- [迭代器](./16_iterator.md)
+- [可變性](./17_mutability.md)
+- [所有權](./18_ownership.md)
+- [可見性](./19_visibility.md)
+- [命名規則](20_naming_rule.md)
+- [Lambda](./21_lambda.md)
+- [子程序](./22_subroutine.md)
+- [關閉](./23_closure.md)
+- [模塊](./24_module.md)
+- [對象系統](./25_object_system.md)
+- [模式匹配](./26_pattern_matching.md)
+- [理解](./27_comprehension.md)
+- [擴展語法](./28_spread_syntax.md)
+- [裝飾器](./29_decorator.md)
+- [錯誤處理](./30_error_handling.md)
+- [管道](./31_pipeline.md)
+- [與 Python 集成](./32_integration_with_python.md)
+- [包系統](./33_package_system.md)
+- [發電機](./34_generator.md)
+- [索引](./indexes.md)
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/container_ownership.md b/doc/zh_TW/syntax/container_ownership.md
new file mode 100644
index 00000000..31392695
--- /dev/null
+++ b/doc/zh_TW/syntax/container_ownership.md
@@ -0,0 +1,44 @@
+# 下標(索引訪問)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/container_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`[]` 不同于普通的方法。
+
+```python
+a = [!1, !2]
+a[0].inc!()
+assert a == [2, 2]
+```
+
+回想一下,子例程的返回值不能是引用。
+這里的 `a[0]` 的類型顯然應該是 `Ref!(Int!)`(`a[0]` 的類型取決于上下文)。
+所以 `[]` 實際上是特殊語法的一部分,就像 `.` 一樣。 與 Python 不同,它不能被重載。
+也無法在方法中重現 `[]` 的行為。
+
+```python
+C = Class {i = Int!}
+C. get(ref self) =
+ self::i # 類型錯誤:`self::i` 是 `Int!`(需要所有權)但 `get` 不擁有 `self`
+C.steal(self) =
+ self::i
+#NG
+C.new({i = 1}).steal().inc!() # 所有權警告:`C.new({i = 1}).steal()` 不屬于任何人
+# 提示:分配給變量或使用 `uwn_do!`
+# OK (分配)
+c = C.new({i = 1})
+i = c.steal()
+i.inc!()
+assert i == 2
+# or (own_do!)
+own_do! C.new({i = 1}).steal(), i => i.inc!()
+```
+
+此外,`[]` 可以不承認,但元素不會移動
+
+```python
+a = [!1, !2]
+i = a[0]
+i.inc!()
+assert a[1] == 2
+a[0] # 所有權錯誤:`a[0]` 被移動到 `i`
+```
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/grammar.md b/doc/zh_TW/syntax/grammar.md
new file mode 100644
index 00000000..27a9388d
--- /dev/null
+++ b/doc/zh_TW/syntax/grammar.md
@@ -0,0 +1,90 @@
+# Erg 的語法(版本 0.1.0, 臨時)
+```
+special_op ::= '=' | '->' | '=>' | '.' | ',' | ':' | '::' | '|>' | '&'
+separator ::= ';' | '\n'
+escape ::= '\'
+comment_marker ::= '#'
+reserved_symbol ::= special_op | separator | comment_marker
+number ::= [0-9]
+first_last_dight ::= number
+dight ::= number | '_'
+bin_dight ::= [0-1]
+oct_dight ::= [0-8]
+hex_dight ::= [0-9]
+ | [a-f]
+ | [A-F]
+int ::= first_last_dight
+ | first_last_dight dight* first_last_dight
+ | '0' ('b' | 'B') binary_dight+
+ | '0' ('o' | 'O') octa_dight+
+ | '0' ('x' | 'X') hex_dight+
+ratio ::= '.' dight* first_last_dight
+ | first_last_dight dight* '.' dight* first_last_dight
+bool ::= 'True' | 'False'
+none ::= 'None'
+ellipsis ::= 'Ellipsis'
+not_implemented ::= 'NotImplemented'
+parenthesis ::= '(' | ')'
+bracket ::= '{' | '}'
+square_bracket ::= '[' | ']'
+enclosure ::= parenthesis | bracket | square_bracket
+infix_op ::= '+' | '-' | '*' | '/' | '//' | '**'
+ | '%' | '&&' | '||' | '^^' | '<' | '<=' | '>' | '>='
+ | 'and' | 'or' | 'is' | 'as' | 'isnot' | 'in' | 'notin' | 'dot' | 'cross'
+prefix_op ::= '+' | '-' | '*' | '**' | '..' | '..<' | '~' | '&' | '!'
+postfix_op ::= '?' | '..' | '<..'
+operator ::= infix_op | prefix_op | postfix_op
+char ::= /* ... */
+str ::= '\"' char* '\"
+symbol_head ::= /* char except dight */
+symbol ::= symbol_head /* char except (reserved_symbol | operator | escape | ' ') */
+subscript ::= accessor '[' expr ']'
+attr ::= accessor '.' symbol
+accessor ::= symbol | attr | subscript
+literal ::= int | ratio | str | bool | none | ellipsis | not_implemented
+pos_arg ::= expr
+kw_arg ::= symbol ':' expr
+arg ::= pos_arg | kw_arg
+enc_args ::= pos_arg (',' pos_arg)* ','?
+args ::= '()' | '(' arg (',' arg)* ','? ')' | arg (',' arg)*
+var_pattern ::= accessor | `...` accessor | '[' single_patterns ']'
+var_decl_opt_t = var_pattern (':' type)?
+var_decl = var_pattern ':' type
+param_pattern ::= symbol | `...` symbol | literal | '[' param_patterns ']'
+param_decl_opt_t = param_pattern (':' type)?
+param_decl = param_pattern ':' type
+params_opt_t ::= '()' (':' type)?
+ | '(' param_decl_opt_t (',' param_decl_opt_t)* ','? ')' (':' type)?
+ | param_decl_opt_t (',' param_decl_opt_t)*
+params ::= '()' ':' type
+ | '(' param_decl (',' param_decl)* ','? ')' ':' type
+subr_decl ::= accessor params
+subr_decl_opt_t ::= accessor params_opt_t
+decl ::= var_decl | subr_decl
+decl_opt_t = var_decl_opt_t | subr_decl_opt_t
+body ::= expr | indent line+ dedent
+def ::= ('@' decorator '\n')* decl_opt_t '=' body
+call ::= accessor args | accessor call
+decorator ::= call
+lambda_func ::= params_opt_t '->' body
+lambda_proc ::= params_opt_t '=>' body
+lambda ::= lambda_func | lambda_proc
+normal_array ::= '[' enc_args ']'
+array_comprehension ::= '[' expr | (generator)+ ']'
+array ::= normal_array | array_comprehension
+record ::= '{' '=' '}'
+ | '{' def (';' def)* ';'? '}'
+set ::= '{' '}'
+ | '{' expr (',' expr)* ','? '}'
+dict ::= '{' ':' '}'
+ | '{' expr ':' expr (',' expr ':' expr)* ','? '}'
+tuple ::= '(' ')'
+ | '(' expr (',' expr)* ','? ')'
+indent ::= /* ... */
+expr ::= accessor | literal
+ | prefix | infix | postfix
+ | array | record | set | dict | tuple
+ | call | def | lambda
+line ::= expr separator+
+program ::= expr? | (line | comment)*
+```
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/indexes.md b/doc/zh_TW/syntax/indexes.md
new file mode 100644
index 00000000..25fc980e
--- /dev/null
+++ b/doc/zh_TW/syntax/indexes.md
@@ -0,0 +1,178 @@
+# 指數
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/indexes.md&commit_hash=438bcb89ea692f219b30f3a3ba107888b23eae98)
+
+有關不在此索引中的 API,請參閱 [此處](../API/index.md)。
+有關術語,請參見 [此處](../dev_guide/terms.md)。
+
+## 符號
+
+* !
+ * !-type → [可變性](./type/mut.md)
+* [#](./00_basic.md/#comment)
+* $
+* %
+* &
+ * &&
+* ′ (single quote)
+* ()
+* *
+ * [*-less multiplication](./01_literal.md/#less-multiplication)
+* + (前置)
+ * +_ → + (前置)
+* + (中置)
+* ,
+* − (前置)
+ * −_ → − (前置)
+* − (中置)
+ * −>
+* . → [可見性]
+* /
+* :
+ * :: → [可見性]
+* ;
+* <
+ * <:
+ * <<
+ * <=
+* =
+ * ==
+ * =>
+* >
+ * >>
+ * >=
+* ?
+* @
+* []
+* \
+* ^
+ * ^^
+* _
+ * _+_ → + (infix)
+ * _-_ → − (infix)
+*``
+* {}
+ * {} type
+* {:}
+* {=}
+ * {=} type
+* |
+ * ||
+* ~
+
+## 字母
+
+### A
+
+* algebraic type
+* And
+* and
+* assert
+* attribute
+
+### B
+
+* Base
+* Bool
+
+### C
+
+* Class
+
+### D
+
+* Deprecated
+* distinct
+
+### E
+
+* enum type
+* Eq
+* Erg
+
+### F
+
+* for
+
+### G
+
+### H
+
+### I
+
+* if
+* import
+* in
+* Int
+
+### J
+
+### K
+
+### L
+
+* let-polymorphism → [rank 1 polymorphism]
+* log
+
+### M
+
+* match
+
+### N
+
+* Nat
+* Never
+* None
+* None
+* Not
+* not
+
+### O
+
+* Option
+* Or
+* or
+* Ord
+
+### P
+
+* panic
+* [print!](./../API/procs.md#print)
+* Python
+
+### Q
+
+### R
+
+* ref
+* ref!
+* Result
+* rootobj
+
+### S
+
+* self
+* [Self](./type/special.md)
+* [side-effect](./07_side_effect.md)
+* Str
+
+### T
+
+* Traits
+* True
+* Type
+* type
+
+### U
+
+### V
+
+### W
+
+* while!
+
+### X
+
+### Y
+
+### Z
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/quick_tour.md b/doc/zh_TW/syntax/quick_tour.md
new file mode 100644
index 00000000..c293b37b
--- /dev/null
+++ b/doc/zh_TW/syntax/quick_tour.md
@@ -0,0 +1,269 @@
+# 快速瀏覽
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/quick_tour.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`syntax` 下面的文檔是為了讓編程初學者也能理解而編寫的。
+對于已經掌握 Python、Rust、Haskell 等語言的人來說,可能有點啰嗦。
+
+所以,這里是 Erg 語法的概述。
+請認為未提及的部分與 Python 相同。
+
+## 變量,常量
+
+變量用 `=` 定義。 與 Haskell 一樣,變量一旦定義就不能更改。 但是,它可以在另一個范圍內被遮蔽。
+
+```python
+i = 0
+if True:
+ i = 1
+assert i == 0
+```
+
+任何以大寫字母開頭的都是常數。 只有可以在編譯時計算的東西才能是常量。
+此外,自定義以來,常量在所有范圍內都是相同的。
+
+```python
+PI = 3.141592653589793
+match random.random!(0..10):
+ PIs:
+ log "You get PI, it's a miracle!"
+```
+
+## 類型聲明
+
+與 Python 不同的是,只能先聲明變量類型。
+當然,聲明的類型和實際分配的對象的類型必須兼容。
+
+```python
+i: Int
+i = 10
+```
+
+## 函數
+
+你可以像在 Haskell 中一樣定義它。
+
+```python
+fib0 = 0
+fib1 = 1
+fibn = fib(n - 1) + fib(n - 2)
+```
+
+匿名函數可以這樣定義:
+
+```python
+i -> i + 1
+assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4]
+```
+
+## 運算符
+
+特定于 Erg 的運算符是:
+
+### 變異運算符 (!)
+
+這就像 Ocaml 中的`ref`。
+
+```python
+i = !0
+i.update! x -> x + 1
+assert i == 1
+```
+
+## 程序
+
+具有副作用的子例程稱為過程,并標有`!`。
+
+```python
+print! 1 # 1
+```
+
+## 泛型函數(多相關)
+
+```python
+id|T|(x: T): T = x
+id(1): Int
+id("a"): Str
+```
+
+## 記錄
+
+您可以使用類似 ML 的語言中的記錄等價物(或 JS 中的對象字面量)。
+
+```python
+p = {x = 1; y = 2}
+```
+
+## 所有權
+
+Ergs 由可變對象(使用 `!` 運算符突變的對象)擁有,并且不能從多個位置重寫。
+
+```python
+i = !0
+j = i
+assert j == 0
+i#移動錯誤
+```
+
+另一方面,不可變對象可以從多個位置引用。
+
+## 可見性
+
+使用 `.` 前綴變量使其成為公共變量并允許從外部模塊引用它。
+
+```python
+# foo.er
+.x = 1
+y = 1
+```
+
+```python
+foo = import "foo"
+assert foo.x == 1
+foo.y # 可見性錯誤
+```
+
+## 模式匹配
+
+### 變量模式
+
+```python
+# 基本任務
+i = 1
+# with 類型
+i: Int = 1
+# 函數
+fn x = x + 1
+fn: Int -> Int = x -> x + 1
+```
+
+### 文字模式
+
+```python
+# 如果 `i` 在編譯時無法確定為 1,則發生 類型錯誤
+# 簡寫:`_ {1} = i`
+1 = i
+# 簡單的模式匹配
+match x:
+ 1 -> "1"
+ 2 -> "2"
+ _ -> "other"
+# 斐波那契函數
+fib0 = 0
+fib1 = 1
+fibn: Nat = fibn-1 + fibn-2
+```
+
+### 常量模式
+
+```python
+PI = 3.141592653589793
+E = 2.718281828459045
+num = PI
+name = match num:
+ PI -> "pi"
+ E -> "e"
+ _ -> "unnamed"
+```
+
+### 丟棄(通配符)模式
+
+```python
+_ = 1
+_: Int = 1
+right(_, r) = r
+```
+
+### 可變長度模式
+
+與稍后描述的元組/數組/記錄模式結合使用。
+
+```python
+[i,...j] = [1, 2, 3, 4]
+assert j == [2, 3, 4]
+first|T|(fst: T, ...rest: T) = fst
+assert first(1, 2, 3) == 1
+```
+
+### 元組模式
+
+```python
+(i, j) = (1, 2)
+((k, l), _) = ((1, 2), (3, 4))
+# 如果不嵌套,() 可以省略(1, 2 被視為(1, 2))
+m, n = 1, 2
+```
+
+### 數組模式
+
+```python
+length[] = 0
+length[_, ...rest] = 1 + lengthrest
+```
+
+#### 記錄模式
+
+```python
+{sin; cos; tan; ...} = import "math"
+{*} = import "math" # 全部導入
+
+person = {name = "John Smith"; age = 20}
+age = match person:
+ {name = "Alice"; _} -> 7
+ {_; age} -> age
+```
+
+### 數據類模式
+
+```python
+Point = Inherit {x = Int; y = Int}
+p = Point::{x = 1; y = 2}
+Point::{x; y} = p
+```
+
+## 理解(Comprehensions)
+
+```python
+odds = [i | i <- 1..100; i % 2 == 0]
+```
+
+## 班級
+
+Erg 不支持多級/多級繼承。
+
+## 特質
+
+它們類似于 Rust 特征,但在更字面意義上,允許組合和解耦,并將屬性和方法視為平等。
+此外,它不涉及實施。
+
+```python
+XY = Trait {x = Int; y = Int}
+Z = Trait {z = Int}
+XYZ = XY and Z
+Show = Trait {show: Self.() -> Str}
+
+@Impl XYZ, Show
+Point = Class {x = Int; y = Int; z = Int}
+Point.
+ ...
+```
+
+## 修補
+
+您可以為類和特征提供實現。
+
+## 篩子類型
+
+謂詞表達式可以是類型限制的。
+
+```python
+Nat = {I: Int | I >= 0}
+```
+
+## 帶值的參數類型(依賴類型)
+
+```python
+a: [Int; 3]
+b: [Int; 4]
+a + b: [Int; 7]
+```
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/01_type_system.md b/doc/zh_TW/syntax/type/01_type_system.md
new file mode 100644
index 00000000..9dcd57e3
--- /dev/null
+++ b/doc/zh_TW/syntax/type/01_type_system.md
@@ -0,0 +1,230 @@
+# Erg 的類型系統
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/01_type_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+下面簡單介紹一下 Erg 的類型系統。 詳細信息在其他部分進行說明。
+
+## 如何定義
+
+Erg 的獨特功能之一是(普通)變量、函數(子例程)和類型(Kind)定義之間的語法沒有太大區別。 所有都是根據普通變量和函數定義的語法定義的。
+
+```python
+f i: Int = i + 1
+f # <函數 f>
+f(1) # 2
+f.method self = ... # 語法錯誤:無法為子例程定義方法
+
+T I: Int = {...}
+T #
+T(1) # 類型 T(1)
+T.method self = ...
+D = Class {private = Int; .public = Int}
+D # <類 'D'>
+o1 = {private = 1; .public = 2} # o1 是一個不屬于任何類的對象
+o2 = D.new {private = 1; .public = 2} # o2 是 D 的一個實例
+o2 = D.new {.public = 2} # 初始化錯誤:類 'D' 需要屬性 'private'(: Int) 但未定義
+```
+
+## Classification
+
+Erg 中的所有對象都是強類型的。
+頂層類型是`{=}`,實現了`__repr__`、`__hash__`、`clone`等(不是必須的方法,這些屬性不能被覆蓋)。
+Erg 的類型系統包含結構子類型 (SST)。 該系統類型化的類型稱為結構類型。
+結構類型主要分為三種:Attributive(屬性類型)、Refinement(細化類型)和Algebraic(代數類型)。
+
+| | Record | Enum | Interval | Union | Intersection | Diff |
+| --------- | ----------- | ---------- | -------------- | ----------- | ------------ | ------------ |
+| kind | Attributive | Refinement | Refinement | Algebraic | Algebraic | Algebraic |
+| generator | record | set | range operator | or operator | and operator | not operator |
+
+也可以使用名義子類型(NST),將 SST 類型轉換為 NST 類型稱為類型的名義化。 結果類型稱為名義類型。
+在 Erg 中,名義類型是類和特征。 當我們簡單地說類/特征時,我們通常指的是記錄類/特征。
+
+| | Type | Abstraction | Subtyping procedure |
+| --- | -------------- | ---------------- | ------------------- |
+| NST | NominalType | Trait | Inheritance |
+| SST | StructuralType | Structural Trait | (Implicit) |
+
+整個名義類型的類型(`NominalType`)和整個結構類型的類型(`StructuralType`)是整個類型(`Type`)的類型的子類型。
+
+Erg 可以將參數(類型參數)傳遞給類型定義。帶有類型參數的 `Option`、`Array` 等稱為多項式類型。這些本身不是類型,但它們通過應用參數成為類型。諸如 `Int`、`Str` 等沒有參數的類型稱為簡單類型(標量類型)。
+
+一個類型可以看成一個集合,并且存在包含關系。例如,“Num”包含“Add”、“Sub”等,“Int”包含“Nat”。
+所有類的上類是`Object == Class {:}`,所有類型的下類是`Never == Class {}`。這在下面描述。
+
+## 類型
+
+像 `Array T` 這樣的類型可以看作是 `Type -> Type` 類型的函數,它以 `T` 類型為參數并返回 `Array T` 類型(在類型論中也稱為 Kind)。像 `Array T` 這樣的類型專門稱為多態類型,而 `Array` 本身稱為一元 Kind。
+
+已知參數和返回類型的函數的類型表示為`(T, U) -> V`。如果要指定同一類型的整個雙參數函數,可以使用 `|T| (T, T) -> T`,如果要指定整個 N 參數函數,可以使用 `Func N`。但是,`Func N` 類型沒有關于參數數量或其類型的信息,因此所有返回值在調用時都是`Obj` 類型。
+
+`Proc` 類型表示為 `() => Int` 等等。此外,`Proc` 類型實例的名稱必須以 `!` 結尾。
+
+`Method` 類型是一個函數/過程,其第一個參數是它所屬的對象 `self`(通過引用)。對于依賴類型,也可以在應用方法后指定自己的類型。這是 `T!(!N)` 類型和 `T!(N ~> N-1)。 () => Int` 等等。
+
+Erg 的數組(Array)就是 Python 所說的列表。 `[詮釋; 3]`是一個數組類,包含三個`Int`類型的對象。
+
+> __Note__: `(Type; N)` 既是類型又是值,所以可以這樣使用。
+>
+> ```python.
+> Types = (Int, Str, Bool)
+>
+> for! Types, T =>
+> print! T
+> # Int Str Bool
+> a: Types = (1, "aaa", True)
+> ```
+
+```python
+pop|T, N|(l: [T; N]): ([T; N-1], T) =
+ [...l, last] = l
+ (l, last)
+
+lpop|T, N|(l: [T; N]): (T, [T; N-1]) =
+ [first, ...l] = l
+ (first, l)
+```
+
+以 `!` 結尾的類型可以重寫內部結構。 例如,`[T; !N]` 類是一個動態數組。
+要從“T”類型的對象創建“T!”類型的對象,請使用一元運算符“!”。
+
+```python
+i: Int! = !1
+i.update! i -> i + 1
+assert i == 2
+arr = [1, 2, 3]
+arr.push! 4 # 導入錯誤
+mut_arr = [1, 2, 3].into [Int; !3]
+mut_arr.push4
+assert mut_arr == [1, 2, 3, 4].
+```
+
+## 類型定義
+
+類型定義如下。
+
+```python
+Point2D = {.x = Int; .y = Int}
+```
+
+請注意,如果從變量中省略 `.`,它將成為類型中使用的私有變量。 但是,這也是必需的屬性。
+由于類型也是對象,因此類型本身也有屬性。 這樣的屬性稱為類型屬性。 在類的情況下,它們也稱為類屬性。
+
+## 數據類型
+
+如前所述,Erg 中的“類型”大致表示一組對象。
+
+下面是 `Add` 類型的定義,需要 `+`(中間運算符)。 `R, O` 是所謂的類型參數,可以是真正的類型(類),例如 `Int` 或 `Str`。 在其他語言中,類型參數被賦予特殊的符號(泛型、模板等),但在 Erg 中,它們可以像普通參數一樣定義。
+類型參數也可以用于類型對象以外的類型。 例如數組類型`[Int; 3]` 是 `Array Int, 3` 的語法糖。 如果類型實現重疊,用戶必須明確選擇一個。
+
+```python
+Add R = Trait {
+ .AddO = Type
+ . `_+_` = Self.(R) -> Self.AddO
+}
+```
+
+.`_+_`是Add.`_+_`的縮寫。 前綴運算符 .`+_` 是 `Num` 類型的方法。
+
+```python
+Num = Add and Sub and Mul and Eq
+NumImpl = Patch Num
+NumImpl.
+ `+_`(self): Self = self
+ ...
+```
+
+多態類型可以像函數一樣對待。 通過將它們指定為 `Mul Int、Str` 等,它們可以是單態的(在許多情況下,它們是用實際參數推斷出來的,而沒有指定它們)。
+
+```python
+1 + 1
+`_+_` 1, 1
+Nat.`_+_` 1, 1
+Int.`_+_` 1, 1
+```
+
+前四行返回相同的結果(準確地說,底部的返回 `Int`),但通常使用頂部的。
+`Ratio.`_+_`(1, 1)` 將返回 `2.0` 而不會出錯。
+這是因為 `Int <: Ratio`,所以 `1` 向下轉換為 `Ratio`。
+但這不是演員。
+
+```python
+i = 1
+if i: # 類型錯誤:i:Int 不能轉換為 Bool,請改用 Int.is_zero()。
+ log "a"
+ log "b"
+```
+
+這是因為 `Bool <: Int` (`True == 1`, `False == 0`)。轉換為子類型通常需要驗證。
+
+## 類型推理系統
+
+Erg 使用靜態鴨子類型,因此幾乎不需要顯式指定類型。
+
+```python
+f x, y = x + y
+```
+
+在上面的代碼中,帶有 `+` 的類型,即 `Add` 是自動推斷的; Erg 首先推斷出最小的類型。如果`f 0, 1`,它將推斷`f x:{0},y:{1}`,如果`n:Nat; f n, 1`,它會推斷`f x: Nat, y: {1}`。最小化之后,增加類型直到找到實現。在 `{0}, {1}` 的情況下,`Nat` 與 `Nat` 是單態的,因為 `Nat` 是具有 `+` 實現的最小類型。
+如果是 `{0}, {-1}`,它與 `Int` 是單態的,因為它不匹配 `Nat`。如果子類型和超類型之間沒有關系,則首先嘗試具有最低濃度(實例數)(或者在多態類型的情況下參數更少)的那個。
+`{0}` 和 `{1}` 是枚舉類型,它們是部分類型,例如 `Int` 和 `Nat`。
+例如,可以為枚舉類型指定名稱和請求/實現方法。在有權訪問該類型的命名空間中,滿足請求的對象可以使用實現方法。
+
+```python
+Binary = Patch {0, 1}
+Binary.
+ # self 包含一個實例。 在此示例中,為 0 或 1。
+ # 如果你想重寫self,你必須追加! 必須添加到類型名稱和方法名稱。
+ is_zero(self) = match self:
+ 0 -> True
+ 1 -> False # 你也可以使用 _ -> False
+ is_one(self) = not self.is_zero()
+ to_bool(self) = match self:
+ 0 -> False
+ 1 -> True
+```
+
+此后,代碼“0.to_bool()”是可能的(盡管“0 as Bool == False”是內置定義的)。
+這是一個實際上可以重寫 `self` 的類型的示例,如代碼所示。
+
+```python
+Binary! = Patch {0, 1}!
+Binary!
+ switch! ref! self = match! self:
+ 0 => self = 1
+ 1 => self = 0
+
+b = !1
+b.switch!()
+print! b # => 0
+```
+
+## 結構類型(匿名類型)
+
+```python
+Binary = {0, 1}
+```
+
+上面代碼中的 `Binary` 是一個類型,其元素是 `0` 和 `1`。 它也是 `Int` 類型的子類型,它同時具有 `0` 和 `1`。
+像 `{}` 這樣的對象本身就是一種類型,可以在分配或不分配給上述變量的情況下使用。
+這樣的類型稱為結構類型。 當我們想強調它作為后者而不是類(命名類型)的用途時,它也被稱為未命名類型。 `{0, 1}`這樣的結構類型稱為枚舉類型,還有區間類型、記錄類型等。
+
+### 類型標識
+
+無法指定以下內容。 例如,您不能指定 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int`。
+例如,`Int`和`Str`都是`Add`,但是`Int`和`Str`不能相加。
+
+```python
+add l: Add, r: Add =
+ l + r # 類型錯誤: `_+_` 沒有實現: |T, U <: Add| (T, U) -> <失敗>
+```
+
+此外,下面的類型 `A` 和 `B` 不被認為是同一類型。 但是,類型“O”被認為是匹配的
+
+```python
+... |R1; R2; O; A <: Add(R1, O); B <: Add(R2, O)|
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/type/02_basic.md b/doc/zh_TW/syntax/type/02_basic.md
new file mode 100644
index 00000000..583a8615
--- /dev/null
+++ b/doc/zh_TW/syntax/type/02_basic.md
@@ -0,0 +1,163 @@
+# 類型的基本語法
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/02_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 類型規范
+
+在 Erg 中,可以在 `:` 之后指定變量的類型,如下所示。這可以與作業同時完成。
+
+```python
+i: Int # 將變量 i 聲明為 Int 類型
+i: Int = 1
+j = 1 # 類型說明可以省略
+```
+
+您還可以指定普通表達式的類型。
+
+```python
+i = 1: Int
+f([1, "a"]: [Int or Str])
+```
+
+對于簡單的變量賦值,大多數類型說明可以省略。
+在定義子例程和類型時,類型規范更有用。
+
+```python
+# 參數的類型規范
+f x, y: Array Int = ...
+T X, Y: Array Int = ...
+```
+
+請注意,在上述情況下,`x, y` 都是 `Array Int`。
+
+```python
+# 大寫變量的值必須是常量表達式
+f X: Int = X
+```
+
+或者,如果你不需要關于類型參數的完整信息,你可以用 `_` 省略它
+
+```python
+g v: [T; _] = ...
+```
+
+但是請注意,類型規范中的 `_` 意味著 `Object`。
+
+```python
+f x: _, y: Int = x + y # 類型錯誤:Object 和 Int 之間沒有實現 +
+```
+
+## 子類型規范
+
+除了 `:`(類型聲明運算符),Erg 還允許您使用 `<:`(部分類型聲明運算符)來指定類型之間的關系。
+`<:` 的左邊只能指定一個類。 使用 `Subtypeof` 或類似的運算符來比較結構類型。
+
+這也經常在定義子例程或類型時使用,而不是簡單地指定變量。
+
+```python
+# 參數的子類型規范
+f X <: T = ...
+
+# 所需屬性的子類型規范(.Iterator 屬性必須是 Iterator 類型的子類型)
+Iterable T = Trait {
+ .Iterator = {Iterator} # {Iterator} == {I: Type | I <: Iterator}
+ .iter = Self.() -> Self.Iterator T
+ ...
+}
+```
+
+也可以在定義類時使用子類型規范來靜態檢查該類是否是指定類型的子類型。
+
+```python
+# C 類是 Show 的子類型
+C = Class Object, Impl := Show
+C.show self = ... # 顯示所需的屬性。
+```
+
+您也可以僅在特定情況下指定子類型
+
+```python
+K T: Eq
+K Int <: Show and Eq
+K T = Class Object
+K(T).
+ `==` self, other = ...
+K(Int).
+ show self = ...
+```
+
+實現結構類型時建議使用子類型規范。
+這是因為,由于結構子類型的性質,拼寫錯誤或類型規范錯誤在實現所需屬性時不會導致錯誤
+
+```python
+C = Class Object
+C.shoe self = ... # Show 由于 Typo 沒有實現(它被認為只是一種獨特的方法)
+```
+
+## 屬性定義
+
+只能在模塊中為特征和類定義屬性
+
+```python
+C = Class()
+C.pub_attr = "this is public"
+C::private_attr = "this is private"
+
+c = C.new()
+assert c.pub_attr == "this is public"
+```
+
+定義批處理定義的語法稱為批處理定義,其中在 `C.` 或 `C::` 之后添加換行符,并且定義在縮進下方組合在一起
+
+```python
+C = Class()
+C.pub1 = ...
+C.pub2 = ...
+C::priv1 = ...
+C::priv2 = ...
+# 相當于
+C = Class()
+C.
+ pub1 = ...
+ C. pub2 = ...
+C::
+ priv1 = ...
+ priv2 = ...
+```
+
+## 別名
+
+類型可以有別名。 這允許縮短長類型,例如記錄類型
+
+```python
+Id = Int
+Point3D = {x = Int; y = Int; z = Int}
+IorS = Int or Str
+Vector = Array Int
+```
+
+此外,當顯示錯誤時,如果定義了復合類型(在上面的示例中,右側類型不是第一個類型),編譯器將為它們使用別名。
+
+但是,每個模塊只允許一個相同類型的別名,多個別名將導致警告。
+這意味著應將具有不同用途的類型定義為單獨的類型。
+目的還在于防止在已經具有別名的類型之上添加別名。
+
+```python
+Id = Int
+UserId = Int # 類型警告:重復別名:Id 和 UserId
+
+Ids = Array Id
+Ints = Array Int # 類型警告:重復別名:Isd 和 Ints
+
+IorS = Int or Str
+IorSorB = IorS or Bool
+IorSorB_ = Int or Str or Bool # 類型警告:重復別名:IorSorB 和 IorSorB_
+
+Point2D = {x = Int; y = Int}
+Point3D = {.... Point2D; z = Int}
+Point = {x = Int; y = Int; z = Int} # 類型警告:重復別名:Point3D 和 Point
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/type/03_trait.md b/doc/zh_TW/syntax/type/03_trait.md
new file mode 100644
index 00000000..df7f4dee
--- /dev/null
+++ b/doc/zh_TW/syntax/type/03_trait.md
@@ -0,0 +1,189 @@
+# 特質
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/03_trait.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Trait 是一種名義類型,它將類型屬性要求添加到記錄類型。
+它類似于 Python 中的抽象基類 (ABC),但區別在于能夠執行代數運算。
+
+```python
+Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int}
+```
+
+特質不區分屬性和方法。
+
+注意,trait 只能聲明,不能實現(實現是通過一個叫做 patching 的特性來實現的,后面會討論)。
+可以通過指定部分類型來檢查特征在類中的實現。
+
+```python
+Point2D <: Norm
+Point2D = Class {.x = Int; .y = Int}
+Point2D.norm self = self.x**2 + self.y**2
+```
+
+Error if the required attributes are not implemented.
+
+```python
+Point2D <: Norm # 類型錯誤:Point2D 不是 Norm 的子類型
+Point2D = Class {.x = Int; .y = Int}
+```
+
+特征與結構類型一樣,可以應用組合、替換和消除等操作(例如“T 和 U”)。 由此產生的特征稱為即時特征。
+
+```python
+T = Trait {.x = Int}
+U = Trait {.y = Int}
+V = Trait {.x = Int; y: Int}
+assert Structural(T and U) == Structural V
+assert Structural(V not U) == Structural T
+W = Trait {.x = Ratio}
+assert Structural(W) ! = Structural(T)
+assert Structural(W) == Structural(T.replace {.x = Ratio})
+```
+
+Trait 也是一種類型,因此可以用于普通類型規范
+
+```python
+points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)]
+assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25].
+```
+
+## 特征包含
+
+擴展運算符 `...` 允許您將包含某個特征的特征定義為超類型。 這稱為特征的 __subsumption__。
+在下面的示例中,`BinAddSub` 包含 `BinAdd` 和 `BinSub`。
+這對應于類中的繼承,但與繼承不同的是,可以使用“和”組合多個基類型。 也允許被 `not` 部分排除的特征。
+
+```python
+Add R = Trait {
+ .AddO = Type
+ . `_+_` = Self.(R) -> Self.AddO
+}
+
+Sub R = Trait {
+ .SubO = Type
+ . `_-_` = Self.(R) -> Self.SubO
+}
+
+BinAddSub = Subsume Add(Self) and Sub(Self)
+```
+
+## 結構特征
+
+特征可以結構化
+
+```python
+SAdd = Structural Trait {
+ . `_+_` = Self.(Self) -> Self
+}
+# |A <: SAdd| 不能省略
+add|A <: SAdd| x, y: A = x.`_+_` y
+
+C = Class {i = Int}
+C.
+ new i = Self.__new__ {i;}
+ `_+_` self, other: Self = Self.new {i = self::i + other::i}
+
+assert add(C.new(1), C.new(2)) == C.new(3)
+```
+
+名義特征不能簡單地通過實現請求方法來使用,而必須明確聲明已實現。
+在以下示例中,`add`不能與`C`類型的參數一起使用,因為沒有明確的實現聲明。 它必須是`C = Class {i = Int}, Impl := Add`。
+
+```python
+Add = Trait {
+ .`_+_` = Self.(Self) -> Self
+}
+# |A <: 添加| 可以省略
+add|A <: Add| x, y: A = x.`_+_` y
+
+C = Class {i = Int}
+C.
+ new i = Self.__new__ {i;}
+ `_+_` self, other: Self = Self.new {i = self::i + other::i}
+
+add C.new(1), C.new(2) # 類型錯誤:C 不是 Add 的子類
+# 提示:繼承或修補“添加”
+```
+
+不需要為此實現聲明結構特征,但類型推斷不起作用。 使用時需要指定類型。
+
+## 多態特征
+
+特征可以帶參數。 這與多態類型相同。
+
+```python
+Mapper T: Type = Trait {
+ .mapIter = {Iterator}
+ .map = Self(T). (T -> U) -> Self.MapIter U
+}
+
+# ArrayIterator <: Mapper
+# ArrayIterator.MapIter == ArrayMapper
+# [1, 2, 3].iter(): ArrayIterator Int
+# [1, 2, 3].iter().map(x -> "{x}"): ArrayMapper Str
+assert [1, 2, 3].iter().map(x -> "{x}").collect(Array) == ["1", "2", "3"].
+```
+
+## Override特征
+
+派生特征可以Override基本特征的類型定義。
+在這種情況下,Override方法的類型必須是基方法類型的子類型。
+
+```python
+# `Self.(R) -> O` is a subtype of ``Self.(R) -> O or Panic
+Div R, O: Type = Trait {
+ . `/` = Self.(R) -> O or Panic
+}
+SafeDiv R, O = Subsume Div, {
+ @Override
+ . `/` = Self.(R) -> O
+}
+```
+
+## 在 API 中實現和解決重復的特征
+
+`Add`、`Sub` 和 `Mul` 的實際定義如下所示。
+
+```python
+Add R = Trait {
+ .Output = Type
+ . `_+_` = Self.(R) -> .Output
+}
+Sub R = Trait {
+ .Output = Type
+ . `_-_` = Self.(R) -> .Output
+}
+Mul R = Trait {
+ .Output = Type
+ . `*` = Self.(R) -> .Output
+}
+```
+
+`.Output` 重復。 如果要同時實現這些多個特征,請指定以下內容
+
+```python
+P = Class {.x = Int; .y = Int}
+# P|Self <: Add(P)|可簡寫為 P|<: Add(P)|
+P|Self <: Add(P)|.
+ Output = P
+ `_+_` self, other = P.new {.x = self.x + other.x; .y = self.y + other.y}
+P|Self <: Mul(Int)|.
+ Output = P
+ `*` self, other = P.new {.x = self.x * other; .y = self.y * other}
+```
+
+以這種方式實現的重復 API 在使用時幾乎總是類型推斷,但也可以通過使用 `||` 顯式指定類型來解決。
+
+```python
+print! P.Output # 類型錯誤:不明確的類型
+print! P|<: Mul(Int)|.Output #
+```
+
+## 附錄:與 Rust 特征的區別
+
+Erg 的特征忠實于 [Sch?rli 等人] (https://www.ptidej.net/courses/ift6251/fall06/presentations/061122/061122.doc.pdf) 提出的特征。
+為了允許代數運算,特征被設計為不能有方法實現目錄,但可以在必要時進行修補。
+
+
+ 上一頁 | 下一步
+
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/04_class.md b/doc/zh_TW/syntax/type/04_class.md
new file mode 100644
index 00000000..80185bb1
--- /dev/null
+++ b/doc/zh_TW/syntax/type/04_class.md
@@ -0,0 +1,289 @@
+# Class
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/04_class.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Erg 中的類大致是一種可以創建自己的元素(實例)的類型。
+這是一個簡單類的示例。
+
+```python
+Person = Class {.name = Str; .age = Nat}
+# 如果 `.new` 沒有定義,那么 Erg 將創建 `Person.new = Person::__new__`
+Person.
+ new name, age = Self::__new__ {.name = name; .age = age}
+
+john = Person.new "John Smith", 25
+print! john #
+print! classof(john) # Person
+```
+
+賦予“Class”的類型(通常是記錄類型)稱為需求類型(在本例中為“{.name = Str; .age = Nat}”)。
+可以使用 `::__new__ { = ; 創建實例 ...}` 可以創建。
+`{.name = "約翰·史密斯"; .age = 25}` 只是一條記錄,但它通過傳遞 `Person.new` 轉換為 `Person` 實例。
+創建此類實例的子例程稱為構造函數。
+在上面的類中,`.new` 方法被定義為可以省略字段名等。
+
+請注意,以下不帶換行符的定義將導致語法錯誤。
+
+```python
+Person.new name, age = ... # 語法錯誤:不能直接在對象上定義屬性
+```
+
+> __Warning__:這是最近添加的規范,后續文檔中可能不會遵循。 如果你發現它,請報告它。
+
+## 實例和類屬性
+
+在 Python 和其他語言中,實例屬性通常在塊側定義如下,但請注意,這樣的寫法在 Erg 中具有不同的含義。
+
+```python
+# Python
+class Person:
+ name: str
+ age: int
+```
+
+```python
+# 在Erg中,這個符號意味著類屬性的聲明(不是實例屬性)
+Person = Class()
+Person.
+ name: Str
+ age: Int
+```
+
+```python
+# 以上 Python 代碼的 Erg 代碼
+Person = Class {
+ .name = Str
+ .age = Nat
+}
+```
+
+元素屬性(在記錄中定義的屬性)和類型屬性(也稱為實例/類屬性,尤其是在類的情況下)是完全不同的東西。 類型屬性是類型本身的屬性。 當一個類型的元素本身沒有所需的屬性時,它指的是一個類型屬性。 元素屬性是元素直接擁有的唯一屬性。
+為什么要進行這種區分? 如果所有屬性都是元素屬性,那么在創建對象時復制和初始化所有屬性將是低效的。
+此外,以這種方式劃分屬性明確了諸如“該屬性是共享的”和“該屬性是分開持有的”之類的角色。
+
+下面的例子說明了這一點。 `species` 屬性對所有實例都是通用的,因此將其用作類屬性更自然。 但是,屬性 `name` 應該是實例屬性,因為每個實例都應該單獨擁有它。
+
+```python
+Person = Class {name = Str}
+Person::
+ species = "human"
+Person.
+ describe() =
+ log "species: {species}"
+ greet self =
+ log "Hello, My name is {self::name}."
+
+Person.describe() # 類型:Person
+Person.greet() # 類型錯誤: 未綁定的方法 Person.greet 需要一個參數
+
+john = Person.new {name = "John"}
+john.describe() # 類型: human
+john.greet() # 你好,我是約翰
+
+alice = Person.new {name = "Alice"}
+alice.describe() # 類型: human
+alice.greet() # 你好,我是愛麗絲
+```
+
+順便說一下,如果實例屬性和類型屬性具有相同的名稱和相同的類型,則會發生編譯錯誤。 這是為了避免混淆。
+
+```python
+C = Class {.i = Int}
+C.i = 1 # 屬性錯誤:`.i` 已在實例字段中定義
+```
+
+## 類(Class), 類型(Type)
+
+請注意,`1` 的類和類型是不同的。
+只有一個類 `Int` 是 `1` 的生成器。 可以通過`classof(obj)`或`obj.__class__`獲取對象所屬的類。
+相比之下,`1`有無數種。 例如,`{1}, {0, 1}, 0..12, Nat, Int, Num`。
+但是,可以將最小類型定義為單一類型,在本例中為“{1}”。 可以通過`Typeof(obj)`獲取對象所屬的類型。 這是一個編譯時函數。
+對象可以使用補丁方法以及類方法。
+Erg 不允許您添加類方法,但您可以使用 [patch](./07_patch.md) 來擴展類。
+
+您還可以從現有類([Inheritable](./../27_decorator.md/#inheritable) 類)繼承。
+您可以使用 `Inherit` 創建一個繼承類。 左側的類型稱為派生類,右側的“繼承”的參數類型稱為基類(繼承類)。
+
+```python
+MyStr = Inherit Str
+# other: 如果你設置 ``other: Str'',你可以使用 MyStr。
+MyStr.
+ `-` self, other: Str = self.replace other, ""
+
+abc = MyStr.new("abc")
+# 這里的比較是向上的
+assert abc - "b" == "ac"
+```
+
+與 Python 不同,默認情況下,定義的 Erg 類是 `final`(不可繼承的)。
+要使類可繼承,必須將 `Inheritable` 裝飾器附加到該類。
+Str` 是可繼承的類之一。
+
+```python
+MyStr = Inherit Str # OK
+MyStr2 = Inherit MyStr # NG
+
+@Inheritable
+InheritableMyStr = Inherit Str
+MyStr3 = Inherit InheritableMyStr # OK
+```
+
+`Inherit Object` 和 `Class()` 在實踐中幾乎是等價的。 一般使用后者。
+
+類具有與類型不同的等價檢查機制。
+類型基于其結構進行等效性測試。
+
+```python
+Person = {.name = Str; .age = Nat}
+Human = {.name = Str; .age = Nat}
+
+assert Person == Human
+```
+
+class has no equivalence relation defined.
+
+```python
+Person = Class {.name = Str; .age = Nat}
+Human = Class {.name = Str; .age = Nat}
+
+Person == Human # 類型錯誤:無法比較類
+```
+
+## 與結構類型的區別
+
+我們說過類是一種可以生成自己的元素的類型,但這并不是嚴格的描述。 事實上,一個記錄類型+補丁可以做同樣的事情。
+
+```python
+Person = {.name = Str; .age = Nat}
+PersonImpl = Patch Person
+PersonImpl.
+ new name, age = {.name; .age}
+
+john = Person.new("John Smith", 25)
+```
+
+使用類有四個優點。
+第一個是構造函數經過有效性檢查,第二個是它的性能更高,第三個是您可以使用符號子類型(NST),第四個是您可以繼承和覆蓋。
+
+我們之前看到記錄類型 + 補丁也可以定義一個構造函數(某種意義上),但這當然不是一個合法的構造函數。 這當然不是一個合法的構造函數,因為它可以返回一個完全不相關的對象,即使它調用自己`.new`。 在類的情況下,`.new` 被靜態檢查以查看它是否生成滿足要求的對象。
+
+~
+
+類的類型檢查只是檢查對象的`。 __class__` 對象的屬性。 因此可以快速檢查一個對象是否屬于一個類型。
+
+~
+
+Erg 在課堂上啟用 NST; NST 的優點包括健壯性。
+在編寫大型程序時,經常會出現對象的結構巧合匹配的情況。
+
+```python
+Dog = {.name = Str; .age = Nat}
+DogImpl = Patch Dog
+DogImpl.
+ bark = log "Yelp!"
+...
+Person = {.name = Str; .age = Nat}
+PersonImpl = Patch Person
+PersonImpl.
+ greet self = log "Hello, my name is {self.name}."
+
+john = {.name = "John Smith"; .age = 20}
+john.bark() # "Yelp!"
+```
+
+`Dog` 和 `Person` 的結構完全一樣,但讓動物打招呼,讓人類吠叫顯然是無稽之談。
+前者是不可能的,所以讓它不適用更安全。 在這種情況下,最好使用類。
+
+```python
+Dog = Class {.name = Str; .age = Nat}
+Dog.bark = log "Yelp!"
+...
+Person = Class {.name = Str; .age = Nat}
+Person.greet self = log "Hello, my name is {self.name}."
+
+john = Person.new {.name = "John Smith"; .age = 20}
+john.bark() # 類型錯誤: `Person` 對象沒有方法 `.bark`。
+```
+
+另一個特點是補丁添加的類型屬性是虛擬的,實現類不作為實體保存。
+也就是說,`T.x`、`T.bar` 是可以通過與 `{i = Int}` 兼容的類型訪問(編譯時綁定)的對象,并且未在 `{i = Int}` 或 ` C`。
+相反,類屬性由類本身持有。 因此,它們不能被不處于繼承關系的類訪問,即使它們具有相同的結構。
+
+```python
+C = Class {i = Int}
+C.
+ foo self = ...
+print! dir(C) # ["foo", ...].
+
+T = Patch {i = Int}
+T.
+ x = 1
+ bar self = ...
+print! dir(T) # ["bar", "x", ...].
+assert T.x == 1
+assert {i = 1}.x == 1
+print! T.bar # <函數 bar>
+{i = Int}.bar # 類型錯誤:Record({i = Int}) 沒有方法 `.bar`。
+C.bar # 類型錯誤:C 沒有方法 `.bar` 打印!
+print! {i = 1}.bar # <方法 bar>
+C.new({i = 1}).bar # <方法 bar>
+```
+
+## 與數據類的區別
+
+有兩種類型的類:常規類,通過`Class`成為記錄類,以及從記錄類繼承(`Inherit`)的數據類。
+數據類繼承了記錄類的功能,具有分解賦值、默認實現的`==`和`hash`等特性。另一方面,數據類有自己的等價關系和格式展示。
+另一方面,如果要定義自己的等價關系或格式顯示,則應使用普通類。
+
+```python
+C = Class {i = Int}
+c = C.new {i = 1}
+d = C.new {i = 2}
+print! c #
+c == d # 類型錯誤:`==` 沒有為 `C` 實現
+
+D = Inherit {i = Int}
+e = D.new {i = 1}
+f = D.new {i = 2}
+print! e # D{i = 1}
+assert e ! = f
+```
+
+## 枚舉類
+
+為了便于定義“Or”類型的類,提供了一個“Enum”。
+
+```python
+X = Class()
+Y = Class()
+XorY = Enum X, Y
+```
+
+每種類型都可以通過`XorY.X`、`XorY.Y`來訪問,構造函數可以通過`XorY.cons(X)`獲得。
+`.cons` 是一個接受類并返回其構造函數的方法。
+
+```python
+x1 = XorY.new X.new()
+x2 = XorY.cons(X)()
+assert x1 == x2
+```
+
+## 類關系
+
+類是需求類型的子類型。 類中可以使用需求類型的方法(包括補丁方法)。
+
+```python
+T = Trait {.foo = Foo}
+C = Class(... , impl: T)
+C.
+ foo = foo
+ bar x = ...
+assert C < T
+assert C.foo == foo
+assert not T < C
+assert T.foo == Foo
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/type/05_inheritance.md b/doc/zh_TW/syntax/type/05_inheritance.md
new file mode 100644
index 00000000..ab3dc4a0
--- /dev/null
+++ b/doc/zh_TW/syntax/type/05_inheritance.md
@@ -0,0 +1,255 @@
+# 繼承
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/05_inheritance.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+繼承允許您定義一個新類,為現有類添加功能或專業化。
+繼承類似于包含在特征中。 繼承的類成為原始類的子類型。
+
+```python
+NewInt = Inherit Int
+NewInt.
+ plus1 self = self + 1
+
+assert NewInt.new(1).plus1() == 2
+assert NewInt.new(1) + NewInt.new(1) == 2
+```
+
+如果你希望新定義的類是可繼承的,你必須給它一個 `Inheritable` 裝飾器。
+
+您可以指定一個可選參數 `additional` 以允許該類具有其他實例屬性,但前提是該類是一個值類。 但是,如果類是值類,則不能添加實例屬性。
+
+```python
+@Inheritable
+Person = Class {name = Str}
+Student = Inherit Person, additional: {id = Int}
+
+john = Person.new {name = "John"}
+alice = Student.new {name = "Alice", id = 123}
+
+MailAddress = Inherit Str, additional: {owner = Str} # 類型錯誤:實例變量不能添加到值類中
+```
+
+Erg 的特殊設計不允許繼承“Never”類型。 Erg 的特殊設計不允許繼承 `Never` 類型,因為 `Never` 是一個永遠無法實例化的獨特類。
+
+## 枚舉類的繼承
+
+[Or 類型](./13_algebraic.md) 也可以被繼承。 在這種情況下,您可以通過指定可選參數 `Excluding` 來刪除任何選項(可以使用 `or` 進行多項選擇)。
+不能添加其他選項。 添加選項的類不是原始類的子類型。
+
+```python
+Number = Class Int or Float or Complex
+Number.abs(self): Float =
+ match self:
+ i: Int -> i.abs().into Float
+ f: Float -> f.abs()
+ c: Complex -> c.abs().into Float
+
+# c: 復雜不能出現在匹配選項中
+RealNumber = Inherit Number, Excluding: Complex
+```
+
+同樣,也可以指定[細化類型](./12_refinement.md)。
+
+```python
+Months = Class 0..12
+MonthsNot31Days = Inherit Months, Excluding: {1, 3, 5, 7, 8, 10, 12}
+
+StrMoreThan3 = Class StrWithLen N | N >= 3
+StrMoreThan4 = Inherit StrMoreThan3, Excluding: StrWithLen N | N == 3
+```
+
+## 覆蓋
+
+該類與補丁相同,可以將新方法添加到原始類型,但可以進一步“覆蓋”該類。
+這種覆蓋稱為覆蓋。要覆蓋,必須滿足三個條件。
+首先,覆蓋必須有一個 `Override` 裝飾器,因為默認情況下它會導致錯誤。
+另外,覆蓋不能改變方法的類型。它必須是原始類型的子類型。
+如果你重寫了一個被另一個方法引用的方法,你也必須重寫所有被引用的方法。
+
+為什么這個條件是必要的?這是因為重寫不僅會改變一種方法的行為,而且可能會影響另一種方法的行為。
+
+讓我們從第一個條件開始。此條件是為了防止“意外覆蓋”。
+換句話說,必須使用 `Override` 裝飾器來防止派生類中新定義的方法的名稱與基類的名稱沖突。
+
+接下來,考慮第二個條件。這是為了類型一致性。由于派生類是基類的子類型,因此它的行為也必須與基類的行為兼容。
+
+最后,考慮第三個條件。這種情況是 Erg 獨有的,在其他面向對象語言中并不常見,同樣是為了安全。讓我們看看如果不是這種情況會出現什么問題。
+
+```python
+# 反面示例
+@Inheritable
+Base! = Class {x = Int!}
+Base!
+ f! ref! self =
+ print! self::x
+ self.g!()
+ g! ref! self = self::x.update! x -> x + 1
+
+Inherited! = Inherit Base!
+Inherited!
+ @Override
+ g! ref! self = self.f!() # 無限遞歸警告:此代碼陷入無限循環
+ # 覆蓋錯誤:方法 `.g` 被 `.f` 引用但未被覆蓋
+```
+
+在繼承類 `Inherited!` 中,`.g!` 方法被重寫以將處理轉移到 `.f!`。 但是,基類中的 `.f!` 方法會將其處理轉移到 `.g!`,從而導致無限循環。 `.f` 是 `Base!` 類中的一個沒有問題的方法,但它被覆蓋以一種意想不到的方式使用,并且被破壞了。
+
+Erg 已將此規則構建到規范中。
+
+```python
+# OK.
+@Inheritable
+Base! = Class {x = Int!}
+Base!
+ f! ref! self =
+ print! self::x
+ self.g!()
+ g! ref! self = self::x.update! x -> x + 1
+
+Inherited! = Inherit Base!
+Inherited!
+ @Override
+ f! ref! self =
+ print! self::x
+ self::x.update! x -> x + 1
+ @Override
+ g! ref! self = self.f!()
+```
+
+然而,這個規范并沒有完全解決覆蓋問題。 然而,這個規范并沒有完全解決覆蓋問題,因為編譯器無法檢測覆蓋是否解決了問題。
+創建派生類的程序員有責任糾正覆蓋的影響。 只要有可能,嘗試定義一個別名方法。
+
+### 替換特征(或看起來像什么)
+
+盡管無法在繼承時替換特征,但有一些示例似乎可以這樣做。
+
+例如,`Int`,`Real` 的子類型(實現了 `Add()`),似乎重新實現了 `Add()`。
+
+```python
+Int = Class ... , Impl := Add() and ...
+```
+
+但實際上 `Real` 中的 `Add()` 代表 `Add(Real, Real)`,而在 `Int` 中它只是被 `Add(Int, Int)` 覆蓋。
+它們是兩個不同的特征(`Add` 是一個 [covariate](./advanced/variance.md),所以`Add(Real, Real) :> Add(Int, Int)`)。
+
+## 多重繼承
+
+Erg 不允許普通類之間的交集、差異和互補。
+```python
+Int and Str # 類型錯誤:無法合并類
+```
+
+該規則防止從多個類繼承,即多重繼承。
+
+```python
+IntAndStr = Inherit Int and Str # 語法錯誤:不允許類的多重繼承
+```
+
+但是,可以使用多個繼承的 Python 類。
+
+## 多層(多級)繼承
+
+Erg 繼承也禁止多層繼承。 也就是說,您不能定義從另一個類繼承的類。
+從“Object”繼承的可繼承類可能會異常繼承。
+
+同樣在這種情況下,可以使用 Python 的多層繼承類。
+
+## 重寫繼承的屬性
+
+Erg 不允許重寫從基類繼承的屬性。 這有兩個含義。
+
+第一個是對繼承的源類屬性的更新操作。 例如,它不能重新分配,也不能通過 `.update!` 方法更新。
+
+覆蓋與重寫不同,因為它是一種用更專業的方法覆蓋的操作。 覆蓋也必須替換為兼容的類型。
+
+```python
+@Inheritable
+Base! = Class {.pub = !Int; pri = !Int}
+Base!
+ var = !1
+ inc_pub! ref! self = self.pub.update! p -> p + 1
+
+Inherited! = Inherit Base!
+Inherited!
+ var.update! v -> v + 1
+ # 類型錯誤:不能更新基類變量
+ @Override
+ inc_pub! ref! self = self.pub + 1
+ # 覆蓋錯誤:`.inc_pub!` 必須是 `Self! 的子類型! () => ()`
+```
+
+第二個是對繼承源的(變量)實例屬性的更新操作。 這也是被禁止的。 基類的實例屬性只能從基類提供的方法中更新。
+無論屬性的可見性如何,都無法直接更新。 但是,它們可以被讀取。
+
+```python
+@Inheritable
+Base! = Class {.pub = !Int; pri = !Int}
+Base!
+ inc_pub! ref! self = self.pub.update! p -> p + 1
+ inc_pri! ref! self = self::pri.update! p -> p + 1
+
+self = self.pub.update!
+Inherited!
+ # OK
+ add2_pub! ref! self =
+ self.inc_pub!()
+ self.inc_pub!()
+ # NG, `Child` 不能觸摸 `self.pub` 和 `self::pri`。
+ add2_pub! ref! self =
+ self.pub.update! p -> p + 2
+```
+
+畢竟 Erg 繼承只能添加新的屬性和覆蓋基類的方法。
+
+## 使用繼承
+
+雖然繼承在正確使用時是一項強大的功能,但它也有一個缺點,即它往往會使類依賴關系復雜化,尤其是在使用多層或多層繼承時。復雜的依賴關系會降低代碼的可維護性。
+Erg 禁止多重和多層繼承的原因是為了降低這種風險,并且引入了類補丁功能以降低依賴關系的復雜性,同時保留繼承的“添加功能”方面。
+
+那么,反過來說,應該在哪里使用繼承呢?一個指標是何時需要“基類的語義子類型”。
+Erg 允許類型系統自動進行部分子類型確定(例如,Nat,其中 Int 大于或等于 0)。
+但是,例如,僅依靠 Erg 的類型系統很難創建“表示有效電子郵件地址的字符串類型”。您可能應該對普通字符串執行驗證。然后,我們想為已通過驗證的字符串對象添加某種“保證”。這相當于向下轉換為繼承的類。將 `Str object` 向下轉換為 `ValidMailAddressStr` 與驗證字符串是否采用正確的電子郵件地址格式是一一對應的。
+
+```python
+ValidMailAddressStr = Inherit Str
+ValidMailAddressStr.
+ init s: Str =
+ validate s # 郵件地址驗證
+ Self.new s
+
+s1 = "invalid mail address"
+s2 = "foo@gmail.com"
+_ = ValidMailAddressStr.init s1 # 恐慌:無效的郵件地址
+valid = ValidMailAddressStr.init s2
+valid: ValidMailAddressStr # 確保電子郵件地址格式正確
+```
+
+另一個指標是您何時想要實現名義多態性。
+例如,下面定義的 `greet!` 過程將接受任何類型為 `Named` 的對象。
+但顯然應用 `Dog` 類型的對象是錯誤的。 所以我們將使用 `Person` 類作為參數類型。
+這樣,只有 `Person` 對象、從它們繼承的類和 `Student` 對象將被接受為參數。
+這是比較保守的,避免不必要地承擔過多的責任。
+
+```python
+Named = {name = Str; ...}
+Dog = Class {name = Str; breed = Str}
+Person = Class {name = Str}
+Student = Inherit Person, additional: {id = Int}
+structural_greet! person: Named =
+ print! "Hello, my name is {person::name}."
+greet! person: Person =
+ print! "Hello, my name is {person::name}."
+
+max = Dog.new {name = "Max", breed = "Labrador"}
+john = Person.new {name = "John"}
+alice = Student.new {name = "Alice", id = 123}
+
+structural_greet! max # 你好,我是馬克斯
+structural_greet! john # 你好,我是約翰
+greet! alice # 你好,我是愛麗絲
+greet! max # 類型錯誤:
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/type/06_nst_vs_sst.md b/doc/zh_TW/syntax/type/06_nst_vs_sst.md
new file mode 100644
index 00000000..8e0ecac5
--- /dev/null
+++ b/doc/zh_TW/syntax/type/06_nst_vs_sst.md
@@ -0,0 +1,45 @@
+# 名義子類型與結構子類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/06_nst_vs_sst.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+```python
+Months = 0..12
+
+# NST
+MonthsClass = Class Months
+MonthsClass.
+ name self =
+ match self:
+ 1 -> "january"
+ 2 -> "february"
+ 3 -> "march"
+ ...
+
+# SST
+MonthsImpl = Patch Months
+MonthsImpl.
+ name self =
+ match self:
+ 1 -> "January"
+ 2 -> "February"
+ 3 -> "March"
+ ...
+
+assert 12 in Months
+assert 2.name() == "February"
+assert not 12 in MonthsClass
+assert MonthsClass.new(12) in MonthsClass
+# 它可以使用結構類型,即使包裝在一個類中。
+assert MonthsClass.new(12) in Months
+# 如果兩者都存在,則類方法優先
+assert MonthsClass.new(2).name() == "february"
+```
+
+## 最后,我應該使用哪個,NST 還是 SST?
+
+如果您無法決定使用哪一個,我們的建議是 NST。
+SST 需要抽象技能來編寫在任何用例中都不會崩潰的代碼。 好的抽象可以帶來高生產力,但錯誤的抽象(外觀上的共性)會導致適得其反的結果。(NST 可以通過故意將抽象保持在最低限度來降低這種風險。如果您不是庫實現者,那么僅使用 NST 進行編碼并不是一個壞主意。
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/type/07_patch.md b/doc/zh_TW/syntax/type/07_patch.md
new file mode 100644
index 00000000..0cc37292
--- /dev/null
+++ b/doc/zh_TW/syntax/type/07_patch.md
@@ -0,0 +1,224 @@
+# 修補
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/07_patch.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Erg 不允許修改現有類型和類。
+這意味著,不可能在類中定義額外的方法,也不能執行特化(一種語言特性,單態化多態聲明的類型并定義專用方法,如在 C++ 中)。
+但是,在許多情況下,您可能希望向現有類型或類添加功能,并且有一個稱為“修補”的功能允許您執行此操作。
+
+```python
+StrReverse = Patch Str
+StrReverse.
+ reverse self = self.iter().rev().collect(Str)
+
+assert "abc".reverse() == "cba"
+```
+
+補丁的名稱應該是要添加的主要功能的簡單描述。
+這樣,被修補類型的對象(`Str`)可以使用修補程序的方法(`StrReverse`)。
+實際上,內置方法`.reverse`并不是`Str`的方法,而是`StrRReverse`中添加的方法。
+
+但是,補丁方法的優先級低于名義類型(類/特質)的方法,并且不能覆蓋現有類型。
+
+```python
+StrangeInt = Patch Int
+StrangeInt.
+ `_+_` = Int.`_-_` # 賦值錯誤:. `_+_` 已在 Int 中定義
+```
+
+如果要覆蓋,則必須從類繼承。
+但是,基本上建議不要覆蓋并定義具有不同名稱的方法。
+由于一些安全限制,覆蓋不是很容易做到。
+
+```python
+StrangeInt = Inherit Int
+StrangeInt.
+# 覆蓋方法必須被賦予覆蓋裝飾器。
+ # 另外,你需要覆蓋所有依賴于 Int.`_+_` 的 Int 方法。
+ @Override
+ `_+_` = Super.`_-_` # OverrideError: Int.`_+_` 被 ... ````` 引用,所以這些方法也必須被覆蓋
+```
+
+## 選擇修補程序
+
+可以為單一類型定義修復程序,并且可以組合在一起。
+
+```python
+# foo.er
+
+StrReverse = Patch(Str)
+StrReverse.
+ reverse self = ...
+StrMultiReplace = Patch(Str)
+StrMultiReverse.
+ multi_replace self, pattern_and_targets: [(Pattern, Str)] = ...
+StrToCamelCase = Patch(Str)
+StrToCamelCase.
+ to_camel_case self = ...
+StrToKebabCase = Patch(Str)
+StrToKebabCase.
+ to_kebab_case self = ...
+
+StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase
+StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase
+```
+
+```python
+{StrBoosterPack; ...} = import "foo"
+
+assert "abc".reverse() == "cba"
+assert "abc".multi_replace([("a", "A"), ("b", "B")]) == "ABc"
+assert "to camel case".to_camel_case() == "toCamelCase"
+assert "to kebab case".to_kebab_case() == "to-kebab-case"
+```
+
+如果定義了多個修復程序,其中一些可能會導致重復實施
+
+```python
+# foo.er
+
+StrReverse = Patch(Str)
+StrReverse.
+ reverse self = ...
+# 更高效的實現
+StrReverseMk2 = Patch(Str)
+StrReverseMk2.
+ reverse self = ...
+
+"hello".reverse() # 補丁選擇錯誤: `.reverse` 的多個選擇: StrReverse, StrReverseMk2
+```
+
+在這種情況下,您可以使用 __related function__ 形式而不是方法形式使其唯一
+
+```python
+assert StrReverseMk2.reverse("hello") == "olleh"
+```
+
+You can also make it unique by selectively importing.
+
+```python
+{StrReverseMk2; ...} = import "foo"
+
+assert "hello".reverse() == "olleh"
+```
+
+## 膠水補丁
+
+維修程序也可以將類型相互關聯。 `StrReverse` 補丁涉及 `Str` 和 `Reverse`。
+這樣的補丁稱為 __glue patch__。
+因為 `Str` 是內置類型,所以用戶需要使用膠水補丁來改造特征。
+
+```python
+Reverse = Trait {
+ .reverse = Self.() -> Self
+}
+
+StrReverse = Patch Str, Impl := Reverse
+StrReverse.
+ reverse self =
+ self.iter().rev().collect(Str)
+```
+
+每個類型/特征對只能定義一個膠水補丁。
+這是因為如果多個膠水修復程序同時“可見”,就不可能唯一確定選擇哪個實現。
+但是,當移動到另一個范圍(模塊)時,您可以交換維修程序。
+
+```python
+NumericStr = Inherit Str
+NumericStr.
+ ...
+
+NumStrRev = Patch NumericStr, Impl := Reverse
+NumStrRev.
+ ...
+# 重復修補程序錯誤:數值Str已與“反向”關聯`
+# 提示:'Str'(NumericStr'的超類)通過'StrReverse'與'Reverse'關聯
+```
+
+## 附錄:與 Rust 特征的關系
+
+Erg 修復程序相當于 Rust 的(改造的)`impl` 塊。
+
+```rust
+// Rust
+trait Reverse {
+ fn reverse(self) -> Self;
+}
+
+impl Reverse for String {
+ fn reverse(self) -> Self {
+ self.chars().rev().collect()
+ }
+}
+```
+
+可以說,Rust 的特征是 Erg 的特征和修復程序的特征。 這使得 Rust 的特征聽起來更方便,但事實并非如此。
+
+```python
+# Erg
+Reverse = Trait {
+ .reverse = Self.() -> Self
+}
+
+StrReverse = Patch(Str, Impl := Reverse)
+StrReverse.
+ reverse self =
+ self.iter().rev().collect(Str)
+```
+
+因為 impl 塊在 Erg 中被對象化為補丁,所以在從其他模塊導入時可以選擇性地包含。 作為副作用,它還允許將外部特征實現到外部結構。
+此外,結構類型不再需要諸如 `dyn trait` 和 `impl trait` 之類的語法。
+
+```python
+# Erg
+reversible: [Reverse; 2] = [[1, 2, 3], "hello"]
+
+iter|T|(i: Iterable T): Iterator T = i.iter()
+```
+
+```rust
+// Rust
+let reversible: [Box; 2] = [Box::new([1, 2, 3]), Box::new("hello")];
+
+fn iter(i: I) -> impl Iterator- where I: IntoIterator {
+ i.into_iter()
+}
+```
+
+## 通用補丁
+
+補丁不僅可以為一種特定類型定義,還可以為“一般功能類型”等定義。
+在這種情況下,要給出自由度的項作為參數給出(在下面的情況下,`T:Type`)。 以這種方式定義的補丁稱為全對稱補丁。
+如您所見,全對稱補丁正是一個返回補丁的函數,但它本身也可以被視為補丁。
+
+```python
+FnType T: Type = Patch(T -> T)
+FnType(T).
+ type = T
+
+assert (Int -> Int).type == Int
+```
+
+## 結構補丁
+
+此外,可以為滿足特定結構的任何類型定義修復程序。
+但是,這比名義上的維修程序和類方法具有較低的優先級。
+
+在定義結構修復程序時應使用仔細的設計,因為某些屬性會因擴展而丟失,例如以下內容。
+
+```python
+# 這不應該是 `Structural`
+Norm = Structural Patch {x = Int; y = Int}
+Norm.
+ norm self = self::x**2 + self::y**2
+
+Point2D = Class {x = Int; y = Int}
+assert Point2D.new({x = 1; y = 2}).norm() == 5
+
+Point3D = Class {x = Int; y = Int; z = Int}
+assert Point3D.new({x = 1; y = 2; z = 3}).norm() == 14 # AssertionError:
+```
+
+
+ 上一頁 | 下一頁
+
diff --git a/doc/zh_TW/syntax/type/08_value.md b/doc/zh_TW/syntax/type/08_value.md
new file mode 100644
index 00000000..0989d081
--- /dev/null
+++ b/doc/zh_TW/syntax/type/08_value.md
@@ -0,0 +1,39 @@
+# 值類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/08_value.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+值類型是可以在編譯時評估的 Erg 內置類型,具體來說:
+
+```python
+Value = (
+ Int
+ or Nat
+ or Ratio
+ or Float
+ or Complex
+ or Bool
+ or Str
+ or NoneType
+ or Array Const
+ or Tuple Const
+ or Set Const
+ or ConstFunc(Const, _)
+ or ConstProc(Const, _)
+ or ConstMethod(Const, _)
+)
+```
+
+應用于它們的值類型對象、常量和編譯時子例程稱為 __constant 表達式__。
+
+```python
+1, 1.0, 1+2im, True, None, "aaa", [1, 2, 3], Fib(12)
+```
+
+小心子程序。子例程可能是也可能不是值類型。
+由于子程序的實質只是一個指針,因此可以將其視為一個值[1 ](#1),但是在編譯不是子程序的東西時不能使用 在恒定的上下文中。 不是值類型,因為它沒有多大意義。
+
+將來可能會添加歸類為值類型的類型。
+
+---
+
+1 Erg 中的術語“值類型”與其他語言中的定義不同。 純 Erg 語義中沒有內存的概念,并且因為它被放置在堆棧上而說它是值類型,或者因為它實際上是一個指針而說它不是值類型是不正確的。 值類型僅表示它是“值”類型或其子類型。 [?](#f1)
diff --git a/doc/zh_TW/syntax/type/09_attributive.md b/doc/zh_TW/syntax/type/09_attributive.md
new file mode 100644
index 00000000..726e38ea
--- /dev/null
+++ b/doc/zh_TW/syntax/type/09_attributive.md
@@ -0,0 +1,11 @@
+# 屬性類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/09_attributive.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7)
+
+屬性類型是包含 Record 和 Dataclass、Patch、Module 等的類型。
+屬于屬性類型的類型不是值類型。
+
+## 記錄類型復合
+
+可以展平復合的記錄類型。
+例如,`{... {.name = Str; .age = Nat}; ... {.name = Str; .id = Nat}}` 變成 `{.name = Str; .age = 自然; .id = Nat}`。
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/10_interval.md b/doc/zh_TW/syntax/type/10_interval.md
new file mode 100644
index 00000000..b64290d9
--- /dev/null
+++ b/doc/zh_TW/syntax/type/10_interval.md
@@ -0,0 +1,38 @@
+# 間隔類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/10_interval.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+`Range` 對象最基本的用途是作為迭代器。
+
+```python
+for! 0..9, i =>
+ print! i
+```
+
+請注意,與 Python 不同,它包含一個結束編號。
+
+然而,這不僅僅用于 `Range` 對象。 也可以使用類型。 這種類型稱為Interval類型。
+
+```python
+i: 0..10 = 2
+```
+
+`Nat` 類型等價于 `0.. ExtraStatus,Status的元素可以使用ExtraStatus的方法
+Status = Trait {"Ok", "Error"}
+ # ...
+ExtraStatus = Trait {"Ok", "Error", "Unknown"}
+ # ...
+```
+
+方法也可以通過補丁添加。
+
+使用“或”運算符明確指示包含或向現有 Enum 類型添加選項。
+
+```python
+ExtraStatus = Status or {"Unknown"}
+```
+
+一個元素所屬的所有類都相同的枚舉類型稱為同質枚舉類型。
+
+默認情況下,可以將需求類型為同類枚舉類型的類視為元素所屬類的子類。
+
+如果您不想這樣做,可以將其設為包裝類
+
+```python
+Abc = Class {"A", "B", "C"}
+Abc.new("A").is_uppercase()
+
+OpaqueAbc = Class {inner = {"A", "B", "C"}}.
+ new inner: {"A", "B", "C"} = Self.new {inner;}
+OpaqueAbc.new("A").is_uppercase() # 類型錯誤
+```
diff --git a/doc/zh_TW/syntax/type/12_refinement.md b/doc/zh_TW/syntax/type/12_refinement.md
new file mode 100644
index 00000000..1bb55f49
--- /dev/null
+++ b/doc/zh_TW/syntax/type/12_refinement.md
@@ -0,0 +1,77 @@
+# 細化類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/12_refinement.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+細化類型是受謂詞表達式約束的類型。 枚舉類型和區間類型是細化類型的語法糖。
+
+細化類型的標準形式是`{Elem: Type | (預)*}`。 這意味著該類型是其元素為滿足 `Pred` 的 `Elem` 的類型。
+可用于篩選類型的類型僅為 [Const type](./advanced/const.md)。
+
+```python
+Nat = 0.. _
+Odd = {N: Int | N % 2 == 1}
+Char = StrWithLen 1
+# StrWithLen 1 == {_: StrWithLen N | N == 1}
+[Int; 3] == {_: Array Int, N | N == 3}
+Array3OrMore == {A: Array _, N | N >= 3}
+```
+
+當有多個 pred 時,可以用 `;` 或 `and` 或 `or` 分隔。 `;` 和 `and` 的意思是一樣的。
+
+`Odd` 的元素是 `1, 3, 5, 7, 9, ...`。
+它被稱為細化類型,因為它的元素是現有類型的一部分,就好像它是細化一樣。
+
+`Pred` 被稱為(左側)謂詞表達式。 和賦值表達式一樣,它不返回有意義的值,左側只能放置一個模式。
+也就是說,諸如`X**2 - 5X + 6 == 0`之類的表達式不能用作細化類型的謂詞表達式。 在這方面,它不同于右側的謂詞表達式。
+
+```python
+{X: Int | X**2 - 5X + 6 == 0} # 語法錯誤:謂詞形式無效。 只有名字可以在左邊
+```
+
+如果你知道如何解二次方程,你會期望上面的細化形式等價于`{2, 3}`。
+但是,Erg 編譯器對代數的了解很少,因此無法解決右邊的謂詞。
+
+## 智能投射
+
+很高興您定義了 `Odd`,但事實上,它看起來不能在文字之外使用太多。 要將普通 `Int` 對象中的奇數提升為 `Odd`,即將 `Int` 向下轉換為 `Odd`,您需要傳遞 `Odd` 的構造函數。
+對于細化類型,普通構造函數 `.new` 可能會出現恐慌,并且有一個名為 `.try_new` 的輔助構造函數返回一個 `Result` 類型。
+
+```python
+i = Odd.new (0..10).sample!()
+i: Odd # or Panic
+```
+
+它也可以用作 `match` 中的類型說明。
+
+```python
+# i: 0..10
+i = (0..10).sample!
+match i:
+ o: Odd ->
+ log "i: Odd"
+ n: Nat -> # 0..10 < Nat
+ log "i: Nat"
+```
+
+但是,Erg 目前無法做出諸如“偶數”之類的子決策,因為它不是“奇數”等。
+
+## 枚舉、區間和篩選類型
+
+前面介紹的枚舉/區間類型是細化類型的語法糖。
+`{a, b, ...}` 是 `{I: Typeof(a) | I == a 或 I == b 或 ... }`,并且 `a..b` 被去糖化為 `{I: Typeof(a) | 我 >= a 和我 <= b}`。
+
+```python
+{1, 2} == {I: Int | I == 1 or I == 2}
+1..10 == {I: Int | I >= 1 and I <= 10}
+1... <10 == {I: Int | I >= 1 and I < 10}
+```
+
+## 細化模式
+
+正如 `_: {X}` 可以重寫為 `X`(常量模式),`_: {X: T | Pred}` 可以重寫為`X: T | Pred`
+
+```python
+# 方法 `.m` 是為長度為 3 或更大的數組定義的
+Array(T, N | N >= 3)
+ .m(&self) = ...
+```
diff --git a/doc/zh_TW/syntax/type/13_algebraic.md b/doc/zh_TW/syntax/type/13_algebraic.md
new file mode 100644
index 00000000..45739a7c
--- /dev/null
+++ b/doc/zh_TW/syntax/type/13_algebraic.md
@@ -0,0 +1,86 @@
+# 代數類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/13_algebraic.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e)
+
+代數類型是通過將類型視為代數來操作類型而生成的類型。
+它們處理的操作包括Union、Intersection、Diff、Complement等。
+普通類只能進行Union,其他操作會導致類型錯誤。
+
+## 聯合(Union)
+
+聯合類型可以為類型提供多種可能性。 顧名思義,它們是由“或”運算符生成的。
+一個典型的 Union 是 `Option` 類型。 `Option` 類型是 `T 或 NoneType` 補丁類型,主要表示可能失敗的值。
+
+```python
+IntOrStr = Int or Str
+assert dict.get("some key") in (Int or NoneType)
+
+# 隱式變為 `T != NoneType`
+Option T = T or NoneType
+```
+
+## 路口
+
+交集類型是通過將類型與 `and` 操作組合得到的。
+
+```python
+Num = Add and Sub and Mul and Eq
+```
+
+如上所述,普通類不能與“and”操作結合使用。 這是因為實例只屬于一個類。
+
+## 差異
+
+Diff 類型是通過 `not` 操作獲得的。
+最好使用 `and not` 作為更接近英文文本的符號,但建議只使用 `not`,因為它更適合與 `and` 和 `or` 一起使用。
+
+```python
+CompleteNum = Add and Sub and Mul and Div and Eq and Ord
+Num = CompleteNum not Div not Ord
+
+True = Bool not {False}
+OneTwoThree = {1, 2, 3, 4, 5, 6} - {4, 5, 6, 7, 8, 9, 10}
+```
+
+## 補充
+
+補碼類型是通過 `not` 操作得到的,這是一個一元操作。 `not T` 類型是 `{=} not T` 的簡寫。
+類型為“非 T”的交集等價于 Diff,類型為“非 T”的 Diff 等價于交集。
+但是,不推薦這種寫法。
+
+```python
+# 非零數類型的最簡單定義
+NonZero = Not {0}
+# 不推薦使用的樣式
+{True} == Bool and not {False} # 1 == 2 + - 1
+Bool == {True} not not {False} # 2 == 1 - -1
+```
+
+## 真代數類型
+
+有兩種代數類型:可以簡化的表觀代數類型和不能進一步簡化的真實代數類型。
+“表觀代數類型”包括 Enum、Interval 和 Record 類型的 `or` 和 `and`。
+這些不是真正的代數類型,因為它們被簡化了,并且將它們用作類型說明符將導致警告; 要消除警告,您必須簡化它們或定義它們的類型。
+
+```python
+assert {1, 2, 3} or {2, 3} == {1, 2, 3}
+assert {1, 2, 3} and {2, 3} == {2, 3}
+assert -2..-1 or 1..2 == {-2, -1, 1, 2}
+
+i: {1, 2} or {3, 4} = 1 # 類型警告:{1, 2} 或 {3, 4} 可以簡化為 {1, 2, 3, 4}
+p: {x = Int, ...} and {y = Int; ...} = {x = 1; y = 2; z = 3}
+# 類型警告:{x = Int, ...} 和 {y = Int; ...} 可以簡化為 {x = Int; y = 整數; ...}
+
+Point1D = {x = Int; ...}
+Point2D = Point1D and {y = Int; ...} # == {x = Int; y = Int; ...}
+q: Point2D = {x = 1; y = 2; z = 3}
+```
+
+真正的代數類型包括類型“或”和“與”。 類之間的“或”等類屬于“或”類型。
+
+```python
+assert Int or Str == Or(Int, Str)
+assert Int and Marker == And(Int, Marker)
+```
+
+Diff, Complement 類型不是真正的代數類型,因為它們總是可以被簡化。
diff --git a/doc/zh_TW/syntax/type/14_dependent.md b/doc/zh_TW/syntax/type/14_dependent.md
new file mode 100644
index 00000000..b2f226a4
--- /dev/null
+++ b/doc/zh_TW/syntax/type/14_dependent.md
@@ -0,0 +1,76 @@
+# 依賴類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/14_dependent.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+依賴類型是一個特性,可以說是 Erg 的最大特性。
+依賴類型是將值作為參數的類型。 普通的多態類型只能將類型作為參數,但依賴類型放寬了這個限制。
+
+依賴類型等價于`[T; N]`(`數組(T,N)`)。
+這種類型不僅取決于內容類型“T”,還取決于內容數量“N”。 `N` 包含一個`Nat` 類型的對象。
+
+```python
+a1 = [1, 2, 3]
+assert a1 in [Nat; 3]
+a2 = [4, 5, 6, 7]
+assert a1 in [Nat; 4]
+assert a1 + a2 in [Nat; 7]
+```
+
+如果函數參數中傳遞的類型對象與返回類型有關,則寫:
+
+```python
+narray: |N: Nat| {N} -> [{N}; N]
+narray(N: Nat): [N; N] = [N; N]
+assert array(3) == [3, 3, 3]
+```
+
+定義依賴類型時,所有類型參數都必須是常量。
+
+依賴類型本身存在于現有語言中,但 Erg 具有在依賴類型上定義過程方法的特性
+
+```python
+x=1
+f x =
+ print! f::x, module::x
+
+# Phantom 類型有一個名為 Phantom 的屬性,其值與類型參數相同
+T X: Int = Class Impl := Phantom X
+T(X).
+ x self = self::Phantom
+
+T(1).x() # 1
+```
+
+可變依賴類型的類型參數可以通過方法應用程序進行轉換。
+轉換規范是用 `~>` 完成的
+
+```python
+# 注意 `Id` 是不可變類型,不能轉換
+VM!(State: {"stopped", "running"}! := _, Id: Nat := _) = Class(..., Impl := Phantom! State)
+VM!().
+ # 不改變的變量可以通過傳遞`_`省略。
+ start! ref! self("stopped" ~> "running") =
+ self.initialize_something!()
+ self::set_phantom!("running")
+
+# 你也可以按類型參數切出(僅在定義它的模塊中)
+VM!.new() = VM!(!"stopped", 1).new()
+VM!("running" ~> "running").stop!ref!self =
+ self.close_something!()
+ self::set_phantom!("stopped")
+
+vm = VM!.new()
+vm.start!()
+vm.stop!()
+vm.stop!() # 類型錯誤:VM!(!"stopped", 1) 沒有 .stop!()
+# 提示:VM!(!"running", 1) 有 .stop!()
+```
+
+您還可以嵌入或繼承現有類型以創建依賴類型。
+
+```python
+MyArray(T, N) = Inherit[T; N]
+
+# self 的類型:Self(T, N) 與 .array 一起變化
+MyStruct!(T, N: Nat!) = Class {.array: [T; !N]}
+```
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/15_quantified.md b/doc/zh_TW/syntax/type/15_quantified.md
new file mode 100644
index 00000000..b0703989
--- /dev/null
+++ b/doc/zh_TW/syntax/type/15_quantified.md
@@ -0,0 +1,282 @@
+# 類型變量,量化類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/15_quantified.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+類型變量是用于例如指定子程序參數類型的變量,它的類型是任意的(不是單態的)。
+首先,作為引入類型變量的動機,考慮 `id` 函數,它按原樣返回輸入。
+
+```python
+id x: Int = x
+```
+
+返回輸入的“id”函數是為“Int”類型定義的,但這個函數顯然可以為任何類型定義。
+讓我們使用 `Object` 來表示最大的類。
+
+```python
+id x: Object = x
+
+i = id 1
+s = id "foo"
+b = id True
+```
+
+當然,它現在接受任意類型,但有一個問題:返回類型被擴展為 `Object`。 返回類型擴展為 `Object`。
+如果輸入是“Int”類型,我想查看返回類型“Int”,如果輸入是“Str”類型,我想查看“Str”。
+
+```python
+print! id 1 #
+id(1) + 1 # 類型錯誤:無法添加 `Object` 和 `Int
+```
+
+要確保輸入的類型與返回值的類型相同,請使用 __type 變量__。
+類型變量在`||`(類型變量列表)中聲明。
+
+```python
+id|T: Type| x: T = x
+assert id(1) == 1
+assert id("foo") == "foo"
+assert id(True) == True
+```
+
+這稱為函數的 __universal quantification(泛化)__。 有細微的差別,但它對應于其他語言中稱為泛型的函數。 泛化函數稱為__多態函數__。
+定義一個多態函數就像為所有類型定義一個相同形式的函數(Erg 禁止重載,所以下面的代碼真的不能寫)。
+
+```python
+id|T: Type| x: T = x
+# 偽代碼
+id x: Int = x
+id x: Str = x
+id x: Bool = x
+id x: Ratio = x
+id x: NoneType = x
+...
+```
+
+此外,類型變量“T”可以推斷為“Type”類型,因為它在類型規范中使用。 所以 `|T: Type|` 可以簡單地縮寫為 `|T|`。
+你也可以省略`|T, N| 腳; N]` 如果可以推斷它不是類型對象(`T: Type, N: Nat`)。
+
+如果類型對于任意類型來說太大,您也可以提供約束。
+約束也有優勢,例如,子類型規范允許使用某些方法。
+
+```python
+# T <: Add
+# => T 是 Add 的子類
+# => 可以做加法
+add|T <: Add| l: T, r: T = l + r
+```
+
+在本例中,`T` 必須是`Add` 類型的子類,并且要分配的`l` 和`r` 的實際類型必須相同。
+在這種情況下,“T”由“Int”、“Ratio”等滿足。因此,例如,“Int”和“Str”的添加沒有定義,因此被拒絕。
+
+您也可以像這樣鍵入它。
+
+```python
+f|
+ Y, Z: Type
+ X <: Add Y, O1
+ O1 <: Add Z, O2
+ O2 <: Add X, _
+| x: X, y: Y, z: Z =
+ x + y + z + x
+```
+
+如果注釋列表很長,您可能需要預先聲明它。
+
+```python
+f: |Y, Z: Type, X <: Add(Y, O1), O1 <: Add(Z, O2), O2 <: Add(X, O3)| (X, Y, Z) -> O3
+f|X, Y, Z| x: X, y: Y, z: Z =
+ x + y + z + x
+```
+
+與許多具有泛型的語言不同,所有聲明的類型變量都必須在臨時參數列表(`x: X, y: Y, z: Z` 部分)或其他類型變量的參數中使用。
+這是 Erg 語言設計的一個要求,即所有類型變量都可以從真實參數中推斷出來。
+因此,無法推斷的信息,例如返回類型,是從真實參數傳遞的; Erg 允許從實參傳遞類型。
+
+```python
+Iterator T = Trait {
+ # 從參數傳遞返回類型。
+ # .collect: |K: Type -> Type| Self(T). ({K}) -> K(T)
+ .collect(self(T), K: Type -> Type): K(T) = ...
+ ...
+}
+
+it = [1, 2, 3].iter().map i -> i + 1
+it.collect(Array) # [2, 3, 4].
+```
+
+類型變量只能在 `||` 期間聲明。 但是,一旦聲明,它們就可以在任何地方使用,直到它們退出作用域
+
+```python
+f|X|(x: X): () =
+ y: X = x.clone()
+ log X.__name__
+ log X
+
+f 1
+# Int
+#
+```
+
+您也可以在使用時明確單相如下
+
+```python
+f: Int -> Int = id|Int|
+```
+
+在這種情況下,指定的類型優先于實際參數的類型(匹配失敗將導致類型錯誤,即實際參數的類型錯誤)。
+即如果傳遞的實際對象可以轉換為指定的類型,則進行轉換; 否則會導致編譯錯誤。
+
+```python
+assert id(1) == 1
+assert id|Int|(1) in Int
+assert id|Ratio|(1) in Ratio
+# 你也可以使用關鍵字參數
+assert id|T: Int|(1) == 1
+id|Int|("str") # 類型錯誤: id|Int| is type `Int -> Int`但得到了 Str
+```
+
+當此語法與理解相沖突時,您需要將其括在 `()` 中。
+
+```python
+# {id|Int| x | x <- 1..10} 將被解釋為 {id | ...}
+{(id|Int| x) | x <- 1..10}
+```
+
+不能使用與已存在的類型相同的名稱來聲明類型變量。 這是因為所有類型變量都是常量。
+
+```python
+I: Type
+# ↓ 無效類型變量,已經存在
+f|I: Type| ... = ...
+```
+
+## 在方法定義中輸入參數
+
+默認情況下,左側的類型參數被視為綁定變量。
+
+```python
+K(T: Type, N: Nat) = ...
+K(T, N).
+ foo(x) = ...
+```
+
+使用另一個類型變量名稱將導致警告。
+
+```python
+K(T: Type, N: Nat) = ...
+K(U, M). # 警告:K 的類型變量名是 'T' 和 'N'
+ foo(x) = ...
+```
+
+自定義以來,所有命名空間中的常量都是相同的,因此它們當然不能用于類型變量名稱
+
+```python
+N = 1
+K(N: Nat) = ... # 名稱錯誤:N 已定義
+
+L(M: Nat) = ...
+# 僅當 M == N == 1 時才定義
+L(N).
+ foo(self, x) = ...
+# 為任何定義 M: Nat
+L(M).
+ .bar(self, x) = ...
+```
+
+每個類型參數不能有多個定義,但可以定義具有相同名稱的方法,因為未分配類型參數的依賴類型(非原始類型)和分配的依賴類型(原始類型)之間沒有關系 )。
+
+```python
+K(I: Int) = ...
+K.
+ # K 不是真正的類型(atomic Kind),所以我們不能定義方法
+ # 這不是方法(更像是靜態方法)
+ foo(x) = ...
+K(0).
+ foo(self, x): Nat = ...
+```
+
+## 所有對稱類型
+
+上一節中定義的 `id` 函數是一個可以是任何類型的函數。 那么 `id` 函數本身的類型是什么?
+
+```python
+print! classof(id) # |T: Type| T -> T
+```
+
+我們得到一個類型`|T: Type| T -> T`。 這稱為一個 __封閉的全稱量化類型/全稱類型__,即`['a. ...]'` 在 ML 和 `forall t. ...` 在 Haskell 中。 為什么使用形容詞“關閉”將在下面討論。
+
+封閉的全稱量化類型有一個限制:只有子程序類型可以被通用量化,即只有子程序類型可以放在左子句中。 但這已經足夠了,因為子程序是 Erg 中最基本的控制結構,所以當我們說“我要處理任意 X”時,即我想要一個可以處理任意 X 的子程序。所以,量化類型具有相同的含義 作為多態函數類型。 從現在開始,這種類型基本上被稱為多態函數類型。
+
+與匿名函數一樣,多態類型具有任意類型變量名稱,但它們都具有相同的值。
+
+```python
+assert (|T: Type| T -> T) == (|U: Type| U -> U)
+```
+
+當存在 alpha 等價時,等式得到滿足,就像在 lambda 演算中一樣。 由于對類型的操作有一些限制,所以總是可以確定等價的(如果我們不考慮 stoppage 屬性)。
+
+## 多態函數類型的子類型化
+
+多態函數類型可以是任何函數類型。 這意味著與任何函數類型都存在子類型關系。 讓我們詳細看看這種關系。
+
+類型變量在左側定義并在右側使用的類型,例如 `OpenFn T: Type = T -> T`,稱為 __open 通用類型__。
+相反,在右側定義和使用類型變量的類型,例如 `ClosedFn = |T: Type| T -> T`,被稱為 __封閉的通用類型__。
+
+開放通用類型是所有同構“真”類型的超類型。 相反,封閉的通用類型是所有同構真類型的子類型。
+
+```python
+(|T: Type| T -> T) < (Int -> Int) < (T -> T)
+```
+
+您可能還記得封閉的較小/開放的較大。
+但為什么會這樣呢? 為了更好地理解,讓我們考慮每個實例。
+
+```python
+# id: |T: Type| T -> T
+id|T|(x: T): T = x
+
+# iid: Int -> Int
+iid(x: Int): Int = x
+
+# 按原樣返回任意函數
+id_arbitrary_fn|T|(f1: T -> T): (T -> T) = f
+# id_arbitrary_fn(id) == id
+# id_arbitrary_fn(iid) == iid
+
+# return the poly correlation number as it is
+id_poly_fn(f2: (|T| T -> T)): (|T| T -> T) = f
+# id_poly_fn(id) == id
+id_poly_fn(iid) # 類型錯誤
+
+# 按原樣返回 Int 類型函數
+id_int_fn(f3: Int -> Int): (Int -> Int) = f
+# id_int_fn(id) == id|Int|
+# id_int_fn(iid) == iid
+```
+
+由于 `id` 是 `|T: Type| 類型T -> T`,可以賦值給`Int-> Int`類型的參數`f3`,我們可以考慮`(|T| T -> T) < (Int -> Int)`。
+反之,`Int -> Int`類型的`iid`不能賦值給`(|T| T -> T)`類型的參數`f2`,但可以賦值給`(|T| T -> T)`的參數`f1`輸入 `T -> T`,所以 `(Int -> Int) < (T -> T)`。
+因此,確實是`(|T| T -> T) < (Int -> Int) < (T -> T)`。
+
+## 量化類型和依賴類型
+
+依賴類型和量化類型(多態函數類型)之間有什么關系,它們之間有什么區別?
+我們可以說依賴類型是一種接受參數的類型,而量化類型是一種賦予參數任意性的類型。
+
+重要的一點是封閉的多態類型本身沒有類型參數。例如,多態函數類型`|T| T -> T` 是一個接受多態函數 __only__ 的類型,它的定義是封閉的。您不能使用其類型參數`T`來定義方法等。
+
+在 Erg 中,類型本身也是一個值,因此帶參數的類型(例如函數類型)可能是依賴類型。換句話說,多態函數類型既是量化類型又是依賴類型。
+
+```python
+PolyFn = Patch(|T| T -> T)
+PolyFn.
+ type self = T # 名稱錯誤:找不到“T”
+DepFn T = Patch(T -> T)
+DepFn.
+ type self =
+ log "by DepFn"
+ T
+
+assert (Int -> Int).type() == Int # 由 DepFn
+assert DepFn(Int).type() == Int # 由 DepFn
+```
diff --git a/doc/zh_TW/syntax/type/16_subtyping.md b/doc/zh_TW/syntax/type/16_subtyping.md
new file mode 100644
index 00000000..fe8e4127
--- /dev/null
+++ b/doc/zh_TW/syntax/type/16_subtyping.md
@@ -0,0 +1,78 @@
+# 子類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/16_subtyping.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+在 Erg 中,可以使用比較運算符 `<`、`>` 確定類包含。
+
+```python
+Nat < Int
+Int < Object
+1... _ < Nat
+{1, 2} > {1}
+{=} > {x = Int}
+{I: Int | I >= 1} < {I: Int | I >= 0}
+```
+
+請注意,這與 `<:` 運算符的含義不同。 它聲明左側的類是右側類型的子類型,并且僅在編譯時才有意義。
+
+```python
+C <: T # T: 結構類型
+f|D <: E| ...
+
+assert F < G
+```
+
+您還可以為多態子類型規范指定 `Self <: Add`,例如 `Self(R, O) <: Add(R, O)`。
+
+## 結構類型和類類型關系
+
+結構類型是結構類型的類型,如果它們具有相同的結構,則被認為是相同的對象。
+
+```python
+T = Structural {i = Int}
+U = Structural {i = Int}
+
+assert T == U
+t: T = {i = 1}
+assert t in T
+assert t in U
+```
+
+相反,類是符號類型的類型,不能在結構上與類型和實例進行比較
+
+```python
+C = Class {i = Int}
+D = Class {i = Int}
+
+assert C == D # 類型錯誤:無法比較類
+c = C.new {i = 1}
+assert c in C
+assert not c in D
+```
+
+## 子程序的子類型化
+
+子例程的參數和返回值只采用一個類。
+換句話說,您不能直接將結構類型或特征指定為函數的類型。
+必須使用部分類型規范將其指定為“作為該類型子類型的單個類”。
+
+```python
+# OK
+f1 x, y: Int = x + y
+# NG
+f2 x, y: Add = x + y
+# OK
+# A 是一些具體的類
+f3 x, y: A = x + y
+```
+
+子程序中的類型推斷也遵循此規則。 當子例程中的變量具有未指定的類型時,編譯器首先檢查它是否是其中一個類的實例,如果不是,則在特征范圍內查找匹配項。 如果仍然找不到,則會發生編譯錯誤。 此錯誤可以通過使用結構類型來解決,但由于推斷匿名類型可能會給程序員帶來意想不到的后果,因此它被設計為由程序員使用 `Structural` 顯式指定。
+
+## 類向上轉換
+
+```python
+i: Int
+i as (Int or Str)
+i as (1..10)
+i as {I: Int | I >= 0}
+```
diff --git a/doc/zh_TW/syntax/type/17_type_casting.md b/doc/zh_TW/syntax/type/17_type_casting.md
new file mode 100644
index 00000000..14a80ce8
--- /dev/null
+++ b/doc/zh_TW/syntax/type/17_type_casting.md
@@ -0,0 +1,74 @@
+# 投擲
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/17_type_casting.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 向上轉型
+
+因為 Python 是一種使用鴨子類型的語言,所以沒有強制轉換的概念。沒有必要向上轉型,本質上也沒有向下轉型。
+但是,Erg 是靜態類型的,因此有時必須進行強制轉換。
+一個簡單的例子是 `1 + 2.0`:`+`(Int, Ratio) 或 Int(<: Add(Ratio, Ratio)) 操作在 Erg 語言規范中沒有定義。這是因為 `Int <: Ratio`,所以 1 向上轉換為 1.0,即 Ratio 的一個實例。
+
+~~ Erg擴展字節碼在BINARY_ADD中增加了類型信息,此時類型信息為Ratio-Ratio。在這種情況下,BINARY_ADD 指令執行 Int 的轉換,因此沒有插入指定轉換的特殊指令。因此,例如,即使您在子類中重寫了某個方法,如果您將父類指定為類型,則會執行類型強制,并在父類的方法中執行該方法(在編譯時執行名稱修改以引用父母的方法)。編譯器只執行類型強制驗證和名稱修改。運行時不強制轉換對象(當前。可以實現強制轉換指令以優化執行)。 ~~
+
+```python
+@Inheritable
+Parent = Class()
+Parent.
+ greet!() = print! "Hello from Parent"
+
+Child = Inherit Parent
+Child.
+ # Override 需要 Override 裝飾器
+ @Override
+ greet!() = print! "Hello from Child"
+
+greet! p: Parent = p.greet!()
+
+parent = Parent.new()
+child = Child.new()
+
+parent # 來自Parent的問候!
+child # 來自child的問候!
+```
+
+此行為不會造成與 Python 的不兼容。 首先,Python 沒有指定變量的類型,所以可以這么說,所有的變量都是類型變量。 由于類型變量會選擇它們可以適應的最小類型,因此如果您沒有在 Erg 中指定類型,則可以實現與 Python 中相同的行為。
+
+```python
+@Inheritable
+Parent = Class()
+Parent.
+ greet!() = print! "Hello from Parent"
+
+Child = Inherit Parent
+Child.
+ greet!() = print! "Hello from Child" Child.
+
+greet! some = some.greet!()
+
+parent = Parent.new()
+child = Child.new()
+
+parent # 來自Parent的問候!
+child # 來自child的問候!
+```
+
+您還可以使用 `.from` 和 `.into`,它們會為相互繼承的類型自動實現
+
+```python
+assert 1 == 1.0
+assert Ratio.from(1) == 1.0
+assert 1.into() == 1.0
+```
+
+## 向下轉型
+
+由于向下轉換通常是不安全的并且轉換方法很重要,我們改為實現“TryFrom.try_from”
+
+```python
+IntTryFromFloat = Patch Int
+IntTryFromFloat.
+ try_from r: Float =
+ if r.ceil() == r:
+ then: r.ceil()
+ else: Error "conversion failed".
+```
diff --git a/doc/zh_TW/syntax/type/18_mut.md b/doc/zh_TW/syntax/type/18_mut.md
new file mode 100644
index 00000000..d0d24c7c
--- /dev/null
+++ b/doc/zh_TW/syntax/type/18_mut.md
@@ -0,0 +1,165 @@
+# 可變類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/18_mut.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+> __Warning__:本節中的信息是舊的并且包含一些錯誤。
+
+默認情況下,Erg 中的所有類型都是不可變的,即它們的內部狀態無法更新。
+但是你當然也可以定義可變類型。 變量類型用 `!` 聲明。
+
+```python
+Person! = Class({name = Str; age = Nat!})
+Person!.
+ greet! ref! self = print! "Hello, my name is {self::name}. I am {self::age}."
+ inc_age!ref!self = self::name.update!old -> old + 1
+```
+
+準確地說,基類型是可變類型或包含可變類型的復合類型的類型必須在類型名稱的末尾有一個“!”。 沒有 `!` 的類型可以存在于同一個命名空間中,并被視為單獨的類型。
+在上面的例子中,`.age` 屬性是可變的,`.name` 屬性是不可變的。 如果即使一個屬性是可變的,那么整個屬性也是可變的。
+
+可變類型可以定義重寫實例的過程方法,但具有過程方法并不一定使它們可變。 例如數組類型`[T; N]` 實現了一個 `sample!` 隨機選擇一個元素的方法,但當然不會破壞性地修改數組。
+
+對可變對象的破壞性操作主要是通過 .update! 方法完成的。 `.update!` 方法是一個高階過程,它通過應用函數 `f` 來更新 `self`
+
+```python
+i = !1
+i.update! old -> old + 1
+assert i == 2
+```
+
+`.set!` 方法只是丟棄舊內容并用新值替換它。 .set!x = .update!_ -> x。
+
+```python
+i = !1
+i.set! 2
+assert i == 2
+```
+
+`.freeze_map` 方法對不變的值進行操作
+
+```python
+a = [1, 2, 3].into [Nat; !3]
+x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(Array)
+```
+
+在多態不可變類型中,該類型的類型參數“T”被隱式假定為不可變。
+
+```python
+# ImmutType < Type
+KT: ImmutType = Class ...
+K!T: Type = Class ...
+```
+
+在標準庫中,變量 `(...)!` 類型通常基于不可變 `(...)` 類型。 但是,`T!` 和 `T` 類型沒有特殊的語言關系,并且不能這樣構造 [1 ](#1) 。
+
+請注意,有幾種類型的對象可變性。
+下面我們將回顧內置集合類型的不可變/可變語義。
+
+```python
+# 數組類型
+## 不可變類型
+[T; N] # 不能執行可變操作
+## 可變類型
+[T; N] # 可以一一改變內容
+[T; !N] # 可變長度,內容不可變但可以通過添加/刪除元素來修改
+[!T; N] # 內容是不可變的對象,但是可以替換成不同的類型(實際上可以通過不改變類型來替換)
+[!T; !N] # 類型和長度可以改變
+[T; !N] # 內容和長度可以改變
+[!T!; N] # 內容和類型可以改變
+[!T!; !N] # 可以執行各種可變操作
+```
+
+當然,您不必全部記住和使用它們。
+對于可變數組類型,只需將 `!` 添加到您想要可變的部分,實際上是 `[T; N]`, `[T!; N]`,`[T; !N]`, ` [T!; !N]` 可以涵蓋大多數情況。
+
+這些數組類型是語法糖,實際類型是:
+
+```python
+# actually 4 types
+[T; N] = Array(T, N)
+[T; !N] = Array!(T, !N)
+[!T; N] = ArrayWithMutType!(!T, N)
+[!T; !N] = ArrayWithMutTypeAndLength!(!T, !N)
+[T!; !N] = Array!(T!, !N)
+[!T!; N] = ArrayWithMutType!(!T!, N)
+[!T!; !N] = ArrayWithMutTypeAndLength!(!T!, !N)
+```
+
+這就是能夠改變類型的意思。
+
+```python
+a = [1, 2, 3].into [!Nat; 3]
+a.map!(_ -> "a")
+a: [!Str; 3]
+```
+
+其他集合類型也是如此。
+
+```python
+# 元組類型
+## 不可變類型
+(T, U) # 元素個數不變,內容不能變
+## 可變類型
+(T!, U) # 元素個數不變,第一個元素可以改變
+(T,U)! # 元素個數不變,內容可以替換
+...
+```
+
+```python
+# 設置類型
+## 不可變類型
+{T; N} # 不可變元素個數,內容不能改變
+## 可變類型
+{T!; N} # 不可變元素個數,內容可以改變(一個一個)
+{T; N}! # 可變元素個數,內容不能改變
+{T!; N}! # 可變元素個數,內容可以改變
+...
+```
+
+```python
+# 字典類型
+## 不可變類型
+{K: V} # 長度不可變,內容不能改變
+## 可變類型
+{K:V!} # 恒定長度,值可以改變(一一)
+{K:V}! # 可變長度,內容不能改變,但可以通過添加或刪除元素來增加或刪除,內容類型也可以改變
+...
+```
+
+```python
+# 記錄類型
+## 不可變類型
+{x = Int; y = Str} # 內容不能改變
+## 可變類型
+{x = Int!; y = Str} # 可以改變x的值
+{x = Int; y = Str}! # 替換 {x = Int; 的任何實例 y = Str}
+...
+```
+
+一個類型 `(...)` 簡單地變成了 `T! = (...)!` 當 `T = (...)` 被稱為簡單結構化類型。 簡單的結構化類型也可以(語義上)說是沒有內部結構的類型。
+數組、元組、集合、字典和記錄類型都是非簡單的結構化類型,但 Int 和 Sieve 類型是。
+
+```python
+#篩子類型
+## 枚舉
+{1, 2, 3} # 1, 2, 3 之一,不可更改
+{1、2、3}! # 1、2、3,可以改
+##區間類型
+1..12 #1到12,不能改
+1..12! # 1-12中的任意一個,你可以改變
+##篩型(普通型)
+{I: Int | I % 2 == 0} #偶數類型,不可變
+{I: Int | I % 2 == 0} #偶數類型,可以改變
+{I: Int | I % 2 == 0}! # 與上面完全相同的類型,但上面的表示法是首選
+```
+
+從上面的解釋來看,可變類型不僅包括自身可變的,還包括內部類型可變的。
+諸如 `{x: Int!}` 和 `[Int!; 之類的類型3]` 是內部可變類型,其中內部的對象是可變的,而實例本身是不可變的。
+
+對于具有內部結構并在類型構造函數本身上具有 `!` 的類型 `K!(T, U)`,`*self` 可以更改整個對象。也可以進行局部更改。
+但是,希望盡可能保持本地更改權限,因此如果只能更改 `T`,最好使用 `K(T!, U)`。
+而對于沒有內部結構的類型‘T!’,這個實例只是一個可以交換的‘T’盒子。方法不能更改類型。
+
+---
+
+1 `T!` 和 `T` 類型沒有特殊的語言關系是有意的。這是一個設計。如果存在關系,例如命名空間中存在`T`/`T!`類型,則無法從其他模塊引入`T!`/`T`類型。此外,可變類型不是為不可變類型唯一定義的。給定定義 `T = (U, V)`,`T!` 的可能變量子類型是 `(U!, V)` 和 `(U, V!)`。[?](#f1)
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/19_bound.md b/doc/zh_TW/syntax/type/19_bound.md
new file mode 100644
index 00000000..adf24228
--- /dev/null
+++ b/doc/zh_TW/syntax/type/19_bound.md
@@ -0,0 +1,20 @@
+# 類型綁定
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/19_bound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+類型邊界為類型規范添加條件。 實現這一點的函數是守衛(守衛子句)。
+此功能可用于函數簽名、匿名函數簽名以及篩選類型。
+守衛寫在返回類型之后。
+
+## 謂詞
+
+您可以使用返回 `Bool` 的表達式(謂詞表達式)指定變量滿足的條件。
+只能使用 [值對象](./08_value.md) 和運算符。 未來版本可能會支持編譯時函數
+
+```python
+f a: [T; N] | T, N, N > 5 = ...
+g a: [T; N | N > 5] | T, N = ...
+Odd = {I: Int | I % 2 == 1}
+R2Plus = {(L, R) | L, R: Ratio; L > 0 and R > 0}
+GeneralizedOdd = {I | U; I <: Div(Nat, U); I % 2 == 0}
+```
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced.md b/doc/zh_TW/syntax/type/advanced.md
new file mode 100644
index 00000000..18a43be3
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced.md
@@ -0,0 +1,2 @@
+下面,我們將討論更高級的類型系統。 初學者不必閱讀所有部分。[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/syntax/type/advanced/GADTs.md b/doc/zh_TW/syntax/type/advanced/GADTs.md
new file mode 100644
index 00000000..d8887fb4
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/GADTs.md
@@ -0,0 +1,68 @@
+# 廣義代數數據類型 (GADT)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/GADTs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg 可以通過對 Or 類型進行分類來創建廣義代數數據類型 (GADT)。
+
+```python
+Nil T = Class(Impl := Phantom T)
+Cons T = Class {head = T; rest = List T}, Impl := Unpack
+List T: Type = Class(Nil T or Cons T)
+List.
+ nil|T|() = Self(T).new Nil(T).new()
+ cons head, rest | T = Self(T).new Cons(T).new(head, rest)
+ head self = match self:
+ {head; ...}: Cons_ -> head
+ _: Nil -> panic "empty list"
+{nil; cons; ...} = List
+
+print! cons(1, cons(2, nil())).head() # 1
+print! nil.head() # 運行時錯誤:“空list”
+```
+
+我們說 `List.nil|T|() = ...` 而不是 `List(T).nil() = ...` 的原因是我們在使用它時不需要指定類型。
+
+```python
+i = List.nil()
+_: List Int = cons 1, i
+```
+
+這里定義的 `List T` 是 GADTs,但它是一個幼稚的實現,并沒有顯示 GADTs 的真正價值。
+例如,上面的 .head 方法會在 body 為空時拋出運行時錯誤,但是這個檢查可以在編譯時進行。
+
+```python
+List: (Type, {"Empty", "Nonempty"}) -> Type
+List T, "Empty" = Class(Impl := Phantom T)
+List T, "Nonempty" = Class {head = T; rest = List(T, _)}, Impl := Unpack
+List.
+ nil|T|() = Self(T, "Empty").new Nil(T).new()
+ cons head, rest | T = Self(T, "Nonempty").new {head; rest}
+List(T, "Nonempty").
+ head {head; ...} = head
+{nil; cons; ...} = List
+
+print! cons(1, cons(2, nil())).head() # 1
+print! nil().head() # 類型錯誤
+```
+
+街上經常解釋的 GADT 的一個例子是一個列表,可以像上面那樣通過類型來判斷內容是否為空。
+Erg 可以進一步細化以定義一個有長度的列表。
+
+```python
+List: (Type, Nat) -> Type
+List T, 0 = Class(Impl := Phantom T)
+List T, N = Class {head = T; rest = List(T, N-1)}, Impl := Unpack
+List.
+ nil|T|() = Self(T, 0).new Nil(T).new()
+ cons head, rest | T, N = Self(T, N).new {head; rest}
+List(_, N | N >= 1).
+ head {head; ...} = head
+List(_, N | N >= 2).
+ pair {head = first; rest = {head = second; ...}} = [first, second]
+{nil; cons; ...} = List
+
+print! cons(1, cons(2, nil)).pair() # [1, 2]
+print! cons(1, nil).pair() # 類型錯誤
+print! cons(1, nil).head() # 1
+print! nil. head() # 類型錯誤
+```
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced/_rank2type.md b/doc/zh_TW/syntax/type/advanced/_rank2type.md
new file mode 100644
index 00000000..f506bb75
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/_rank2type.md
@@ -0,0 +1,144 @@
+# rank-2 多態性
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/_rank2type.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+> __Warning__:本文檔已過時,一般包含錯誤。
+
+Erg 允許您定義接受各種類型的函數,例如 `id|T|(x: T): T = x`,即多相關。
+那么,我們可以定義一個接受多相關的函數嗎?
+比如這樣的函數(注意這個定義是錯誤的):
+
+```python
+# 我想要 tuple_map(i -> i * 2, (1, "a")) == (2, "aa")
+tuple_map|T|(f: T -> T, tup: (Int, Str)): (Int, Str) = (f(tup.0), f(tup.1))
+```
+
+注意 `1` 和 `"a"` 有不同的類型,所以匿名函數一次不是單態的。 需要單相兩次。
+這樣的函數不能在我們目前討論的類型范圍內定義。 這是因為類型變量沒有范圍的概念。
+讓我們暫時離開類型,看看值級別的范圍概念。
+
+```python
+arr = [1, 2, 3]
+arr.map i -> i + 1
+```
+
+上面代碼中的 `arr` 和 `i` 是不同作用域的變量。 因此,每個壽命都是不同的(`i` 更短)。
+
+到目前為止,所有類型變量的類型都具有相同的生命周期。 換句話說,‘T’、‘X’和‘Y’必須同時確定,之后保持不變。
+反之,如果我們可以將 `T` 視為“內部作用域”中的類型變量,我們可以組成一個 `tuple_map` 函數。 __Rank 2 type__ 就是為此目的而準備的。
+
+```python
+# tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str)
+tuple_map f: (|T: Type| T -> T), tup: (Int, Str) = (f(tup.0), f(tup.1))
+assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa")
+```
+
+`{(type) | 形式的類型 (類型變量列表)}` 被稱為通用類型(詳見[通用類型](./../quantified.md))。
+目前我們看到的`id`函數是一個典型的通用函數=多相關函數。
+
+```python
+id x = x
+id: |T: Type| T -> T
+```
+
+通用類型與函數類型構造函數`->`的關聯有特殊的規則,根據關聯的方式,類型的語義是完全不同的。
+
+用簡單的單參數函數來考慮這一點。
+
+```python
+f1: (T -> T) -> 整數 | T # 接受任何函數并返回 Int 的函數
+f2: (|T: Type| T -> T) -> Int # 接收多相關并返回 Int 的函數
+f3: Int -> (|T: Type| T -> T) # 一個函數,接受一個 Int 并返回一個封閉的通用函數
+f4: |T: Type|(Int -> (T -> T)) # 同上(首選)
+```
+
+`f1` 和 `f2` 不同,而 `f3` 和 `f4` 相同,這似乎很奇怪。 讓我們實際構造一個這種類型的函數。
+
+```python
+# id: |T: Type| T -> T
+id x = x
+# same type as `f1`
+take_univq_f_and_return_i(_: (|T: Type| T -> T), i: Int): Int = i
+# same type as `f2`
+take_arbit_f_and_return_i|T: Type|(_: T -> T, i: Int): Int = i
+# same type as `f3`
+take_i_and_return_univq_f(_: Int): (|T: Type| T -> T) = id
+# same type as `f4`
+take_i_and_return_arbit_f|T: Type|(_: Int): (T -> T) = id
+```
+
+After applying it, you will notice the difference.
+
+```python
+_ = take_univq_f_and_return_i(x -> x, 1) # OK
+_ = take_univq_f_and_return_i(x: Int -> x, 1) #NG
+_ = take_univq_f_and_return_i(x: Str -> x, 1) # NG
+_ = take_arbit_f_and_return_i(x -> x, 1) # OK
+_ = take_arbit_f_and_return_i(x: Int -> x, 1) # OK
+_ = take_arbit_f_anf_return_i(x: Str -> x, 1) # OK
+
+f: |T| T -> T = take_i_and_return_univq_f(1)
+g: |T| T -> T = take_i_and_return_arbit_f(1)
+assert f == g
+f2: Int -> Int = take_i_and_return_univq_f|Int|(1)
+g2: Int -> Int = take_i_and_return_arbit_f|Int|(1)
+assert f2 == g2
+```
+
+開放的多相關函數類型具體稱為 __任意函數類型__。 任意函數類型有無數種可能性:`Int -> Int`、`Str -> Str`、`Bool -> Bool`、`|T: Type| T -> T`, ... 是。
+另一方面,只有一個封閉的(返回與參數相同類型的對象)多態類型`|T:Type| T -> T`。 這種類型被專門稱為 __多態函數類型__。
+也就是說,`f1`可以通過`x: Int -> x+1`、`x: Bool -> not x`、`x -> x`等=`f1`是一個多相關數是的, 但是您只能將 `x -> x` 等傳遞給 `f2` = `f2` 不是 __多元相關__。
+但是像`f2`這樣的函數類型明顯不同于普通類型,我們需要新的概念來處理它們。 那是類型的“等級”。
+
+關于rank的定義,沒有量化的類型,如`Int`、`Str`、`Bool`、`T`、`Int -> Int`、`Option Int`等,都被視為“rank” 0”。
+
+```python
+# K 是多項式類型,例如 Option
+R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0)
+```
+
+接下來,具有一階全稱的類型,例如`|T| T -> T`,或者在返回值類型中包含它們的類型是“rank 1”。
+此外,具有二階全稱量化的類型(具有 rank 1 類型作為參數的類型,例如 `(|T| T -> T) -> Int`)或將它們包含在返回類型中的類型稱為“rank 2 ”。
+重復上述以定義“Rank N”類型。 此外,秩-N 類型包括秩為N 或更少的所有類型。 因此,混合等級的類型與其中最高的等級相同。
+
+```python
+R1 = (|...| R0) or (R0 -> R1) or K(R1) or R0
+R2 = (|...| R1) or (R1 -> R2) or K(R2) or R1
+...
+Rn = (|...| Rn-1) or (Rn-1 -> Rn) or K(Rn) or Rn-1
+```
+
+讓我們看看例子:
+
+```python
+ (|T: Type| T -> T) -> (|U: Type| U -> U)
+=> R1 -> R1
+=> R1 -> R2
+=> R2
+
+Option(|T: Type| T -> T)
+=> Option(R1)
+=> K(R1)
+=> R1
+```
+
+根據定義,`tuple_map` 是 rank-2 類型。
+
+```python
+tuple_map:
+ ((|T: Type| T -> T), (Int, Str)) -> (Int, Str)
+=> (R1, R0) -> R0
+=> R1 -> R2
+=> R2
+```
+
+Erg 最多可以處理 rank 2 的類型(因為 rank N 類型包括所有 rank N 或更少的類型,確切地說,所有 Erg 類型都是 rank 2 類型)。 試圖構造更多類型的函數是錯誤的。
+例如,所有處理多相關的函數都需要指定其他參數類型。 而且,這樣的功能是不可配置的。
+
+```python
+# 這是一個 rank-3 類型的函數
+# |X, Y: Type|((|T: Type| T -> T), (X, Y)) -> (X, Y)
+generic_tuple_map|X, Y: Type| f: (|T: Type| T -> T), tup: (X, Y) = (f(tup.0), f(tup.1))
+```
+
+眾所周知,具有 3 級或更高等級的類型在理論上無法通過類型推斷來確定。 然而,大多數實際需求可以被等級 2 類型覆蓋。
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced/default_param.md b/doc/zh_TW/syntax/type/advanced/default_param.md
new file mode 100644
index 00000000..8b2e2e63
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/default_param.md
@@ -0,0 +1,30 @@
+# 帶默認參數的函數類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/default_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+首先,讓我們看一個使用默認參數的示例。
+
+```python
+f: (Int, Int, z := Int) -> Int
+f(x, y, z := 0) = x + y + z
+
+g: (Int, Int, z := Int, w := Int) -> Int
+g(x, y, z := 0, w := 1) = x + y + z + w
+
+fold: ((Int, Int) -> Int, [Int], acc := Int) -> Int
+fold(f, [], acc) = acc
+fold(f, arr, acc := 0) = fold(f, arr[1..], f(acc, arr[0]))
+assert fold(f, [1, 2, 3]) == 6
+assert fold(g, [1, 2, 3]) == 8
+```
+
+`:=` 之后的參數是默認參數。
+子類型規則如下:
+
+```python
+((X, y := Y) -> Z) <: (X -> Z)
+((X, y := Y, ...) -> Z) <: ((X, ...) -> Z)
+```
+
+第一個意味著可以用沒有默認參數的函數來識別具有默認參數的函數。
+第二個意味著可以省略任何默認參數。
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced/erasure.md b/doc/zh_TW/syntax/type/advanced/erasure.md
new file mode 100644
index 00000000..7a4a74c5
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/erasure.md
@@ -0,0 +1,45 @@
+# 類型擦除
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/erasure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+類型擦除是將類型參數設置為 `_` 并故意丟棄其信息的過程。類型擦除是許多多態語言的特性,但在 Erg 的語法上下文中,將其稱為類型參數擦除更為準確。
+
+類型擦除的最常見示例是 `[T, _]`。數組在編譯時并不總是知道它們的長度。例如,引用命令行參數的 `sys.argv` 的類型為 `[Str, _]`。由于 Erg 的編譯器無法知道命令行參數的長度,因此必須放棄有關其長度的信息。
+然而,一個已經被類型擦除的類型變成了一個未被擦除的類型的超類型(例如`[T; N] <: [T; _]`),所以它可以接受更多的對象。
+類型的對象`[T; N]` 當然可以使用 `[T; _]`,但使用后會刪除`N`信息。如果長度沒有改變,那么可以使用`[T; N]` 在簽名中。如果長度保持不變,則必須由簽名指示。
+
+```python
+# 保證不改變數組長度的函數(例如,排序)
+f: [T; N] -> [T; N] # 沒有的函數 (f: [T; N])
+# 沒有的功能(例如過濾器)
+g: [T; n] -> [T; _]
+```
+
+如果您在類型規范本身中使用 `_`,則類型將向上轉換為 `Object`。
+對于非類型類型參數(Int、Bool 等),帶有 `_` 的參數將是未定義的。
+
+```python
+i: _ # i: Object
+[_; _] == [Object; _] == Array
+```
+
+類型擦除與省略類型說明不同。 一旦類型參數信息被刪除,除非您再次聲明它,否則它不會被返回。
+
+```python
+implicit = (1..5).iter().map(i -> i * 2).to_arr()
+explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat))
+```
+
+在 Rust 中,這對應于以下代碼:
+
+```rust
+let partial = (1..6).iter().map(|i| i * 2).collect::>();
+```
+
+Erg 不允許部分省略類型,而是使用高階種類多態性。
+
+```python
+# collect 是采用 Kind 的高階 Kind 方法
+hk = (1..5).iter().map(i -> i * 2).collect(Array)
+hk: Array(Int)
+```
diff --git a/doc/zh_TW/syntax/type/advanced/existential.md b/doc/zh_TW/syntax/type/advanced/existential.md
new file mode 100644
index 00000000..b26f02ab
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/existential.md
@@ -0,0 +1,43 @@
+# 存在類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/existential.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+如果存在對應于?的for-all類型,那么很自然地假設存在對應于?的存在類型。
+存在類型并不難。 你已經知道存在類型,只是沒有意識到它本身。
+
+```python
+T: Trait
+f x: T = ...
+```
+
+上面的 trait `T` 被用作存在類型。
+相比之下,小寫的`T`只是一個特征,`X`是一個for-all類型。
+
+```python
+f|X <: T| x: X = ...
+```
+
+事實上,existential 類型被 for-all 類型所取代。 那么為什么會有存在類型這樣的東西呢?
+首先,正如我們在上面看到的,存在類型不涉及類型變量,這簡化了類型規范。
+此外,由于可以刪除類型變量,因此如果它是一個全推定類型,則可以構造一個等級為 2 或更高的類型。
+
+```python
+show_map f: (|T| T -> T), arr: [Show; _] =
+ arr.map x ->
+ y = f x
+ log y
+ y
+```
+
+但是,如您所見,existential 類型忘記或擴展了原始類型,因此如果您不想擴展返回類型,則必須使用 for-all 類型。
+相反,僅作為參數且與返回值無關的類型可以寫為存在類型。
+
+```python
+# id(1): 我希望它是 Int
+id|T|(x: T): T = x
+# |S <: Show|(s: S) -> () 是多余的
+show(s: Show): () = log s
+```
+
+順便說一句,類不稱為存在類型。 一個類不被稱為存在類型,因為它的元素對象是預定義的。
+存在類型是指滿足某種特征的任何類型,它不是知道實際分配了什么類型的地方。
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced/keyword_param.md b/doc/zh_TW/syntax/type/advanced/keyword_param.md
new file mode 100644
index 00000000..0fe2254a
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/keyword_param.md
@@ -0,0 +1,28 @@
+# 帶有關鍵字參數的函數類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/keyword_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+```python
+h(f) = f(y: 1, x: 2)
+h: |T: type|((y: Int, x: Int) -> T) -> T
+```
+
+帶有關鍵字參數的函數的子類型化規則如下。
+
+```python
+((x: T, y: U) -> V) <: ((T, U) -> V) # x, y 為任意關鍵字參數
+((y: U, x: T) -> V) <: ((x: T, y: U) -> V)
+((x: T, y: U) -> V) <: ((y: U, x: T) -> V)
+```
+
+這意味著可以刪除或替換關鍵字參數。
+但是你不能同時做這兩件事。
+也就是說,您不能將 `(x: T, y: U) -> V` 轉換為 `(U, T) -> V`。
+請注意,關鍵字參數僅附加到頂級元組,而不附加到數組或嵌套元組。
+
+```python
+Valid: [T, U] -> V
+Invalid: [x: T, y: U] -> V
+Valid: (x: T, ys: (U,)) -> V
+Invalid: (x: T, ys: (y: U,)) -> V
+```
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced/kind.md b/doc/zh_TW/syntax/type/advanced/kind.md
new file mode 100644
index 00000000..c8c151c2
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/kind.md
@@ -0,0 +1,149 @@
+# Kind
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/kind.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+一切都在 Erg 中輸入。類型本身也不例外。 __kind__ 表示“類型的類型”。例如,`Int` 屬于 `Type`,就像 `1` 屬于 `Int`。 `Type` 是最簡單的一種,__atomic kind__。在類型論符號中,`Type` 對應于 `*`。
+
+在Kind的概念中,實際上重要的是一種或多種Kind(多項式Kind)。單項類型,例如`Option`,屬于它。一元Kind表示為 `Type -> Type` [1 ](#1)。諸如 `Array` 或 `Option` 之類的 __container__ 特別是一種以類型作為參數的多項式類型。
+正如符號 `Type -> Type` 所表明的,`Option` 實際上是一個接收類型 `T` 并返回類型 `Option T` 的函數。但是,由于這個函數不是通常意義上的函數,所以通常稱為一元類。
+
+注意`->`本身,它是一個匿名函數操作符,當它接收一個類型并返回一個類型時,也可以看作是一Kind型。
+
+另請注意,不是原子Kind的Kind不是類型。正如 `-1` 是一個數字但 `-` 不是,`Option Int` 是一個類型但 `Option` 不是。 `Option` 等有時被稱為類型構造函數。
+
+```python
+assert not Option in Type
+assert Option in Type -> Type
+```
+
+所以像下面這樣的代碼會報錯:
+在 Erg 中,方法只能在原子類型中定義,并且名稱 `self` 不能在方法的第一個參數以外的任何地方使用。
+
+```python
+#K 是一元類型
+K: Type -> Type
+K T = Class...
+K.
+foo x = ... # OK,這就像是所謂的靜態方法
+ bar self, x = ... # 類型錯誤: 無法為非類型對象定義方法
+K(T).
+ baz self, x = ... # OK
+```
+
+二進制或更高類型的示例是 `{T: U}`(: `(Type, Type) -> Type`), `(T, U, V)`(: `(Type, Type, Type) - > Type `), ... 等等。
+
+還有一個零項類型`() -> Type`。 這有時等同于類型論中的原子類型,但在 Erg 中有所區別。 一個例子是`類`。
+
+```python
+Nil = Class()
+```
+
+## 收容類
+
+多項類型之間也存在部分類型關系,或者更確切地說是部分類型關系。
+
+```python
+K T = ...
+L = Inherit K
+L<: K
+```
+
+也就是說,對于任何 `T`,如果 `L T <: K T`,則 `L <: K`,反之亦然。
+
+```python
+?T. L T <: K T <=> L <: K
+```
+
+## 高階Kind
+
+還有一種高階Kind。 這是一種與高階函數相同的概念,一種自身接收一種類型。 `(Type -> Type) -> Type` 是一種更高的Kind。 讓我們定義一個屬于更高Kind的對象。
+
+```python
+IntContainerOf K: Type -> Type = K Int
+assert IntContainerOf Option == Option Int
+assert IntContainerOf Result == Result Int
+assert IntContainerOf in (Type -> Type) -> Type
+```
+
+多項式類型的有界變量通常表示為 K, L, ...,其中 K 是 Kind 的 K
+
+## 設置Kind
+
+在類型論中,有記錄的概念。 這與 Erg 記錄 [2 ](#2) 幾乎相同。
+
+```python
+# 這是一條記錄,對應于類型論中所謂的記錄
+{x = 1; y = 2}
+```
+
+當所有的記錄值都是類型時,它是一種類型,稱為記錄類型。
+
+```python
+assert {x = 1; y = 2} in {x = Int; y = Int}
+```
+
+記錄類型鍵入記錄。 一個好的猜測者可能認為應該有一個“記錄類型”來鍵入記錄類型。 實際上它是存在的。
+
+```python
+log Typeof {x = Int; y = Int} # {{x = Int; y = Int}}
+```
+
+像 `{{x = Int; 這樣的類型 y = Int}}` 是一種記錄類型。 這不是一個特殊的符號。 它只是一個枚舉類型,只有 `{x = Int; y = Int}` 作為一個元素。
+
+```python
+Point = {x = Int; y = Int}
+Pointy = {Point}
+```
+
+記錄類型的一個重要屬性是,如果 `T: |T|` 和 `U <: T` 則 `U: |T|`。
+從枚舉實際上是篩子類型的語法糖這一事實也可以看出這一點。
+
+```python
+# {c} == {X: T | X == c} 對于普通對象,但是不能為類型定義相等性,所以 |T| == {X | X <: T}
+{Point} == {P | P <: Point}
+```
+
+類型約束中的 `U <: T` 實際上是 `U: |T|` 的語法糖。
+作為此類類型的集合的種類通常稱為集合種類。 Setkind 也出現在迭代器模式中。
+
+```python
+Iterable T = Trait {
+ .Iterator = {Iterator}
+ .iter = Self(T).() -> Self.Iterator T
+}
+```
+
+## 多項式類型的類型推斷
+
+```python
+Container K: Type -> Type, T: Type = Patch K(T, T)
+Container (K).
+ f self = ...
+Option T: Type = Patch T or NoneType
+Option(T).
+ f self = ...
+Fn T: Type = Patch T -> T
+Fn(T).
+ f self = ...
+Fn2 T, U: Type = Patch T -> U
+Fn2(T, U).
+ f self = ...
+
+(Int -> Int).f() # 選擇了哪一個?
+```
+在上面的示例中,方法 `f` 會選擇哪個補丁?
+天真,似乎選擇了`Fn T`,但是`Fn2 T,U`也是可以的,`Option T`原樣包含`T`,所以任何類型都適用,`Container K,T`也匹配`->(Int, Int)`,即 `Container(`->`, Int)` 為 `Int -> Int`。因此,上述所有四個修復程序都是可能的選擇。
+
+在這種情況下,根據以下優先標準選擇修復程序。
+
+* 任何 `K(T)`(例如 `T or NoneType`)優先匹配 `Type -> Type` 而不是 `Type`。
+* 任何 `K(T, U)`(例如 `T -> U`)優先匹配 `(Type, Type) -> Type` 而不是 `Type`。
+* 類似的標準適用于種類 3 或更多。
+* 選擇需要較少類型變量來替換的那個。例如,`Int -> Int` 是 `T -> T` 而不是 `K(T, T)`(替換類型變量:K, T)或 `T -> U`(替換類型變量:T, U )。(替換類型變量:T)優先匹配。
+* 如果更換的次數也相同,則報錯為不可選擇。
+
+---
+
+1 在類型理論符號中,`*=>*` [?](#f1)
+
+2 可見性等細微差別。[?](#f2)
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced/marker_trait.md b/doc/zh_TW/syntax/type/advanced/marker_trait.md
new file mode 100644
index 00000000..88f13c49
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/marker_trait.md
@@ -0,0 +1,33 @@
+# 標記特征
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/marker_trait.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+標記特征是沒有必需屬性的特征。 也就是說,您可以在不實現任何方法的情況下實現 Impl。
+沒有 required 屬性似乎沒有意義,但由于注冊了它屬于 trait 的信息,因此可以使用 patch 方法或由編譯器進行特殊處理。
+
+所有標記特征都包含在“標記”特征中。
+作為標準提供的“光”是一種標記特征。
+
+```python
+Light = Subsume Marker
+```
+
+```python
+Person = Class {.name = Str; .age = Nat} and Light
+```
+
+```python
+M = Subsume Marker
+
+MarkedInt = Inherit Int, Impl := M
+
+i = MarkedInt.new(2)
+assert i + 1 == 2
+assert i in M
+```
+
+標記類也可以使用 `Excluding` 參數排除。
+
+```python
+NInt = Inherit MarkedInt, Impl := N, Excluding: M
+```
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced/mut_struct.md b/doc/zh_TW/syntax/type/advanced/mut_struct.md
new file mode 100644
index 00000000..ea383304
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/mut_struct.md
@@ -0,0 +1,42 @@
+# 可變結構類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/mut_struct.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+`T!` 類型被描述為可以被任何 `T` 類型對象替換的盒子類型。
+
+```python
+Particle!State: {"base", "excited"}! = Class(... Impl := Phantom State)
+Particle!
+ # 此方法將狀態從“base”移動到“excited”
+ apply_electric_field!(ref! self("base" ~> "excited"), field: Vector) = ...
+```
+
+`T!` 類型可以替換數據,但不能改變其結構。
+更像是一個真實程序的行為,它不能改變它的大小(在堆上)。 這樣的類型稱為不可變結構(mutable)類型。
+
+事實上,有些數據結構不能用不變的結構類型來表示。
+例如,可變長度數組。 `[T; N]!`類型可以包含任何`[T; N]`,但不能被`[T; N+1]` 等等。
+
+換句話說,長度不能改變。 要改變長度,必須改變類型本身的結構。
+
+這是通過可變結構(可變)類型實現的。
+
+```python
+v = [Str; !0].new()
+v.push! "Hello"
+v: [Str; !1].
+```
+
+對于可變結構類型,可變類型參數用 `!` 標記。 在上述情況下,類型 `[Str; !0]` 可以更改為 `[Str; !1]` 等等。 即,可以改變長度。
+順便說一句,`[T; !N]` 類型是 `ArrayWithLength!(T, !N)` 類型的糖衣語法。
+
+可變結構類型當然可以是用戶定義的。 但是請注意,在構造方法方面與不變結構類型存在一些差異。
+
+```python
+Nil T = Class(Impl := Phantom T)
+List T, !0 = Inherit Nil T
+List T, N: Nat! = Class {head = T; rest = List(T, !N-1)}
+List(T, !N).
+ push! ref! self(N ~> N+1, ...), head: T =
+ self.update! old -> Self.new {head; old}
+```
diff --git a/doc/zh_TW/syntax/type/advanced/newtype.md b/doc/zh_TW/syntax/type/advanced/newtype.md
new file mode 100644
index 00000000..2b2435d5
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/newtype.md
@@ -0,0 +1,33 @@
+# 新類型模式
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/newtype.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+這是 Rust 中常用的 newtype 模式的 Erg 版本。
+
+Erg 允許定義類型別名如下,但它們只引用相同的類型。
+
+```python
+UserID = Int
+```
+
+因此,例如,如果你有一個規范,類型為 `UserId` 的數字必須是一個正的 8 位數字,你可以輸入 `10` 或 `-1`,因為它與類型 `Int` 相同 . 如果設置為 `Nat`,則可以拒絕 `-1`,但 8 位數字的性質不能僅用 Erg 的類型系統來表達。
+
+此外,例如,在設計數據庫系統時,假設有幾種類型的 ID:用戶 ID、產品 ID、產品 ID 和用戶 ID。 如果 ID 類型的數量增加,例如用戶 ID、產品 ID、訂單 ID 等,可能會出現將不同類型的 ID 傳遞給不同函數的 bug。 即使用戶 ID 和產品 ID 在結構上相同,但它們在語義上是不同的。
+
+對于這種情況,newtype 模式是一個很好的設計模式。
+
+```python
+UserId = Class {id = Nat}
+UserId.
+ new id: Nat =
+ assert id.dights().len() == 8, else: "UserId 必須是長度為 8 的正數"
+ UserId::__new__ {id;}
+
+i = UserId.new(10000000)
+print! i # <__main__.UserId object>
+i + UserId.new(10000001) # TypeError: + is not implemented between `UserId` and `UserId
+```
+
+構造函數保證 8 位數字的前置條件。
+`UserId` 失去了 `Nat` 擁有的所有方法,所以每次都必須重新定義必要的操作。
+如果重新定義的成本不值得,最好使用繼承。 另一方面,在某些情況下,方法丟失是可取的,因此請根據情況選擇適當的方法。
diff --git a/doc/zh_TW/syntax/type/advanced/overloading.md b/doc/zh_TW/syntax/type/advanced/overloading.md
new file mode 100644
index 00000000..10a7c651
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/overloading.md
@@ -0,0 +1,91 @@
+# 重載
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/overloading.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Erg 不支持 __ad hoc 多態性__。 也就是說,函數和種類(重載)的多重定義是不可能的。 但是,您可以通過使用特征和補丁的組合來重現重載行為。
+您可以使用特征而不是特征類,但隨后將涵蓋所有實現 `.add1` 的類型。
+
+```python
+Add1 = Trait {
+ .add1: Self.() -> Self
+}
+IntAdd1 = Patch Int, Impl := Add1
+IntAdd1.
+ add1 self = self + 1
+RatioAdd1 = Patch Ratio, Impl := Add1
+RatioAdd1.
+ add1 self = self + 1.0
+
+add1|X <: Add1| x: X = x.add1()
+assert add1(1) == 2
+assert add1(1.0) == 2.0
+```
+
+這種接受一個類型的所有子類型的多態稱為__subtyping polymorphism__。
+
+如果每種類型的過程完全相同,則可以編寫如下。 當行為從類到類(但返回類型相同)時,使用上述內容。
+使用類型參數的多態稱為 __parametric polymorphism__。 參數多態性通常與子類型結合使用,如下所示,在這種情況下,它是參數和子類型多態性的組合。
+
+```python
+add1|T <: Int or Str| x: T = x + 1
+assert add1(1) == 2
+assert add1(1.0) == 2.0
+```
+
+此外,可以使用默認參數重現具有不同數量參數的類型的重載。
+
+```python
+C = Class {.x = Int; .y = Int}
+C.
+ new(x, y := 0) = Self::__new__ {.x; .y}
+
+assert C.new(0, 0) == C.new(0)
+```
+
+Erg 的立場是,您不能定義行為完全不同的函數,例如根據參數的數量具有不同的類型,但如果行為不同,則應該以不同的方式命名。
+
+綜上所述,Erg 禁止重載,采用子類型加參數多態,原因如下。
+
+首先,重載函數分布在它們的定義中。 這使得在發生錯誤時很難報告錯誤的原因。
+此外,導入子程序可能會改變已定義子程序的行為。
+
+```python
+{id; ...} = import "foo"
+...
+id x: Int = x
+...
+id x: Ratio = x
+...
+id "str" # 類型錯誤:沒有為 Str 實現 id
+# 但是……但是……這個錯誤是從哪里來的?
+```
+
+其次,它與默認參數不兼容。 當具有默認參數的函數被重載時,會出現一個優先級的問題。
+
+```python
+f x: Int = ...
+f(x: Int, y := 0) = ...
+
+f(1) # 選擇哪個?
+```
+
+此外,它與聲明不兼容。
+聲明 `f: Num -> Num` 不能指定它引用的定義。 這是因為 `Int -> Ratio` 和 `Ratio -> Int` 不包含在內。
+
+```python
+f: Num -> Num
+f(x: Int): Ratio = ...
+f(x: Ratio): Int = ...
+```
+
+并且語法不一致:Erg禁止變量重新賦值,但是重載的語法看起來像重新賦值。
+也不能用匿名函數代替。
+
+```python
+# 同 `f = x -> body`
+f x = body
+
+# 一樣……什么?
+f x: Int = x
+f x: Ratio = x
+```
diff --git a/doc/zh_TW/syntax/type/advanced/phantom.md b/doc/zh_TW/syntax/type/advanced/phantom.md
new file mode 100644
index 00000000..f83b8d02
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/phantom.md
@@ -0,0 +1,58 @@
+# 幻影(phantom)類
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/phantom.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+幻像類型是標記特征,其存在僅用于向編譯器提供注釋。
+作為幻像類型的一種用法,讓我們看一下列表的結構。
+
+```python
+Nil = Class()
+List T, 0 = Inherit Nil
+List T, N: Nat = Class {head = T; rest = List(T, N-1)}
+```
+
+此代碼導致錯誤。
+
+```python
+3 | List T, 0 = Inherit Nil
+ ^^^
+類型構造錯誤:由于Nil沒有參數T,所以無法用Nil構造List(T, 0)
+提示:使用 'Phantom' 特質消耗 T
+```
+
+此錯誤是在使用 `List(_, 0).new Nil.new()` 時無法推斷 `T` 的抱怨。
+在這種情況下,無論 `T` 類型是什么,它都必須在右側使用。 大小為零的類型(例如長度為零的元組)很方便,因為它沒有運行時開銷。
+```python
+Nil T = Class((T; 0))
+List T, 0 = Inherit Nil T
+List T, N: Nat = Class {head = T; rest = List(T, N-1)}
+```
+
+此代碼通過編譯。 但是理解意圖有點棘手,除非類型參數是類型,否則不能使用它。
+
+在這種情況下,幻影類型正是您所需要的。 幻像類型是大小為 0 的廣義類型。
+
+```python
+Nil T = Class(Impl := Phantom T)
+List T, 0 = Inherit Nil T
+List T, N: Nat = Class {head = T; rest = List(T, N-1)}
+
+nil = Nil(Int).new()
+assert nil.__size__ == 0
+```
+
+`Phantom` 擁有`T` 類型。 但實際上 `Phantom T` 類型的大小是 0 并且不包含 `T` 類型的對象。
+
+此外,`Phantom` 可以使用除其類型之外的任意類型參數。 在下面的示例中,`Phantom` 包含一個名為 `State` 的類型參數,它是 `Str` 的子類型對象。
+同樣,`State` 是一個假的類型變量,不會出現在對象的實體中。
+
+```python
+VM! State: {"stopped", "running"}! = Class(... State)
+VM!("stopped").
+ start ref! self("stopped" ~> "running") =
+ self.do_something!()
+ self::set_phantom!("running"))
+```
+
+`state` 是通過 `update_phantom!` 或 `set_phantom!` 方法更新的。
+這是標準補丁為`Phantom!`(`Phantom`的變量版本)提供的方法,其用法與變量`update!`和`set!`相同。
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced/projection.md b/doc/zh_TW/syntax/type/advanced/projection.md
new file mode 100644
index 00000000..d8661882
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/projection.md
@@ -0,0 +1,26 @@
+# 投影類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/projection.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+投影類型表示如下代碼中的“Self.AddO”等類型。
+
+```python
+Add R = Trait {
+ . `_+_` = Self, R -> Self.AddO
+ .AddO = Type
+}
+
+AddForInt = Patch(Int, Impl := Add Int)
+AddForInt.
+ AddO = Int
+```
+
+類型“Add(R)”可以說是定義了與某個對象的加法的類型。 由于方法應該是一個類型屬性,`+` 類型聲明應該寫在縮進下面。
+`Add` 類型的場景是聲明 `.AddO = Type`,而 `.AddO` 類型的實體是一個投影類型,由一個作為 ` 子類型的類型持有 添加`。 例如,`Int.AddO = Int`、`Odd.AddO = Even`。
+
+```python
+assert Int < Add
+assert Int.AddO == Int
+assert Odd < Add
+assert Odd.AddO == Even
+```
diff --git a/doc/zh_TW/syntax/type/advanced/quantified_dependent.md b/doc/zh_TW/syntax/type/advanced/quantified_dependent.md
new file mode 100644
index 00000000..aecbe76e
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/quantified_dependent.md
@@ -0,0 +1,29 @@
+# 量化依賴類型
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/quantified_dependent.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+Erg 有量化和依賴類型。 那么很自然地,就可以創建一個將兩者結合起來的類型。 那是量化的依賴類型。
+
+```python
+NonNullStr = |N: Nat| StrWithLen N | N ! = 0 # 同 {S | N: Nat; S: StrWithLen N; N ! = 0}
+NonEmptyArray = |N: Nat| [_; N | N > 0] # 同 {A | N: Nat; A: Array(_, N); N > 0}
+```
+
+量化依賴類型的標準形式是“K(A, ... | Pred)”。 `K` 是類型構造函數,`A, B` 是類型參數,`Pred` 是條件表達式。
+
+作為左值的量化依賴類型只能在與原始類型相同的模塊中定義方法。
+
+```python
+K A: Nat = Class ...
+K(A).
+ ...
+K(A | A >= 1).
+ method ref! self(A ~> A+1) = ...
+```
+
+作為右值的量化依賴類型需要在類型變量列表 (`||`) 中聲明要使用的類型變量。
+
+```python
+# T 是具體類型
+a: |N: Nat| [T; N | N > 1]
+```
diff --git a/doc/zh_TW/syntax/type/advanced/shared.md b/doc/zh_TW/syntax/type/advanced/shared.md
new file mode 100644
index 00000000..7be09ecc
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/shared.md
@@ -0,0 +1,74 @@
+# 共享參考
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/shared.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+共享引用是必須小心處理的語言特性之一。
+例如,在 TypeScript 中,以下代碼將通過類型檢查。
+
+```typescript
+class NormalMember {}
+class VIPMember extends NormalMember {}
+
+let vip_area: VIPMember[] = []
+let normal_area: NormalMember[] = vip_area
+
+normal_area.push(new NormalMember())
+console.log(vip_area) # [NormalMember]
+```
+
+一個 NormalMember 已進入 vip_area。 這是一個明顯的錯誤,但是出了什么問題?
+原因是共享引用 [denatured](./variance.md)。 `normal_area` 是通過復制 `vip_area` 來創建的,但是這樣做的時候類型已經改變了。
+但是 `VIPMember` 繼承自 `NormalMember`,所以 `VIPMember[] <: NormalMember[]`,這不是問題。
+關系 `VIPMember[] <: NormalMember[]` 適用于不可變對象。 但是,如果您執行上述破壞性操作,則會出現故障。
+
+在 Erg 中,由于所有權系統,此類代碼會被回放。
+
+```python
+NormalMember = Class()
+VIPMember = Class()
+
+vip_area = [].into [VIPMember; !_]
+normal_area: [NormalMember; !_] = vip_area
+
+normal_area.push!(NormalMember.new())
+log vip_area # 所有權錯誤:`vip_room` 已移至 `normal_room`
+```
+
+然而,一個對象只屬于一個地方可能會很不方便。
+出于這個原因,Erg 有一個類型 `SharedCell!T!`,它代表一個共享狀態。
+
+```python
+$p1 = SharedCell!.new(!1)
+$p2 = $p1.mirror!()
+$p3 = SharedCell!.new(!1)
+# 如果$p1 == $p2,比較內容類型Int!
+assert $p1 == $p2
+assert $p1 == $p3
+# 檢查 $p1 和 $p2 是否用 `.addr!` 指向同一個東西。
+assert $p1.addr!() == $p2.addr!()
+assert $p1.addr!() != $p3.addr!()
+$p1.add! 1
+assert $p1 == 2
+assert $p2 == 2
+assert $p3 == 1
+```
+
+`SharedCell!` 類型的對象必須以`$` 為前綴。 此外,就其性質而言,它們不可能是常數。
+
+`SharedCell! T!` 類型也是 `T!` 的子類型,可以調用 `T!` 類型的方法。 `SharedCell!T!` 類型特有的唯一方法是 `.addr!`、`.mirror!` 和 `.try_take`。
+
+一個重要的事實是`SharedCell! T!` 是非變體的,即沒有為不同類型的參數定義包含。
+
+```python
+$vip_area = SharedCell!.new([].into [VIPMember; !_])
+$normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() #類型錯誤:預期 SharedCell!([NormalMember;!_]),但得到 SharedCell!([VIPMember;!_])
+# 提示:SharedCell!(T) 是非變體的,這意味著它不能有超類型或子類型。
+```
+
+但是,下面的代碼沒有問題。 在最后一行,它是 `VIPMember` 參數已被類型轉換
+
+```python
+$normal_area = SharedCell!.new([].into [NormalMember; !_])
+$normal_area.push!(NormalMember.new()) # OK
+$normal_area.push!(VIPMember.new()) # OK
+```
diff --git a/doc/zh_TW/syntax/type/advanced/special.md b/doc/zh_TW/syntax/type/advanced/special.md
new file mode 100644
index 00000000..a79890f1
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/special.md
@@ -0,0 +1,53 @@
+# 特殊類型(Self、Super)
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`Self` 代表它自己的類型。 您可以將其用作別名,但請注意派生類型的含義會發生變化(指的是自己的類型)。
+
+```python
+@Inheritable
+C = Class()
+C.
+ new_self() = Self. new()
+ new_c() = C.new()
+D = Inherit C
+
+classof D. new_self() # D
+classof D. new_c() # C
+```
+
+`Super` 表示基類的類型。方法本身引用基類,但實例使用自己的類型。
+
+```python
+@Inheritable
+C = Class()
+
+D = Inherit(C)
+D.
+ new_super() = Super.new()
+ new_c() = C.new()
+
+classof D. new_super() # D
+classof D. new_c() # C
+```
+
+## 特殊類型變量
+
+`Self` 和 `Super` 可以用作結構化類型和特征中的類型變量。 這指的是作為該類型子類型的類。 也就是說,`T` 類型中的`Self` 表示`Self <: T`。
+
+```python
+Add R = Trait {
+ .AddO = Type
+ .`_+_`: Self, R -> Self.AddO
+}
+ClosedAdd = Subsume Add(Self)
+
+ClosedAddForInt = Patch(Int, Impl := ClosedAdd)
+ClosedAddForInt.
+ AddO = Int
+
+assert 1 in Add(Int, Int)
+assert 1 in ClosedAdd
+assert Int < Add(Int, Int)
+assert Int < ClosedAdd
+```
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced/typeof.md b/doc/zh_TW/syntax/type/advanced/typeof.md
new file mode 100644
index 00000000..ca15b886
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/typeof.md
@@ -0,0 +1,67 @@
+# Typeof, classof
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/typeof.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+`Typeof` 是一個可以窺探 Erg 類型推斷系統的函數,它的行為很復雜
+
+```python
+assert Typeof(1) == {I: Int | I == 1}
+i: 1..3 or 5..10 = ...
+assert Typeof(i) == {I: Int | (I >= 1 and I <= 3) or (I >= 5 and I <= 10)}
+
+C = Class {i = Int}
+I = C. new {i = 1}
+assert Typeof(I) == {X: C | X == I}
+J: C = ...
+assert Typeof(J) == {i = Int}
+
+assert {X: C | X == I} < C and C <= {i = Int}
+```
+
+`Typeof` 函數返回派生類型,而不是對象的類。
+因此,例如 `C = Class T` 類的`I: C`,`Typeof(I) == T`。
+值類沒有對應的記錄類型。 為了解決這個問題,值類應該是具有 `__valueclass_tag__` 屬性的記錄類型。
+請注意,您不能訪問此屬性,也不能在用戶定義的類型上定義 `__valueclass_tag__` 屬性。
+
+```python
+i: Int = ...
+assert Typeof(i) == {__valueclass_tag__ = Phantom Int}
+s: Str = ...
+assert Typeof(s) == {__valueclass_tag__ = Phantom Str}
+```
+
+`Typeof` 僅輸出結構化類型。 我解釋說結構化類型包括屬性類型、篩類型和(真正的)代數類型。
+這些是獨立的類型(存在推理優先級),不會發生推理沖突。
+屬性類型和代數類型可以跨越多個類,而篩類型是單個類的子類型。
+Erg 盡可能將對象類型推斷為篩類型,如果不可能,則將篩基類擴展為結構化類型(見下文)。
+
+## 結構化的
+
+所有類都可以轉換為派生類型。 這稱為 __結構化__。 類的結構化類型可以通過 `Structure` 函數獲得。
+如果一個類是用`C = Class T`定義的(所有類都以這種形式定義),那么`Structure(C) == T`。
+
+```python
+C = Class {i = Int}
+assert Structure(C) == {i = Int}
+D = Inherit C
+assert Structure(D) == {i = Int}
+Nat = Class {I: Int | I >= 0}
+assert Structure(Nat) == {I: Int | I >= 0}
+Option T = Class (T or NoneType)
+assert Structure(Option Int) == Or(Int, NoneType)
+assert Structure(Option) # 類型錯誤:只能構造單態類型
+# 你實際上不能用 __valueclass_tag__ 定義一條記錄,但在概念上
+assert Structure(Int) == {__valueclass_tag__ = Phantom Int}
+assert Structure(Str) == {__valueclass_tag__ = Phantom Str}
+assert Structure((Nat, Nat)) == {__valueclass_tag__ = Phantom(Tuple(Nat, Nat))}
+assert Structure(Nat -> Nat) == {__valueclass_tag__ = Phantom(Func(Nat, Nat))}
+# 標記類也是帶有 __valueclass_tag__ 的記錄類型
+M = Inherit Marker
+assert Structure(M) == {__valueclass_tag__ = Phantom M}
+D = Inherit(C and M)
+assert Structure(D) == {i = Int; __valueclass_tag__ = Phantom M}
+E = Inherit(Int and M)
+assert Structure(E) == {__valueclass_tag__ = Phantom(And(Int, M))}
+F = Inherit(E not M)
+assert Structure(F) == {__valueclass_tag__ = Phantom Int}
+```
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced/variance.md b/doc/zh_TW/syntax/type/advanced/variance.md
new file mode 100644
index 00000000..1124dc38
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/variance.md
@@ -0,0 +1,144 @@
+# 變化
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/variance.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg 可以對多態類型進行子類型化,但有一些注意事項。
+
+首先,考慮普通多態類型的包含關系。一般來說,有一個容器`K`和它分配的類型`A,B`,當`A < B`時,`K A < K B`。
+例如,`Option Int < Option Object`。因此,在`Option Object`中定義的方法也可以在`Option Int`中使用。
+
+考慮典型的多態類型 `Array!(T)`。
+請注意,這一次不是 `Array!(T, N)` 因為我們不關心元素的數量。
+現在,`Array!(T)` 類型具有稱為 `.push!` 和 `.pop!` 的方法,分別表示添加和刪除元素。這是類型:
+
+`Array.push!: Self(T).(T) => NoneType`
+`Array.pop!: Self(T).() => T`
+
+可以直觀地理解:
+
+* `Array!(Object).push!(s)` is OK when `s: Str` (just upcast `Str` to `Object`)
+* When `o: Object`, `Array!(Str).push!(o)` is NG
+* `Array!(Object).pop!().into(Str)` is NG
+* `Array!(Str).pop!().into(Object)` is OK
+
+就類型系統而言,這是
+
+* `(Self(Object).(Object) => NoneType) < (Self(Str).(Str) => NoneType)`
+* `(Self(Str).() => Str) < (Self(Object).() => Object)`
+方法
+
+前者可能看起來很奇怪。即使是 `Str < Object`,包含關系在將其作為參數的函數中也是相反的。
+在類型論中,這種關系(`.push!` 的類型關系)稱為逆變,反之,`.pop!` 的類型關系稱為協變。
+換句話說,函數類型就其參數類型而言是逆變的,而就其返回類型而言是協變的。
+這聽起來很復雜,但正如我們之前看到的,如果將其應用于實際示例,這是一個合理的規則。
+如果您仍然不明白,請考慮以下內容。
+
+Erg 的設計原則之一是“大輸入類型,小輸出類型”。這正是函數可變性的情況。
+看上面的規則,輸入類型越大,整體類型越小。
+這是因為通用函數明顯比專用函數少。
+而且輸出類型越小,整體越小。
+
+這樣一來,上面的策略就相當于說“盡量減少函數的類型”。
+
+## 不變性
+
+Erg 有另一個修改。它是不變的。
+這是對 `SharedCell! T!`等內置類型的修改。這意味著對于兩種類型 `T!, U!` 其中 `T! != U!`,在 `SharedCell! T!` 和 `SharedCell!意思是
+這是因為`SharedCell! T!` 是共享參考。有關詳細信息,請參閱 [共享參考](shared.md)。
+
+## 變異的泛型類型
+
+通用類型變量可以指定其上限和下限。
+
+```python
+|A <: T| K(A)
+|B :> T| K(B)
+```
+
+在類型變量列表中,執行類型變量的__variant說明__。 在上述變體規范中,類型變量“A”被聲明為“T”類型的任何子類,“B”類型被聲明為“T”類型的任何超類。
+在這種情況下,`T` 也稱為 `A` 的上部類型和 `B` 的下部類型。
+
+突變規范也可以重疊。
+
+```python
+# U U}
+```
+
+這是使用變量規范的代碼示例:
+
+```python
+show|S <: Show| s: S = log s
+
+Nil T = Class(Impl = Phantom T)
+Cons T = Class(Nil T or List T)
+List T = Class {head = T; rest = Cons T}
+List(T).
+ push|U <: T|(self, x: U): List T = Self. new {head = x; rest = self}
+ upcast(self, U :> T): List U = self
+```
+
+## 更改規范
+
+`List T` 的例子很棘手,所以讓我們更詳細一點。
+要理解上面的代碼,你需要了解多態類型退化。 [this section](./variance.md) 中詳細討論了方差,但現在我們需要三個事實:
+
+* 普通的多態類型,例如`List T`,與`T`是協變的(`List U > List T` when `U > T`)
+* 函數 `T -> U` 對于參數類型 `T` 是逆變的(`(S -> U) < (T -> U)` when `S > T`)
+* 函數 `T -> U` 與返回類型 `U` 是協變的(`(T -> U) > (T -> S)` 當 `U > S` 時)
+
+例如,`List Int` 可以向上轉換為 `List Object`,而 `Obj -> Obj` 可以向上轉換為 `Int -> Obj`。
+
+現在讓我們考慮如果我們省略方法的變量說明會發生什么。
+
+```python
+...
+List T = Class {head = T; rest = Cons T}
+List(T).
+ # 如果 T > U,列表 T 可以被推入 U
+ push|U|(self, x: U): List T = Self. new {head = x; rest = self}
+ # List T 可以是 List U 如果 T < U
+ upcast(self, U): List U = self
+```
+
+即使在這種情況下,Erg 編譯器也能很好地推斷 `U` 的上下類型。
+但是請注意,Erg 編譯器不理解方法的語義。編譯器只是根據變量和類型變量的使用方式機械地推斷和派生類型關系。
+
+正如評論中所寫,放在`List T`的`head`中的`U`類型是`T`的子類(`T:Int`,例如`Nat`)。也就是說,它被推斷為 `U <: T`。此約束將 `.push{U}` upcast `(List(T), U) -> List(T) 的參數類型更改為 (List(T), T) -> List(T)`(例如 disallow `列表(整數).push{對象}`)。但是請注意,`U <: T` 約束不會改變函數的類型包含。 `(List(Int), Object) -> List(Int) to (List(Int), Int) -> List(Int)` 的事實并沒有改變,只是在 `.push` 方法中表示強制轉換無法執行。
+類似地,從 `List T` 到?? `List U` 的轉換可能會受到約束 `U :> T` 的約束,因此可以推斷出變體規范。此約束將 `.upcast(U)` 的返回類型更改為向上轉換 `List(T) -> List(T) 到 List(T) -> List(T)`(例如 `List(Object) .upcast(Int )`) 被禁止。
+
+現在讓我們看看如果我們允許這種向上轉換會發生什么。
+讓我們反轉變性名稱。
+
+```python
+...
+List T = Class {head = T; rest = Cons T}
+List(T).
+ push|U :> T|(self, x: U): List T = Self. new {head = x; rest = self}
+ upcast(self, U :> T): List U = self
+# 類型警告:`.push` 中的 `U` 不能接受除 `U == T` 之外的任何內容。 將“U”替換為“T”。
+# 類型警告:`.upcast` 中的 `U` 不能接受除 `U == T` 之外的任何內容。 將“U”替換為“T”。
+```
+
+只有當 `U == T` 時,約束 `U <: T` 和修改規范`U :> T` 才滿足。 所以這個稱號沒有多大意義。
+只有“向上轉換使得 `U == T`” = “向上轉換不會改變 `U` 的位置”實際上是允許的。
+
+##附錄:用戶定義類型的修改
+
+默認情況下,用戶定義類型的突變是不可變的。 但是,您也可以使用 `Inputs/Outputs` 標記特征指定可變性。
+如果您指定 `Inputs(T)`,則類型相對于 `T` 是逆變的。
+如果您指定 `Outputs(T)`,則類型相對于 `T` 是協變的。
+
+```python
+K T = Class(...)
+assert not K(Str) <= K(Object)
+assert not K(Str) >= K(Object)
+
+InputStream T = Class ..., Impl := Inputs(T)
+# 接受Objects的流也可以認為接受Strs
+assert InputStream(Str) > InputStream(Object)
+
+OutputStream T = Class ..., Impl := Outputs(T)
+# 輸出Str的流也可以認為輸出Object
+assert OutputStream(Str) < OutputStream(Object)
+```
\ No newline at end of file
diff --git a/doc/zh_TW/syntax/type/advanced/widening.md b/doc/zh_TW/syntax/type/advanced/widening.md
new file mode 100644
index 00000000..4f8a11b6
--- /dev/null
+++ b/doc/zh_TW/syntax/type/advanced/widening.md
@@ -0,0 +1,94 @@
+# 類型加寬
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/widening.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+例如,定義多相關系數如下。
+
+```python
+ids|T|(x: T, y: T) = x, y
+```
+
+分配同一類的一對實例并沒有錯。
+當您分配另一個具有包含關系的類的實例對時,它會向上轉換為較大的類并成為相同的類型。
+另外,很容易理解,如果分配了另一個不在包含關系中的類,就會發生錯誤。
+
+```python
+assert ids(1, 2) == (1, 2)
+assert ids(1, 2.0) == (1.0, 2.0)
+ids(1, "a") #TypeError
+```
+
+現在,具有不同派生類型的類型呢?
+
+```python
+i: Int or Str
+j: Int or NoneType
+ids(i, j) # ?
+```
+
+在解釋這一點之前,我們必須關注 Erg 的類型系統實際上并不關注(運行時)類這一事實。
+
+```python
+1: {__valueclass_tag__ = Phantom Int}
+2: {__valueclass_tag__ = Phantom Int}
+2.0: {__valueclass_tag__ = Phantom Ratio}
+"a": {__valueclass_tag__ = Phantom Str}
+ids(1, 2): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Int} == {__valueclass_tag__ = Phantom Int}
+ids(1, 2.0): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Ratio} == {__valueclass_tag__ = Phantom Ratio} # Int < Ratio
+ids(1, "a"): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Str} == Never # 類型錯誤
+```
+
+我看不到該類,因為它可能無法準確看到,因為在 Erg 中,對象的類屬于運行時信息。
+例如,一個`Int`或Str`類型的對象的類是`Int`或`Str`,但你只有通過執行才能知道它是哪一個。
+當然,`Int` 類型的對象的類被定義為 `Int`,但是在這種情況下,從類型系統中可見的是 `Int` 的結構類型 `{__valueclass_tag__ = Int}`。
+
+現在讓我們回到另一個結構化類型示例。 總之,上述代碼將導致類型錯誤,因為類型不匹配。
+但是,如果您使用類型注釋進行類型擴展,編譯將通過。
+
+```python
+i: Int or Str
+j: Int or NoneType
+ids(i, j) # 類型錯誤:i 和 j 的類型不匹配
+# 提示:嘗試擴大類型(例如 ids)
+ids(i, j) # OK
+```
+
+`A 和 B` 有以下可能性。
+
+* `A and B == A`:當`A <: B`或`A == B`時。
+* `A and B == B`:當 `A :> B` 或 `A == B` 時。
+* `A and B == {}`:當 `!(A :> B)` 和 `!(A <: B)` 時。
+
+`A 或 B` 具有以下可能性。
+
+* `A 或 B == A`:當`A :> B` 或`A == B` 時。
+* `A or B == B`:當`A <: B`或`A == B`時。
+* `A 或 B` 是不可約的(獨立類型):如果 `!(A :> B)` 和 `!(A <: B)`。
+
+## 子程序定義中的類型擴展
+
+如果返回類型不匹配,Erg 默認會出錯。
+
+```python
+parse_to_int s: Str =
+ if not s.is_numeric():
+ do parse_to_int::return error("not numeric")
+... # 返回 Int 對象
+# 類型錯誤:返回值類型不匹配
+# 3 | 做 parse_to_int::return error("not numeric")
+# └─ Error
+# 4 | ...
+# └ Int
+```
+
+為了解決這個問題,需要將返回類型顯式指定為 Or 類型
+
+```python
+parse_to_int(s: Str): Int or Error =
+ if not s.is_numeric():
+ do parse_to_int::return error("not numeric")
+ ... # 返回 Int 對象
+```
+
+這是設計使然,這樣您就不會無意中將子例程的返回類型與另一種類型混合。
+但是,如果返回值類型選項是具有包含關系的類型,例如 `Int` 或 `Nat`,它將與較大的對齊。
\ No newline at end of file
diff --git a/doc/zh_TW/tips.md b/doc/zh_TW/tips.md
new file mode 100644
index 00000000..56d8f484
--- /dev/null
+++ b/doc/zh_TW/tips.md
@@ -0,0 +1,137 @@
+# 提示
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tips.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258)
+
+## 想要更改顯示錯誤的語言
+
+請為您的語言下載 Erg。
+但是,外部庫可能不支持多種語言。
+
+## 只想更改記錄的某些屬性
+
+```python
+record: {.name = Str; .age = Nat; .height = CentiMeter}
+{height; rest; ...} = record
+mut_record = {.height = !height; ...rest}
+```
+
+## 想要隱藏變量
+
+使用 Erg 無法在相同范圍內進行遮蔽。 但是,如果范圍發生變化,您可以重新定義它們(這是一種稱為實例塊的語法)。
+
+````python
+## 獲取一個 T!-type 對象,最后將它作為 T 類型賦值給一個變量
+x: T =
+ x: T! = foo()
+ x.bar!()
+ x.freeze()
+````
+
+## 想以某種方式重用最終類(不可繼承的類)
+
+您可以創建一個包裝類。 這就是所謂的構圖模式。
+
+```python
+FinalWrapper = Class {inner = FinalClass}
+FinalWrapper.
+ method self =
+ self::inner.method()
+ ...
+```
+
+## 想使用不是字符串的枚舉類型
+
+可以定義其他語言中常見的傳統枚舉類型(代數數據類型)如下
+如果您實現“單例”,則類和實例是相同的。
+此外,如果您使用 `Enum`,則選擇的類型會自動定義為重定向屬性。
+
+```python
+Ok = Class Impl := Singleton
+Err = Class Impl := Singleton
+ErrWithInfo = Inherit {info = Str}
+Status = Enum Ok, Err, ErrWithInfo
+stat: Status = Status.cons(ErrWithInfo) {info = "error caused by ..."}
+match! stat:
+ Status.Ok -> ...
+ Status.Err -> ...
+ Status.ErrWithInfo::{info} -> ...
+```
+
+```python
+Status = Enum Ok, Err, ErrWithInfo
+# 相當于
+Status = Class Ok or Err or ErrWithInfo
+Status.
+ Ok = Ok
+ Err = Err
+ ErrWithInfo = ErrWithInfo
+```
+
+## 我想在1開頭枚舉
+
+方法一:
+
+```python
+arr = [...]
+for! arr.iter().enumerate(start: 1), i =>
+ ...
+```
+
+method 2:
+
+```python
+arr = [...]
+for! arr.iter().zip(1...) , i =>
+ ...
+```
+
+## 想要測試一個(白盒)非公共 API
+
+`foo.er` 中的私有 API 可在 `foo.test.er` 模塊中特別訪問。
+`foo.test.er` 模塊無法導入,因此它保持隱藏狀態。
+
+```python
+# foo.er
+private x = ...
+```
+
+```python
+# foo.test.er
+foo = import "foo"
+
+@Test
+'testing private' x =
+ ...
+ y = foo::private x
+ ...
+```
+
+## 想定義一個從外部只讀的(變量)屬性
+
+您可以將屬性設為私有并定義一個 getter。
+
+```python
+C = Class {v = Int!}
+C::
+ inc_v!(ref! self) = self::v.inc!()
+ ...
+C.
+ get_v(ref self): Int = self::v.freeze()
+ ...
+```
+
+## 希望在類型系統上識別參數名稱
+
+您可以按記錄接收參數。
+
+```python
+Point = {x = Int; y = Int}
+
+norm: Point -> Int
+norm({x: Int; y: Int}): Int = x**2 + y**2
+assert norm({x = 1; y = 2}) == norm({y = 2; x = 1})
+```
+
+## 想要停止警告
+
+Erg 中沒有停止警告的選項(這是設計使然)。 請重寫你的代碼。
diff --git a/doc/zh_TW/tools/build.md b/doc/zh_TW/tools/build.md
new file mode 100644
index 00000000..bbc7fa5a
--- /dev/null
+++ b/doc/zh_TW/tools/build.md
@@ -0,0 +1,16 @@
+# 構建子命令
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/build.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+build 子命令構建包。
+默認構建中執行的步驟如下:
+
+1. 檢查注釋/文檔中的代碼(doc 下的 md 文件)
+2. 編譯打包所需的代碼。
+3. 對于應用程序包,生成批處理文件或相當于命令的shell腳本。
+4. 運行測試。
+
+構建完成后的交付物輸出到以下目錄。
+
+* 在調試構建期間:build/debug
+* 對于發布構建:build/release
\ No newline at end of file
diff --git a/doc/zh_TW/tools/env.md b/doc/zh_TW/tools/env.md
new file mode 100644
index 00000000..933ff187
--- /dev/null
+++ b/doc/zh_TW/tools/env.md
@@ -0,0 +1,9 @@
+# 環境子命令
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+env 子命令指定 erg 執行環境。
+使用 `erg env new [env name]` 創建一個新的執行環境。 將打開一個交互式工具,當您指定 erg 版本時,將安裝該版本的 erg(如果已存在,將使用它),您將能夠將其用作新環境。
+您可以使用 `erg env switch [env name]` 切換環境。
+可以使用 `erg env edit` 編輯創建的環境以預安裝軟件包并指定其他語言的依賴項。
+該命令最大的特點是`erg env export`可以將重現環境的信息輸出為`[env name].env.er`文件。 這使您可以立即開始在與其他人相同的環境中進行開發。 此外,`erg env publish` 可以像包一樣發布環境。
\ No newline at end of file
diff --git a/doc/zh_TW/tools/fmt.md b/doc/zh_TW/tools/fmt.md
new file mode 100644
index 00000000..4f73844c
--- /dev/null
+++ b/doc/zh_TW/tools/fmt.md
@@ -0,0 +1,8 @@
+# fmt
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/fmt.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+可以使用 fmt 子命令來完成代碼格式化。
+常用的標志有:
+
+* 顯式類型:在省略類型說明的情況下自動完成。
\ No newline at end of file
diff --git a/doc/zh_TW/tools/index.md b/doc/zh_TW/tools/index.md
new file mode 100644
index 00000000..f08300dc
--- /dev/null
+++ b/doc/zh_TW/tools/index.md
@@ -0,0 +1,2 @@
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
diff --git a/doc/zh_TW/tools/install.md b/doc/zh_TW/tools/install.md
new file mode 100644
index 00000000..dec4ce30
--- /dev/null
+++ b/doc/zh_TW/tools/install.md
@@ -0,0 +1,12 @@
+# 安裝子命令
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/install.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+您可以使用 install 安裝在注冊表站點上注冊的軟件包。
+基本用法與cargo等包管理器相同。
+
+## 便利功能
+
+* 如果有同名的包名,且下載次數超過該包名的10倍以上,會提示可能輸入錯誤。 這可以防止拼寫錯誤。
+* 如果包很大(超過 50MB),請顯示大小并建議您是否真的要安裝它。
+* 如果包裝重復,建議使用替代包裝。
\ No newline at end of file
diff --git a/doc/zh_TW/tools/pack.md b/doc/zh_TW/tools/pack.md
new file mode 100644
index 00000000..f966688c
--- /dev/null
+++ b/doc/zh_TW/tools/pack.md
@@ -0,0 +1,102 @@
+# 包管理器
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/pack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+Erg 標配有一個包管理器,您可以使用 `pack` 子命令調用它。
+以下是典型的選項。
+
+* `erg pack init`:將當前目錄初始化為一個包。會生成一個 `package.er` 文件和一個 `src` 目錄。指定 `app` 將產生一個可執行包,`lib` 將產生一個庫包,而 `hybrid` 將產生兩個包。如果指定了 `--license`,將自動放置許可文件。
+* `erg pack build`:構建一個包。使用 `--release` 可以運行和優化測試。工件放置在 `build/debug` 或 `build/release` 中。
+* `erg pack install`:安裝一個包。在庫的情況下,`src` 被放置在 `.erg/lib` 中,而應用程序作為 shell 腳本被放置在 `.erg/app` 中。使用 `--release` 進行優化。
+* `erg pack run`:構建包并運行應用程序(僅限應用程序包)。
+* `erg pack clean`:刪除構建目錄的內容。
+* `erg pack test`:運行包測試。有關詳細信息,請參閱 [test.md](./test.md)。
+* `erg pack publish`:發布/發布包。您將需要一個 GitHub 帳戶和公鑰。
+
+本文檔解釋了如何管理您自己的包。
+如果要安裝或搜索外部包,請參閱 [install.md](./install.md)。
+另請參閱 [package_system.md](../syntax/33_package_system.md) 了解 Erg 包系統。
+
+## 整個包的標準目錄結構(對于應用程序包)
+
+```console
+/package # package root directory
+ /build # Directory to store build results
+ /debug # Artifacts during debug build
+ /release # Artifacts of release build
+ /doc # Documents (in addition, by dividing into subdirectories such as `en`, `ja` etc., it is possible to correspond to each language)
+ /src # source code
+ /main.er # file that defines the main function
+ /tests # Directory to store (black box) test files
+ /package.er # file that defines package settings
+```
+
+## package.er
+
+`erg pack init` 將生成如下所示的 `package.er` 文件。 `package.er` 描述了包的配置。
+下面是一個`package.er`的例子。
+
+```python
+name = "example" # package 名稱
+author = "John Smith" # package 作者名稱
+version="0.1.0"
+description = "An awesome package"
+categories = ["cli"] # package 類別
+type = "app" # "app" 或者 "lib"
+license = "" # 例如"MIT", "APACHE-2.0", "MIT OR Apache-2.0"
+pre_build = "" # 構建前要執行的腳本文件名
+post_build = "" # 構建后要執行的腳本文件名
+dependencies = {
+ # 如果不指定版本,則選擇最新的
+ # 如果省略版本說明,包管理器會自動將上次成功構建的版本添加到注釋中
+ foo = pack("foo") # [INFO] 最后成功構建的版本:1.2.1
+ # 包可以重命名
+ bar1 = pack("bar", "1.*.*") # [INFO] 最后成功構建的版本:1.2.0
+ bar2 = pack("bar", "2.*.*") # [INFO] 最后成功構建的版本:2.0.0
+ baz = pack("baz", "1.1.0")
+}
+deprecated=False
+successors = [] # 替代包(當一個包被棄用時)
+```
+
+## 語義版本控制
+
+Erg 包是基于 [語義版本控制](https://semver.org/lang/en/) 進行版本控制的。
+語義版本控制大致以“x.y.z”格式指定(x、y、z 是大于或等于 0 的整數)。
+每個數字的含義如下。
+
+* x:主要版本(更新破壞兼容性時增加 1)
+* y:次要版本(執行兼容更新時增加1(API添加,棄用等),錯誤修復等由補丁版本升級處理)
+* z:補丁版本(當進行小的更改以修復錯誤或保持兼容性時增加1,破壞兼容性的嚴重修復由主要版本升級處理)
+
+但是,默認情況下,版本 `0.*.*` 中的更改始終是不兼容的。如果要在保持兼容性的同時升級,請在其后指定 `-compatible`(Erg 自己的規則)。例如,如果要在保持與 0.2.1 兼容的同時添加功能,即要升級到 0.3.0,則指定 0.3.0-compatible。如果您已修復錯誤,還請指定“0.2.2-compatible”。
+該版本將被視為與以前的版本兼容。
+即使您想將 `0.*.*` 升級到 `1.0.0`,這仍然有效。也就是說,`1.0.0-compatible` 與之前的版本 `0.y.z` 兼容。
+
+生成鎖文件時,語義版本控制非常重要。鎖定文件是為保持依賴項兼容而生成的文件,因此除非明確更新,否則較新版本的依賴項依賴于較舊的包。
+當多人開發具有依賴包的包時,鎖定文件很有用。它還通過允許依賴于它們的包在兼容的情況下重用包來節省本地存儲。
+
+Erg 的包管理器嚴格執行這些規則,并將拒絕違反這些規則的包更新。
+Erg 包管理器與版本控制系統(例如 git)一起使用,以檢測代碼差異并在發布包時驗證版本控制的正確性。
+具體來說,包管理器會查看 API 的類型。如果類型是舊版本的子類型,則認為更改是兼容的(請注意,這不是完整的驗證;類型兼容但語義上不兼容的重大更改是可能的,這是開發人員的工作來確定這一點)。
+
+此外,由于整個包存儲庫都在注冊表中注冊,即使是開發人員也無法在不通過包管理器的情況下更新包。
+此外,包可以被棄用但不能被刪除。
+
+### 附錄:語義版本控制問題和對策
+
+語義版本控制存在(至少)兩個已知問題。
+首先,語義版本控制可能過于嚴格。
+使用語義版本控制,單個不兼容的 API 更改會增加整個包的主要版本。
+發生這種情況時,諸如“我想嘗試一個新的 API,但我必須處理另一個不兼容的 API 更改,所以我不會升級”之類的事情。
+其次,語義版本控制可以承諾太多。
+如上一節所述,對 API 的“兼容更改”在理論上是不可證明的。如果您指定要使用版本為 `1.0.1` 的包,則可以在語義版本控制方面使用 `1.0.1` 和 `2.0.0` 之間的任何包(`1.0.0` 不能被使用,因為錯誤已被修復),但由于包開發人員無意使用 API,構建可能不會成功。
+
+Erg 通過允許同時使用不同版本的包(通過重命名)解決了這個問題。這使得在部分引入 ver2 API 的同時繼續使用 ver1 API 成為可能。
+此外,雖然這不是一個非常理想的狀態,但如果只能使用 API 的某個次要版本而沒有錯誤,則可以不理會它并繼續前進到下一個版本。
+
+## 發布
+
+可以使用 `publish` 子命令發布包。發布需要 GitHub 帳戶。
+默認情況下,包使用 `(owner_name)/(package_name)` 注冊。如果滿足一定條件(下載次數、維護頻率等),可以申請注冊一個省略所有者名稱的別名。
+請注意,包名稱不區分大小寫,并且不區分諸如 `_` 和 `-` 之類的分隔符。
\ No newline at end of file
diff --git a/doc/zh_TW/tools/repl.md b/doc/zh_TW/tools/repl.md
new file mode 100644
index 00000000..765b72a7
--- /dev/null
+++ b/doc/zh_TW/tools/repl.md
@@ -0,0 +1,17 @@
+# REPL
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/repl.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1)
+
+運行不帶參數的 `erg` 命令會調用 REPL。 它也可以用 `repl` 子命令調用。
+此外,您可以指定以下標志:
+
+* typed:顯示對象及其類型。
+
+```console
+$ erg repl --typed
+Erg interpreter ... (tags/?:, ...) on ...
+>>> 1
+1: {1}
+>>> id x = x
+id = : |T: Type| T -> T
+```
\ No newline at end of file
diff --git a/doc/zh_TW/tools/test.md b/doc/zh_TW/tools/test.md
new file mode 100644
index 00000000..a5254f27
--- /dev/null
+++ b/doc/zh_TW/tools/test.md
@@ -0,0 +1,47 @@
+# 測試子命令
+
+[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/test.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)
+
+erg 命令有一個名為 test 的子命令,它支持測試的實現和執行。
+
+## 測試裝飾器 (@Test)
+
+Erg 使用 `erg test` 命令測試包中 `tests` 目錄或 `*.test.er` 文件中的 `@Test` 子例程。
+`tests` 子例程負責黑盒測試(不測試私有函數),`*.test.er` 子例程負責白盒測試(也測試私有函數)。
+
+```python
+# tests/test1.er
+{add; ...} = import "foo"
+
+@Test
+test_1_plus_n(n: Nat) =
+ assert add(1, n) == n + 1
+```
+
+執行結果以摘要形式顯示,可以以各種文件格式(.md、.csv 等)輸出。
+
+## 文檔測試
+
+在 Erg 中,`#` 和 `#[` 是注釋行,但 `##` 和 `#[[` 是 doc 注釋,并且注釋可以從 VSCode 等編輯器顯示為 markdown。
+此外,如果指定了 erg,則使用 erg test 命令自動測試文檔注釋中的源代碼。
+下面是一個示例測試。
+
+```python
+VMs =...
+ ...
+ #[[
+ execute commands.
+ ```python
+ # 標準配置的虛擬機
+ {vm1; ...} = import "tests/mock"
+
+ assert vm1.exec!("i = 0") == None
+ assert vm1.exec!("i").try_into(Int)? == 0
+ ```
+ ]]#
+ .exec! ref self, src =
+ ...
+ ...
+```
+
+用于測試的模擬對象(mock objects)在 `tests/mock` 模塊中定義。
\ No newline at end of file