Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Sep 2, 2022
1 parent 58d5cd4 commit 7cace5d
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 29 deletions.
23 changes: 13 additions & 10 deletions doc/EN/dev_guide/branches.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,35 @@

[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/branches.md%26commit_hash%3Dfc7a25a8d86c208fb07beb70ccc19e4722c759d3)](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=fc7a25a8d86c208fb07beb70ccc19e4722c759d3)

* Basically, development is done on a single `main` branch (monorepo development). Create a `feature-*` or `issue-*` branch only if it is difficult to work without a separate branch.

## main

* main development branch
* The following conditions must be met

* compile successfully
* Compile succeeds

## beta (not created at this time)

* Latest beta release
* The following conditions must be met

* Compile succeeds.
* all tests succeed
* Compile succeeds
* All tests passed

## feature-*
## feature-(name)

* A branch that develops one specific feature.
* main is cut off and created.
* A branch that develops one specific feature

* No conditions

## issue-*
## issue-(#issue)

* branch that resolves a specific issue

* no condition
* No condition

## fix-(#issue or bug name)

* branch that fixes a specific bug (If the issue is a bug, please create this instead of `issue-*`)

* No condition
8 changes: 8 additions & 0 deletions doc/EN/dev_guide/build_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,11 @@ Independent of Rust's `debug_assertions` flag.

Set the system language to Japanese.
In this build, Erg internal options, help (help, copyright, license, etc.) and error messages are guaranteed to be in Japanese.

## simplified_chinese

Set the system language to Simplified Chinese.

## traditional_chinese

Set the system language to Traditional Chinese.
3 changes: 2 additions & 1 deletion doc/EN/dev_guide/directories.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
│ │ ├─ python: Knowledge of Python required for Erg development
│ │ ├─ syntax: syntax of Erg
│ │ └─ tools: about Erg's CLI tools
│ └─ JA
│ └─┬ JA
│ ...
├─ examples: sample code
├─ library: Erg libraries
├─ src: main.rs & driver
Expand Down
4 changes: 2 additions & 2 deletions doc/EN/dev_guide/env.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

* Rust (installed with rustup)

* ver >= 1.58.0
* ver >= 1.63.0
* 2021 edition

* [pre-commit](https://pre-commit.com/)
Expand All @@ -18,4 +18,4 @@
* Editor: Visual Studio Code
* VSCode Extensions: Rust-analyzer, GitLens, Git Graph, GitHub Pull Requests and Issues, Markdown All in One, markdownlint
* OS: Windows 10/11 | Ubuntu 20.04/22.04 | MacOS Monterey
* Others: pyenv
* Others: pyenv, mold
112 changes: 112 additions & 0 deletions doc/EN/dev_guide/faq_syntax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Erg design's "Why" and Answers

## Why do Erg's have an ownership system but also coexist with the reference counting system?

This is because Erg's motivation for introducing an ownership system is not for "memory management that does not rely on GC" like Rust.
To begin with, Erg is currently a language that is transpiled into Python bytecode, so GC is used after all.
Erg's aim in introducing the ownership system is "localization of mutable state"; in Erg, mutable objects have the concept of ownership.
This is because shared mutable state can easily become a breeding ground for bugs and even violates type safety (see [here](./syntax/type/advanced/shared.md#SharedReference).

## Why are the parentheses surrounding type parameters || instead of <> or []?

Because `<>` and `[]` cause syntax conflicts.

```erg
id[T: Type] [t]: [T] = t
y = id[Int] # is this a function or array accessing?
id<T: Type> {t: T} = t
y = (id < Int, 1 > 1) # is this a tuple of bools or a call?
id{T: Type} {t: T} = t # conflicts with record pattern
y = id{Int}
id|T: Type| t: T = t
y = id|Int| # OK
```

## The type of {i = 1} is {i = Int}, but in OCaml and other languages it is {i: Int}. Why did Erg adopt the former syntax?

Because Erg is designed to treat the type itself as a value.

```erg
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
```

## Are there any plans to implement macros in Erg?

No. Macros have four main purposes: first, they are compile-time calculations. This is the role of compile-time functions in Erg.
The second is to delay code execution. The third is common processing, for which polymorphic functions and all-symmetric types are better solutions than macros.
Thus, the type system in Erg takes most of the functionality of macros on its shoulders, so there is no motivation to implement it.

## Why is there no exception mechanism in Erg?

Because in many cases, error handling with the `Result` type is a better solution. The `Result` type is a common error handling technique used in many relatively new programming languages.

Erg allows the `?` operator allows you to write without much awareness of errors.

```erg
read_file!() =
f = open!("foo.txt")? # If it fails, it returns an error immediately, so `f` is of type `File`
f.read_all!()
# `try` procedure can be used to catch and process like an exception
try!:
do!:
s = read_file!()?
print! s
e =>
# Blocks to execute when an error occurs
print! e
exit 1
```

When Python functions are imported, by default they are all considered to be functions with exceptions (if they are not typed manually), and their return type is of type `Result`.
If it is known that an exception will not be sent, it is made explicit by `assert`.

## Erg seems to eliminate Python features that are considered bad practice, why didn't you do away with inheritance?

Because some classes in the Python library are designed to be inherited, and completely eliminating inheritance would cause problems in their use.
However, in Erg, classes are `Final` by default, and multiple and multi-layer inheritance is prohibited in principle, so inheritance can be used relatively safely.

## Why does subtype inference for polymorphic functions point to nominal traits by default?

Because pointing to structural traits by default complicates type specification and may introduce unintended behavior by the programmer.

```erg
# 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
# T is a subtype of a nominal trait
# g: |T <: Add() and Sub()| (T, T) -> T
g|T| x, y: T = x + y - x
```

## Will Erg implement the ability to define its own operators?

A: There are no plans to do so. The main reason is that allowing the definition of custom operators raises the question of how to handle the concatenation order. Scala and Haskell, which allow the definition of custom operators, have different approaches, and this can be seen as evidence of a syntax that can lead to differences in interpretation. This can be seen as evidence of a syntax that can lead to differences in interpretation, and also has the disadvantage of creating code with low readability.

## Why did Erg do away with augmented assignment operators like `+=`?

First of all, variables are not mutable in Erg. In other words, reassignment is not possible. Once an object is assigned to a variable, it is bound to that variable forever until it is released out of scope. Once this is understood, the story is simple. For example, `i += 1` means `i = i + 1`, but such a construction is incorrect because variables are not reassignable. Another design principle of Erg is that operators have no side effects, and while Python generally does this, for some objects, such as Dict, the augmented assignment operator changes the internal state of the object. This is not a very beautiful design.
That is why augmented assignment operators have been deprecated in its entirety.

## Why does Erg give special grammatical treatment to objects with side effects?

Localization of side effects is an important part of code maintainability.

However, there are certainly ways to avoid giving side effects special linguistic treatment. For example, procedures can be substituted with algebraic effects (features on the type system).
But such congruence is not always correct. For example, Haskell did not treat strings as special, just arrays of characters, but this abstraction was wrong.

In what cases can we say that unification was wrong? One indicator is "does the congruence make the error message difficult to read?
The Erg designers decided that the error messages would be easier to read if side effects were treated specially.

Erg has a powerful type system, but it does not dominate everything with types.
If it did, it would end up the same way as Java, which tried to dominate everything with classes.
5 changes: 2 additions & 3 deletions doc/EN/dev_guide/rust_code_guideline.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@

## Encouraged code

* Define domain-specific Enums instead of numeric enumerations or bools.
* Define and use domain-specific Enums instead of numeric enumerations or bool.
* Minimize access modifiers. Use `pub(mod)` or `pub(crate)` in preference even when publishing.
* Explicitly convert iterable objects in for expressions to iterators (`for i in x.iter()` instead of `for i in x`).
* Evaluate Lazily. For example, use `unwrap_or_else` instead of `unwrap_or` if `default` is not a literal.

## Unsolicited code

* Use return-type overloading a lot. Specifically, code that uses non-trivial `.into` too often. This is because the result of type inference may be counter-intuitive. In this case, it is recommended to use `from` instead.

* Codes that use `Deref` a lot. This causes practically the same problem as inheritance.
* Use `Deref` a lot. This causes practically the same problem as inheritance.

## Code that changes its decision depending on the context

Expand Down
8 changes: 8 additions & 0 deletions doc/JA/dev_guide/build_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ Rustの`debug_assertions`フラグとは独立。

システム言語を日本語にする。
Erg内部のオプション、ヘルプ(help, copyright, licenseなど)、エラー表示は日本語化が保証される。

## simplified_chinese

システム言語を簡体字中国語にする。

## traditional_chinese

システム言語を繁体字中国語にする。
3 changes: 2 additions & 1 deletion doc/JA/dev_guide/directories.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
│ │ ├─ python: Ergの開発に必要なPythonの知識
│ │ ├─ syntax: Ergの文法
│ │ └─ tools: Ergのコマンドラインツールに関して
│ └─ JA
│ └─┬ JA
│ ...
├─ examples: サンプルコード
├─ library: Ergスクリプトによるライブラリ
├─ src: main.rsとドライバの置かれたディレクトリ
Expand Down
16 changes: 8 additions & 8 deletions doc/JA/dev_guide/env.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# Development Environment
# 開発環境

## Need to install
## インストールが必要なもの

* Rust (installed with rustup)

* ver >= 1.58.0
* ver >= 1.63.0
* 2021 edition

* [pre-commit](https://pre-commit.com/)

* Python3 interpreter
* Python3インタープリタ

## Recommended
## 推奨

* Editor: Visual Studio Code
* VSCode Extensions: Rust-analyzer, GitLens, Git Graph, GitHub Pull Requests and Issues, Markdown All in One, markdownlint
* エディタ: Visual Studio Code
* VSCode拡張機能: Rust-analyzer, GitLens, Git Graph, GitHub Pull Requests and Issues, Markdown All in One, markdownlint
* OS: Windows 10/11 | Ubuntu 20.04/22.04 | MacOS Monterey
* Others: pyenv
* その他: pyenv, mold
4 changes: 2 additions & 2 deletions doc/JA/dev_guide/faq_syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ Pythonのライブラリには継承されることを前提に設計されて

```erg
# If T is a subtype of a structural trait...
# f: |T <: Structural Trait {.`_+_`: Self.(Self) -> Self; .`_-_`: Self.(Self) -> Self| (T, T) -> T
# f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T
f|T| x, y: T = x + y - x
# T is a subtype of a nominal trait
# g: |T <: Add and Sub| (T, T) -> T
# g: |T <: Add() and Sub()| (T, T) -> T
g|T| x, y: T = x + y - x
```

Expand Down
3 changes: 1 addition & 2 deletions doc/JA/dev_guide/rust_code_guideline.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@

## 奨励されるコード

* 数値の列挙やboolの代わりにドメイン固有のEnumを定義する
* 数値の列挙やboolの代わりにドメイン固有のEnumを定義して使う
* アクセス修飾子は必要最小限のものとする。公開する場合でも`pub(mod)``pub(crate)`を優先的に使用する。
* for式でのiterableオブジェクトは明示的にイテレータに変換する(`for i in x`ではなく`for i in x.iter()`)。
* 遅延評価。例えば、`default`がリテラル以外の場合は`unwrap_or`ではなく`unwrap_or_else`を使用する。

## 奨励されないコード

* return type overloadingを多用する。具体的には自明でない`.into`を多用するコード。これは型推論結果が直感に反する場合があるためである。この場合は代わりに`from`を使うことを推奨する。

* `Deref`を多用する。これは実質的に継承と同じ問題を引き起こす。

## 文脈により判断が変わるコード
Expand Down

0 comments on commit 7cace5d

Please sign in to comment.