From c5fba46ee0682dcab1e504167eac0151f63a7131 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 10:47:30 +0800 Subject: [PATCH] Retranslate zh_CN and zh_TW doc --- doc/zh_CN/API/consts.md | 6 +- doc/zh_CN/API/funcs.md | 74 +- doc/zh_CN/API/modules/external/alstruct.md | 83 +- doc/zh_CN/API/modules/repl.md | 16 +- doc/zh_CN/API/modules/status.md | 6 +- doc/zh_CN/API/modules/unit.md | 80 +- doc/zh_CN/API/modules/unsound.md | 18 +- doc/zh_CN/API/operators.md | 42 +- doc/zh_CN/API/procs.md | 22 +- doc/zh_CN/API/special.md | 112 +-- doc/zh_CN/API/types.md | 252 +++--- doc/zh_CN/API/types/classes/Array!(T).md | 3 +- doc/zh_CN/API/types/classes/Array(T).md | 2 +- .../API/types/classes/ArrayWithLen(T,N).md | 28 +- .../types/classes/ArrayWithMutLength!(T,N).md | 40 +- doc/zh_CN/API/types/classes/Complex.md | 4 +- doc/zh_CN/API/types/classes/Dict!.md | 4 +- doc/zh_CN/API/types/classes/Either.md | 4 +- doc/zh_CN/API/types/classes/Float.md | 14 +- doc/zh_CN/API/types/classes/Function(N).md | 4 +- doc/zh_CN/API/types/classes/Inf.md | 10 +- doc/zh_CN/API/types/classes/Int.md | 10 +- doc/zh_CN/API/types/classes/IntRange.md | 10 +- doc/zh_CN/API/types/classes/Interval.md | 14 +- doc/zh_CN/API/types/classes/Matrix.md | 4 +- doc/zh_CN/API/types/classes/Nat.md | 12 +- doc/zh_CN/API/types/classes/Neg.md | 8 +- doc/zh_CN/API/types/classes/Never.md | 10 +- doc/zh_CN/API/types/classes/NonZero.md | 44 +- doc/zh_CN/API/types/classes/Object.md | 6 +- doc/zh_CN/API/types/classes/Operator.md | 6 +- doc/zh_CN/API/types/classes/Option.md | 8 +- doc/zh_CN/API/types/classes/Pos.md | 6 +- doc/zh_CN/API/types/classes/Ratio.md | 8 +- doc/zh_CN/API/types/classes/Record.md | 10 +- doc/zh_CN/API/types/classes/Result.md | 4 +- doc/zh_CN/API/types/classes/Str!.md | 4 +- doc/zh_CN/API/types/classes/Str.md | 6 +- doc/zh_CN/API/types/classes/Subroutine.md | 22 +- doc/zh_CN/API/types/classes/Tensor.md | 16 +- doc/zh_CN/API/types/classes/TransCell(T).md | 8 +- doc/zh_CN/API/types/classes/Tuple.md | 32 +- doc/zh_CN/API/types/classes/Vector.md | 2 +- doc/zh_CN/API/types/patches/BinOp.md | 4 +- doc/zh_CN/API/types/patches/UnaryOp.md | 8 +- doc/zh_CN/API/types/traits/Add(R,O).md | 22 +- doc/zh_CN/API/types/traits/Div(R,O).md | 8 +- doc/zh_CN/API/types/traits/Into.md | 8 +- doc/zh_CN/API/types/traits/Num.md | 4 +- doc/zh_CN/API/types/traits/SafeDiv(R,O).md | 8 +- doc/zh_CN/API/types/traits/Sample.md | 30 +- doc/zh_CN/API/types/traits/Unpack.md | 12 +- doc/zh_CN/compiler/TODO_recov_suggest.md | 4 +- doc/zh_CN/compiler/TODO_warn.md | 4 +- doc/zh_CN/compiler/abandoned.md | 12 +- doc/zh_CN/compiler/architecture.md | 2 +- doc/zh_CN/compiler/errors.md | 60 +- doc/zh_CN/compiler/hir.md | 56 +- doc/zh_CN/compiler/inference.md | 358 ++++---- doc/zh_CN/compiler/overview.md | 36 +- doc/zh_CN/compiler/parsing.md | 24 +- doc/zh_CN/compiler/refinement_subtyping.md | 88 +- doc/zh_CN/compiler/trait_method_resolving.md | 75 +- doc/zh_CN/compiler/transpile.md | 49 +- doc/zh_CN/compiler/type_var_normalization.md | 32 +- doc/zh_CN/dev_guide/branches.md | 2 +- doc/zh_CN/dev_guide/build_features.md | 10 +- doc/zh_CN/dev_guide/directories.md | 2 +- doc/zh_CN/dev_guide/doc_guideline.md | 16 +- doc/zh_CN/dev_guide/env.md | 20 +- doc/zh_CN/dev_guide/faq_syntax.md | 6 +- doc/zh_CN/dev_guide/i18n_messages.md | 6 +- doc/zh_CN/dev_guide/rust_code_guideline.md | 30 +- doc/zh_CN/dev_guide/terms.md | 658 +++++++------- doc/zh_CN/dev_guide/unify_terms.md | 90 +- doc/zh_CN/faq_general.md | 36 +- doc/zh_CN/faq_technical.md | 35 +- doc/zh_CN/improved_points.md | 38 +- doc/zh_CN/index.md | 14 +- doc/zh_CN/migration_from_py.md | 21 +- doc/zh_CN/python/bytecode_instructions.md | 72 +- doc/zh_CN/python/bytecode_specification.md | 11 +- doc/zh_CN/python/class_system.md | 39 +- doc/zh_CN/syntax/00_basic.md | 95 +- doc/zh_CN/syntax/01_literal.md | 78 +- doc/zh_CN/syntax/02_name.md | 75 +- doc/zh_CN/syntax/03_declaration.md | 27 +- doc/zh_CN/syntax/04_function.md | 134 ++- doc/zh_CN/syntax/05_builtin_funcs.md | 15 +- doc/zh_CN/syntax/06_operator.md | 17 +- doc/zh_CN/syntax/07_side_effect.md | 76 +- doc/zh_CN/syntax/08_procedure.md | 6 +- doc/zh_CN/syntax/09_builtin_procs.md | 7 +- doc/zh_CN/syntax/10_array.md | 38 +- doc/zh_CN/syntax/11_tuple.md | 66 +- doc/zh_CN/syntax/12_dict.md | 42 +- doc/zh_CN/syntax/13_record.md | 87 +- doc/zh_CN/syntax/14_set.md | 34 +- doc/zh_CN/syntax/15_type.md | 8 +- doc/zh_CN/syntax/16_iterator.md | 32 +- doc/zh_CN/syntax/17_mutability.md | 57 +- doc/zh_CN/syntax/18_ownership.md | 85 +- doc/zh_CN/syntax/19_visibility.md | 118 ++- doc/zh_CN/syntax/20_naming_rule.md | 38 +- doc/zh_CN/syntax/21_lambda.md | 81 +- doc/zh_CN/syntax/22_subroutine.md | 27 +- doc/zh_CN/syntax/23_closure.md | 65 +- doc/zh_CN/syntax/24_module.md | 37 +- doc/zh_CN/syntax/25_object_system.md | 81 +- doc/zh_CN/syntax/26_pattern_matching.md | 112 ++- doc/zh_CN/syntax/27_comprehension.md | 58 +- doc/zh_CN/syntax/28_spread_syntax.md | 33 +- doc/zh_CN/syntax/29_decorator.md | 80 +- doc/zh_CN/syntax/30_error_handling.md | 75 +- doc/zh_CN/syntax/31_pipeline.md | 20 +- .../syntax/32_integration_with_Python.md | 35 +- doc/zh_CN/syntax/33_package_system.md | 32 +- doc/zh_CN/syntax/34_generator.md | 16 +- doc/zh_CN/syntax/container_ownership.md | 26 +- doc/zh_CN/syntax/indexes.md | 690 +++++++-------- doc/zh_CN/syntax/quick_tour.md | 202 ++--- doc/zh_CN/syntax/type/01_type_system.md | 131 +-- doc/zh_CN/syntax/type/02_basic.md | 85 +- doc/zh_CN/syntax/type/03_trait.md | 110 ++- doc/zh_CN/syntax/type/04_class.md | 144 +-- doc/zh_CN/syntax/type/05_inheritance.md | 146 +-- doc/zh_CN/syntax/type/06_nst_vs_sst.md | 18 +- doc/zh_CN/syntax/type/07_patch.md | 85 +- doc/zh_CN/syntax/type/08_value.md | 19 +- doc/zh_CN/syntax/type/09_attributive.md | 10 +- doc/zh_CN/syntax/type/10_interval.md | 17 +- doc/zh_CN/syntax/type/11_enum.md | 33 +- doc/zh_CN/syntax/type/12_refinement.md | 48 +- doc/zh_CN/syntax/type/13_algebraic.md | 37 +- doc/zh_CN/syntax/type/14_dependent.md | 54 +- doc/zh_CN/syntax/type/15_quantified.md | 150 ++-- doc/zh_CN/syntax/type/16_subtyping.md | 34 +- doc/zh_CN/syntax/type/17_type_casting.md | 36 +- doc/zh_CN/syntax/type/18_mut.md | 187 ++-- doc/zh_CN/syntax/type/19_bound.md | 16 +- doc/zh_CN/syntax/type/advanced.md | 2 +- doc/zh_CN/syntax/type/advanced/GADTs.md | 30 +- doc/zh_CN/syntax/type/advanced/_rank2type.md | 116 +-- .../syntax/type/advanced/default_param.md | 16 +- doc/zh_CN/syntax/type/advanced/erasure.md | 30 +- doc/zh_CN/syntax/type/advanced/existential.md | 26 +- .../syntax/type/advanced/keyword_param.md | 22 +- doc/zh_CN/syntax/type/advanced/kind.md | 122 ++- .../syntax/type/advanced/marker_trait.md | 22 +- doc/zh_CN/syntax/type/advanced/mut_struct.md | 30 +- doc/zh_CN/syntax/type/advanced/newtype.md | 18 +- doc/zh_CN/syntax/type/advanced/overloading.md | 36 +- doc/zh_CN/syntax/type/advanced/phantom.md | 31 +- doc/zh_CN/syntax/type/advanced/projection.md | 11 +- .../type/advanced/quantified_dependent.md | 17 +- doc/zh_CN/syntax/type/advanced/shared.md | 32 +- doc/zh_CN/syntax/type/advanced/special.md | 31 +- doc/zh_CN/syntax/type/advanced/typeof.md | 36 +- doc/zh_CN/syntax/type/advanced/variance.md | 131 +-- doc/zh_CN/syntax/type/advanced/widening.md | 77 +- doc/zh_CN/tips.md | 61 +- doc/zh_CN/tools/build.md | 19 +- doc/zh_CN/tools/env.md | 8 +- doc/zh_CN/tools/fmt.md | 5 +- doc/zh_CN/tools/install.md | 13 +- doc/zh_CN/tools/pack.md | 102 ++- doc/zh_CN/tools/repl.md | 10 +- doc/zh_CN/tools/test.md | 30 +- doc/zh_TW/API/consts.md | 13 - doc/zh_TW/API/funcs.md | 121 --- doc/zh_TW/API/index.md | 0 doc/zh_TW/API/modules/external/alstruct.md | 57 -- doc/zh_TW/API/modules/repl.md | 24 - doc/zh_TW/API/modules/status.md | 6 - doc/zh_TW/API/modules/unit.md | 73 -- doc/zh_TW/API/modules/unsound.md | 24 - doc/zh_TW/API/operators.md | 64 -- doc/zh_TW/API/procs.md | 39 - doc/zh_TW/API/special.md | 175 ---- doc/zh_TW/API/types.md | 262 ------ doc/zh_TW/API/types/classes/Array!(T).md | 3 - doc/zh_TW/API/types/classes/Array(T).md | 3 - .../API/types/classes/ArrayWithLen(T,N).md | 34 - .../types/classes/ArrayWithMutLength!(T,N).md | 26 - doc/zh_TW/API/types/classes/Class.md | 0 doc/zh_TW/API/types/classes/Complex.md | 14 - doc/zh_TW/API/types/classes/Dict!.md | 7 - doc/zh_TW/API/types/classes/Either.md | 12 - doc/zh_TW/API/types/classes/Float.md | 21 - doc/zh_TW/API/types/classes/Function(N).md | 9 - doc/zh_TW/API/types/classes/Inf.md | 7 - doc/zh_TW/API/types/classes/Int.md | 10 - doc/zh_TW/API/types/classes/IntRange.md | 19 - doc/zh_TW/API/types/classes/Interval.md | 18 - doc/zh_TW/API/types/classes/Iterator.md | 0 doc/zh_TW/API/types/classes/Kind(N).md | 5 - doc/zh_TW/API/types/classes/Matrix.md | 7 - doc/zh_TW/API/types/classes/Module.md | 3 - doc/zh_TW/API/types/classes/Nat.md | 18 - doc/zh_TW/API/types/classes/Neg.md | 8 - doc/zh_TW/API/types/classes/Never.md | 13 - doc/zh_TW/API/types/classes/NonZero.md | 30 - doc/zh_TW/API/types/classes/Object.md | 7 - doc/zh_TW/API/types/classes/Operator.md | 7 - doc/zh_TW/API/types/classes/Option.md | 21 - doc/zh_TW/API/types/classes/Pos.md | 8 - doc/zh_TW/API/types/classes/Ratio.md | 5 - doc/zh_TW/API/types/classes/Record.md | 14 - doc/zh_TW/API/types/classes/Result.md | 7 - doc/zh_TW/API/types/classes/Str!.md | 3 - doc/zh_TW/API/types/classes/Str.md | 9 - doc/zh_TW/API/types/classes/StrWithLen.md | 0 doc/zh_TW/API/types/classes/Subroutine.md | 19 - doc/zh_TW/API/types/classes/Tensor.md | 24 - doc/zh_TW/API/types/classes/TransCell(T).md | 12 - doc/zh_TW/API/types/classes/Tuple.md | 27 - doc/zh_TW/API/types/classes/Type.md | 0 doc/zh_TW/API/types/classes/Vector.md | 3 - doc/zh_TW/API/types/patches/BinOp.md | 7 - doc/zh_TW/API/types/patches/UnaryOp.md | 7 - doc/zh_TW/API/types/traits/Add(R,O).md | 34 - doc/zh_TW/API/types/traits/Div(R,O).md | 9 - doc/zh_TW/API/types/traits/Eq.md | 0 doc/zh_TW/API/types/traits/Into.md | 11 - doc/zh_TW/API/types/traits/Iterable.md | 0 doc/zh_TW/API/types/traits/Num.md | 16 - doc/zh_TW/API/types/traits/Ord.md | 0 doc/zh_TW/API/types/traits/SafeDiv(R,O).md | 8 - doc/zh_TW/API/types/traits/Sample.md | 31 - doc/zh_TW/API/types/traits/Seq.md | 0 doc/zh_TW/API/types/traits/Show.md | 0 doc/zh_TW/API/types/traits/Unpack.md | 13 - doc/zh_TW/compiler/TODO_hint.md | 4 - doc/zh_TW/compiler/TODO_recov_suggest.md | 11 - doc/zh_TW/compiler/TODO_warn.md | 5 - doc/zh_TW/compiler/abandoned.md | 10 - doc/zh_TW/compiler/architecture.md | 39 - doc/zh_TW/compiler/errors.md | 131 --- doc/zh_TW/compiler/hir.md | 148 ---- doc/zh_TW/compiler/index.md | 0 doc/zh_TW/compiler/inference.md | 436 --------- doc/zh_TW/compiler/overview.md | 36 - doc/zh_TW/compiler/parsing.md | 31 - doc/zh_TW/compiler/refinement_subtyping.md | 155 ---- doc/zh_TW/compiler/trait_method_resolving.md | 86 -- doc/zh_TW/compiler/transpile.md | 91 -- doc/zh_TW/compiler/type_var_normalization.md | 35 - doc/zh_TW/dev_guide/branches.md | 35 - doc/zh_TW/dev_guide/build_features.md | 17 - doc/zh_TW/dev_guide/directories.md | 24 - doc/zh_TW/dev_guide/doc_guideline.md | 13 - doc/zh_TW/dev_guide/env.md | 19 - doc/zh_TW/dev_guide/faq_syntax.md | 107 --- doc/zh_TW/dev_guide/i18n_messages.md | 55 -- doc/zh_TW/dev_guide/index.md | 0 doc/zh_TW/dev_guide/rust_code_guideline.md | 23 - doc/zh_TW/dev_guide/terms.md | 831 ------------------ doc/zh_TW/dev_guide/unify_terms.md | 80 -- doc/zh_TW/faq_general.md | 27 - doc/zh_TW/faq_technical.md | 25 - doc/zh_TW/improved_points.md | 46 - doc/zh_TW/index.md | 25 - doc/zh_TW/migration_from_py.md | 28 - doc/zh_TW/python/bytecode_instructions.md | 106 --- doc/zh_TW/python/bytecode_specification.md | 70 -- doc/zh_TW/python/class_system.md | 95 -- doc/zh_TW/python/index.md | 0 doc/zh_TW/syntax/00_basic.md | 121 --- doc/zh_TW/syntax/01_literal.md | 165 ---- doc/zh_TW/syntax/02_name.md | 169 ---- doc/zh_TW/syntax/03_declaration.md | 48 - doc/zh_TW/syntax/04_function.md | 306 ------- doc/zh_TW/syntax/05_builtin_funcs.md | 52 -- doc/zh_TW/syntax/06_operator.md | 30 - doc/zh_TW/syntax/07_side_effect.md | 123 --- doc/zh_TW/syntax/08_procedure.md | 12 - doc/zh_TW/syntax/09_builtin_procs.md | 13 - doc/zh_TW/syntax/10_array.md | 56 -- doc/zh_TW/syntax/11_tuple.md | 125 --- doc/zh_TW/syntax/12_dict.md | 71 -- doc/zh_TW/syntax/13_record.md | 198 ----- doc/zh_TW/syntax/14_set.md | 50 -- doc/zh_TW/syntax/15_type.md | 7 - doc/zh_TW/syntax/16_iterator.md | 91 -- doc/zh_TW/syntax/17_mutability.md | 92 -- doc/zh_TW/syntax/18_ownership.md | 103 --- doc/zh_TW/syntax/19_visibility.md | 199 ----- doc/zh_TW/syntax/20_naming_rule.md | 52 -- doc/zh_TW/syntax/21_lambda.md | 102 --- doc/zh_TW/syntax/22_subroutine.md | 65 -- doc/zh_TW/syntax/23_closure.md | 99 --- doc/zh_TW/syntax/24_module.md | 47 - doc/zh_TW/syntax/25_object_system.md | 77 -- doc/zh_TW/syntax/26_pattern_matching.md | 203 ----- doc/zh_TW/syntax/27_comprehension.md | 65 -- doc/zh_TW/syntax/28_spread_syntax.md | 45 - doc/zh_TW/syntax/29_decorator.md | 124 --- doc/zh_TW/syntax/30_error_handling.md | 106 --- doc/zh_TW/syntax/31_pipeline.md | 32 - .../syntax/32_integration_with_Python.md | 87 -- doc/zh_TW/syntax/33_package_system.md | 83 -- doc/zh_TW/syntax/34_generator.md | 37 - doc/zh_TW/syntax/SUMMARY.md | 69 -- doc/zh_TW/syntax/container_ownership.md | 42 - doc/zh_TW/syntax/grammar.txt | 88 -- doc/zh_TW/syntax/indexes.md | 452 ---------- doc/zh_TW/syntax/quick_tour.md | 287 ------ doc/zh_TW/syntax/type/01_type_system.md | 224 ----- doc/zh_TW/syntax/type/02_basic.md | 170 ---- doc/zh_TW/syntax/type/03_trait.md | 193 ---- doc/zh_TW/syntax/type/04_class.md | 285 ------ doc/zh_TW/syntax/type/05_inheritance.md | 248 ------ doc/zh_TW/syntax/type/06_nst_vs_sst.md | 43 - doc/zh_TW/syntax/type/07_patch.md | 223 ----- doc/zh_TW/syntax/type/08_value.md | 38 - doc/zh_TW/syntax/type/09_attributive.md | 7 - doc/zh_TW/syntax/type/10_interval.md | 39 - doc/zh_TW/syntax/type/11_enum.md | 86 -- doc/zh_TW/syntax/type/12_refinement.md | 75 -- doc/zh_TW/syntax/type/13_algebraic.md | 82 -- doc/zh_TW/syntax/type/14_dependent.md | 76 -- doc/zh_TW/syntax/type/15_quantified.md | 288 ------ doc/zh_TW/syntax/type/16_subtyping.md | 80 -- doc/zh_TW/syntax/type/17_type_casting.md | 74 -- doc/zh_TW/syntax/type/18_mut.md | 168 ---- doc/zh_TW/syntax/type/19_bound.md | 16 - doc/zh_TW/syntax/type/advanced.md | 1 - doc/zh_TW/syntax/type/advanced/GADTs.md | 68 -- doc/zh_TW/syntax/type/advanced/_rank2type.md | 142 --- .../syntax/type/advanced/default_param.md | 28 - doc/zh_TW/syntax/type/advanced/erasure.md | 45 - doc/zh_TW/syntax/type/advanced/existential.md | 39 - .../syntax/type/advanced/keyword_param.md | 26 - doc/zh_TW/syntax/type/advanced/kind.md | 157 ---- .../syntax/type/advanced/marker_trait.md | 33 - doc/zh_TW/syntax/type/advanced/mut_struct.md | 40 - doc/zh_TW/syntax/type/advanced/newtype.md | 31 - doc/zh_TW/syntax/type/advanced/overloading.md | 91 -- doc/zh_TW/syntax/type/advanced/phantom.md | 58 -- doc/zh_TW/syntax/type/advanced/projection.md | 25 - .../type/advanced/quantified_dependent.md | 30 - doc/zh_TW/syntax/type/advanced/shared.md | 72 -- doc/zh_TW/syntax/type/advanced/special.md | 54 -- doc/zh_TW/syntax/type/advanced/typeof.md | 61 -- doc/zh_TW/syntax/type/advanced/variance.md | 128 --- doc/zh_TW/syntax/type/advanced/widening.md | 93 -- doc/zh_TW/tips.md | 142 --- doc/zh_TW/tools/build.md | 13 - doc/zh_TW/tools/env.md | 3 - doc/zh_TW/tools/fmt.md | 5 - doc/zh_TW/tools/index.md | 0 doc/zh_TW/tools/install.md | 9 - doc/zh_TW/tools/pack.md | 82 -- doc/zh_TW/tools/repl.md | 15 - doc/zh_TW/tools/test.md | 43 - 355 files changed, 4129 insertions(+), 16617 deletions(-) delete mode 100644 doc/zh_TW/API/consts.md delete mode 100644 doc/zh_TW/API/funcs.md delete mode 100644 doc/zh_TW/API/index.md delete mode 100644 doc/zh_TW/API/modules/external/alstruct.md delete mode 100644 doc/zh_TW/API/modules/repl.md delete mode 100644 doc/zh_TW/API/modules/status.md delete mode 100644 doc/zh_TW/API/modules/unit.md delete mode 100644 doc/zh_TW/API/modules/unsound.md delete mode 100644 doc/zh_TW/API/operators.md delete mode 100644 doc/zh_TW/API/procs.md delete mode 100644 doc/zh_TW/API/special.md delete mode 100644 doc/zh_TW/API/types.md delete mode 100644 doc/zh_TW/API/types/classes/Array!(T).md delete mode 100644 doc/zh_TW/API/types/classes/Array(T).md delete mode 100644 doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md delete mode 100644 doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md delete mode 100644 doc/zh_TW/API/types/classes/Class.md delete mode 100644 doc/zh_TW/API/types/classes/Complex.md delete mode 100644 doc/zh_TW/API/types/classes/Dict!.md delete mode 100644 doc/zh_TW/API/types/classes/Either.md delete mode 100644 doc/zh_TW/API/types/classes/Float.md delete mode 100644 doc/zh_TW/API/types/classes/Function(N).md delete mode 100644 doc/zh_TW/API/types/classes/Inf.md delete mode 100644 doc/zh_TW/API/types/classes/Int.md delete mode 100644 doc/zh_TW/API/types/classes/IntRange.md delete mode 100644 doc/zh_TW/API/types/classes/Interval.md delete mode 100644 doc/zh_TW/API/types/classes/Iterator.md delete mode 100644 doc/zh_TW/API/types/classes/Kind(N).md delete mode 100644 doc/zh_TW/API/types/classes/Matrix.md delete mode 100644 doc/zh_TW/API/types/classes/Module.md delete mode 100644 doc/zh_TW/API/types/classes/Nat.md delete mode 100644 doc/zh_TW/API/types/classes/Neg.md delete mode 100644 doc/zh_TW/API/types/classes/Never.md delete mode 100644 doc/zh_TW/API/types/classes/NonZero.md delete mode 100644 doc/zh_TW/API/types/classes/Object.md delete mode 100644 doc/zh_TW/API/types/classes/Operator.md delete mode 100644 doc/zh_TW/API/types/classes/Option.md delete mode 100644 doc/zh_TW/API/types/classes/Pos.md delete mode 100644 doc/zh_TW/API/types/classes/Ratio.md delete mode 100644 doc/zh_TW/API/types/classes/Record.md delete mode 100644 doc/zh_TW/API/types/classes/Result.md delete mode 100644 doc/zh_TW/API/types/classes/Str!.md delete mode 100644 doc/zh_TW/API/types/classes/Str.md delete mode 100644 doc/zh_TW/API/types/classes/StrWithLen.md delete mode 100644 doc/zh_TW/API/types/classes/Subroutine.md delete mode 100644 doc/zh_TW/API/types/classes/Tensor.md delete mode 100644 doc/zh_TW/API/types/classes/TransCell(T).md delete mode 100644 doc/zh_TW/API/types/classes/Tuple.md delete mode 100644 doc/zh_TW/API/types/classes/Type.md delete mode 100644 doc/zh_TW/API/types/classes/Vector.md delete mode 100644 doc/zh_TW/API/types/patches/BinOp.md delete mode 100644 doc/zh_TW/API/types/patches/UnaryOp.md delete mode 100644 doc/zh_TW/API/types/traits/Add(R,O).md delete mode 100644 doc/zh_TW/API/types/traits/Div(R,O).md delete mode 100644 doc/zh_TW/API/types/traits/Eq.md delete mode 100644 doc/zh_TW/API/types/traits/Into.md delete mode 100644 doc/zh_TW/API/types/traits/Iterable.md delete mode 100644 doc/zh_TW/API/types/traits/Num.md delete mode 100644 doc/zh_TW/API/types/traits/Ord.md delete mode 100644 doc/zh_TW/API/types/traits/SafeDiv(R,O).md delete mode 100644 doc/zh_TW/API/types/traits/Sample.md delete mode 100644 doc/zh_TW/API/types/traits/Seq.md delete mode 100644 doc/zh_TW/API/types/traits/Show.md delete mode 100644 doc/zh_TW/API/types/traits/Unpack.md delete mode 100644 doc/zh_TW/compiler/TODO_hint.md delete mode 100644 doc/zh_TW/compiler/TODO_recov_suggest.md delete mode 100644 doc/zh_TW/compiler/TODO_warn.md delete mode 100644 doc/zh_TW/compiler/abandoned.md delete mode 100644 doc/zh_TW/compiler/architecture.md delete mode 100644 doc/zh_TW/compiler/errors.md delete mode 100644 doc/zh_TW/compiler/hir.md delete mode 100644 doc/zh_TW/compiler/index.md delete mode 100644 doc/zh_TW/compiler/inference.md delete mode 100644 doc/zh_TW/compiler/overview.md delete mode 100644 doc/zh_TW/compiler/parsing.md delete mode 100644 doc/zh_TW/compiler/refinement_subtyping.md delete mode 100644 doc/zh_TW/compiler/trait_method_resolving.md delete mode 100644 doc/zh_TW/compiler/transpile.md delete mode 100644 doc/zh_TW/compiler/type_var_normalization.md delete mode 100644 doc/zh_TW/dev_guide/branches.md delete mode 100644 doc/zh_TW/dev_guide/build_features.md delete mode 100644 doc/zh_TW/dev_guide/directories.md delete mode 100644 doc/zh_TW/dev_guide/doc_guideline.md delete mode 100644 doc/zh_TW/dev_guide/env.md delete mode 100644 doc/zh_TW/dev_guide/faq_syntax.md delete mode 100644 doc/zh_TW/dev_guide/i18n_messages.md delete mode 100644 doc/zh_TW/dev_guide/index.md delete mode 100644 doc/zh_TW/dev_guide/rust_code_guideline.md delete mode 100644 doc/zh_TW/dev_guide/terms.md delete mode 100644 doc/zh_TW/dev_guide/unify_terms.md delete mode 100644 doc/zh_TW/faq_general.md delete mode 100644 doc/zh_TW/faq_technical.md delete mode 100644 doc/zh_TW/improved_points.md delete mode 100644 doc/zh_TW/index.md delete mode 100644 doc/zh_TW/migration_from_py.md delete mode 100644 doc/zh_TW/python/bytecode_instructions.md delete mode 100644 doc/zh_TW/python/bytecode_specification.md delete mode 100644 doc/zh_TW/python/class_system.md delete mode 100644 doc/zh_TW/python/index.md delete mode 100644 doc/zh_TW/syntax/00_basic.md delete mode 100644 doc/zh_TW/syntax/01_literal.md delete mode 100644 doc/zh_TW/syntax/02_name.md delete mode 100644 doc/zh_TW/syntax/03_declaration.md delete mode 100644 doc/zh_TW/syntax/04_function.md delete mode 100644 doc/zh_TW/syntax/05_builtin_funcs.md delete mode 100644 doc/zh_TW/syntax/06_operator.md delete mode 100644 doc/zh_TW/syntax/07_side_effect.md delete mode 100644 doc/zh_TW/syntax/08_procedure.md delete mode 100644 doc/zh_TW/syntax/09_builtin_procs.md delete mode 100644 doc/zh_TW/syntax/10_array.md delete mode 100644 doc/zh_TW/syntax/11_tuple.md delete mode 100644 doc/zh_TW/syntax/12_dict.md delete mode 100644 doc/zh_TW/syntax/13_record.md delete mode 100644 doc/zh_TW/syntax/14_set.md delete mode 100644 doc/zh_TW/syntax/15_type.md delete mode 100644 doc/zh_TW/syntax/16_iterator.md delete mode 100644 doc/zh_TW/syntax/17_mutability.md delete mode 100644 doc/zh_TW/syntax/18_ownership.md delete mode 100644 doc/zh_TW/syntax/19_visibility.md delete mode 100644 doc/zh_TW/syntax/20_naming_rule.md delete mode 100644 doc/zh_TW/syntax/21_lambda.md delete mode 100644 doc/zh_TW/syntax/22_subroutine.md delete mode 100644 doc/zh_TW/syntax/23_closure.md delete mode 100644 doc/zh_TW/syntax/24_module.md delete mode 100644 doc/zh_TW/syntax/25_object_system.md delete mode 100644 doc/zh_TW/syntax/26_pattern_matching.md delete mode 100644 doc/zh_TW/syntax/27_comprehension.md delete mode 100644 doc/zh_TW/syntax/28_spread_syntax.md delete mode 100644 doc/zh_TW/syntax/29_decorator.md delete mode 100644 doc/zh_TW/syntax/30_error_handling.md delete mode 100644 doc/zh_TW/syntax/31_pipeline.md delete mode 100644 doc/zh_TW/syntax/32_integration_with_Python.md delete mode 100644 doc/zh_TW/syntax/33_package_system.md delete mode 100644 doc/zh_TW/syntax/34_generator.md delete mode 100644 doc/zh_TW/syntax/SUMMARY.md delete mode 100644 doc/zh_TW/syntax/container_ownership.md delete mode 100644 doc/zh_TW/syntax/grammar.txt delete mode 100644 doc/zh_TW/syntax/indexes.md delete mode 100644 doc/zh_TW/syntax/quick_tour.md delete mode 100644 doc/zh_TW/syntax/type/01_type_system.md delete mode 100644 doc/zh_TW/syntax/type/02_basic.md delete mode 100644 doc/zh_TW/syntax/type/03_trait.md delete mode 100644 doc/zh_TW/syntax/type/04_class.md delete mode 100644 doc/zh_TW/syntax/type/05_inheritance.md delete mode 100644 doc/zh_TW/syntax/type/06_nst_vs_sst.md delete mode 100644 doc/zh_TW/syntax/type/07_patch.md delete mode 100644 doc/zh_TW/syntax/type/08_value.md delete mode 100644 doc/zh_TW/syntax/type/09_attributive.md delete mode 100644 doc/zh_TW/syntax/type/10_interval.md delete mode 100644 doc/zh_TW/syntax/type/11_enum.md delete mode 100644 doc/zh_TW/syntax/type/12_refinement.md delete mode 100644 doc/zh_TW/syntax/type/13_algebraic.md delete mode 100644 doc/zh_TW/syntax/type/14_dependent.md delete mode 100644 doc/zh_TW/syntax/type/15_quantified.md delete mode 100644 doc/zh_TW/syntax/type/16_subtyping.md delete mode 100644 doc/zh_TW/syntax/type/17_type_casting.md delete mode 100644 doc/zh_TW/syntax/type/18_mut.md delete mode 100644 doc/zh_TW/syntax/type/19_bound.md delete mode 100644 doc/zh_TW/syntax/type/advanced.md delete mode 100644 doc/zh_TW/syntax/type/advanced/GADTs.md delete mode 100644 doc/zh_TW/syntax/type/advanced/_rank2type.md delete mode 100644 doc/zh_TW/syntax/type/advanced/default_param.md delete mode 100644 doc/zh_TW/syntax/type/advanced/erasure.md delete mode 100644 doc/zh_TW/syntax/type/advanced/existential.md delete mode 100644 doc/zh_TW/syntax/type/advanced/keyword_param.md delete mode 100644 doc/zh_TW/syntax/type/advanced/kind.md delete mode 100644 doc/zh_TW/syntax/type/advanced/marker_trait.md delete mode 100644 doc/zh_TW/syntax/type/advanced/mut_struct.md delete mode 100644 doc/zh_TW/syntax/type/advanced/newtype.md delete mode 100644 doc/zh_TW/syntax/type/advanced/overloading.md delete mode 100644 doc/zh_TW/syntax/type/advanced/phantom.md delete mode 100644 doc/zh_TW/syntax/type/advanced/projection.md delete mode 100644 doc/zh_TW/syntax/type/advanced/quantified_dependent.md delete mode 100644 doc/zh_TW/syntax/type/advanced/shared.md delete mode 100644 doc/zh_TW/syntax/type/advanced/special.md delete mode 100644 doc/zh_TW/syntax/type/advanced/typeof.md delete mode 100644 doc/zh_TW/syntax/type/advanced/variance.md delete mode 100644 doc/zh_TW/syntax/type/advanced/widening.md delete mode 100644 doc/zh_TW/tips.md delete mode 100644 doc/zh_TW/tools/build.md delete mode 100644 doc/zh_TW/tools/env.md delete mode 100644 doc/zh_TW/tools/fmt.md delete mode 100644 doc/zh_TW/tools/index.md delete mode 100644 doc/zh_TW/tools/install.md delete mode 100644 doc/zh_TW/tools/pack.md delete mode 100644 doc/zh_TW/tools/repl.md delete mode 100644 doc/zh_TW/tools/test.md diff --git a/doc/zh_CN/API/consts.md b/doc/zh_CN/API/consts.md index b42e2f5b..daf7d1e5 100644 --- a/doc/zh_CN/API/consts.md +++ b/doc/zh_CN/API/consts.md @@ -1,4 +1,4 @@ -# 内置常量 +# built-in constants ## True @@ -8,6 +8,6 @@ ## Ellipsis -## NotImplemented +## Not Implemented -## Inf +## Inf \ No newline at end of file diff --git a/doc/zh_CN/API/funcs.md b/doc/zh_CN/API/funcs.md index 3dee7041..78128595 100644 --- a/doc/zh_CN/API/funcs.md +++ b/doc/zh_CN/API/funcs.md @@ -1,17 +1,17 @@ -# 功能 +# functions -## 基本功能 +## basic functions ### if|T; U|(cond: Bool, then: T, else: U) -> T or U ### map|T; U|(i: Iterable T, f: T -> U) -> Map U -请注意,参数的顺序与 Python 相反 +Note that the order of arguments is reversed from Python. ### log(x: Object, type: LogType = Info) -> None -在调试显示中记录“x”。 执行完成后汇总并显示日志 -支持表情符号的终端根据“类型”添加前缀 +Log `x` in debug display. Logs are summarized and displayed after the execution is finished. +Emoji-capable terminals are prefixed according to `type`. * type == Info: 💬 * type == Ok: ✅ @@ -20,17 +20,17 @@ ### panic(msg: Str) -> Panic -显示msg并停止。 -支持表情符号的终端有一个🚨前缀。 +Display msg and stop. +Emoji-capable terminals have a 🚨 prefix. ### discard|T|(x: ...T) -> NoneType -扔掉`x`。不使用返回值时使用。与 `del` 不同,它不会使变量 `x` 不可访问 +Throw away `x`. Used when the return value is not used. Unlike `del`, it does not make the variable `x` inaccessible. -```erg -p! x = - # q!应该返回一些不是None或()的值 - # 如果不需要,请使用`discard` +``` erg +p!x= + # Let q! return some None or non-() value + # use `discard` if you don't need it discard q!(x) f x @@ -40,32 +40,32 @@ assert True # OK ### import(path: Path) -> Module or CompilerPanic -导入一个模块。如果找不到模块,则引发编译错误 +Import a module. Raises a compilation error if the module is not found. ### eval(code: Str) -> Object -将`code`作为代码进行评估并返回。 +Evaluate code as code and return. ### classof(object: Object) -> Class -返回`object`的类。 -但是,由于无法比较类,如果要判断实例,请使用`object in Class`而不是`classof(object) == Class` -编译时确定的结构类型是通过`Typeof`获得的 +Returns the class of `object`. +However, since classes cannot be compared, use `object in Class` instead of `classof(object) == Class` if you want to judge instances. +The structure type determined at compile time is obtained with `Typeof`. -## Iterator, Array生成系统 +## Iterator, Array generation system ### repeat|T|(x: T) -> RepeatIterator T -```erg +``` erg rep = repeat 1 # Repeater(1) for! rep, i => - print! i + print!i # 1 1 1 1 1 ... ``` ### dup|T; N|(x: T, N: Nat) -> [T; N] -```erg +``` erg [a, b, c] = dup new(), 3 print! a # print! a == b # False @@ -73,21 +73,21 @@ print! a == b # False ### cycle|T|(it: Iterable T) -> CycleIterator T -```erg +``` erg cycle([0, 1]).take 4 # [0, 1, 0, 1] cycle("hello").take 3 # "hellohellohello" ``` -## 定数式関数 +## constant expression functions ### Class -创建一个新类。 与`Inherit`不同,通过`Class`传递与基类型无关,并且方法会丢失 -您将无法进行比较,但您可以进行模式匹配等操作 +Create a new class. Unlike `Inherit`, passing through `Class` is independent of the base type and methods are lost. +You won't be able to compare, but you can do things like pattern matching. -```erg +``` erg C = Class {i = Int} -NewInt = Class Int +NewInt = ClassInt Months = Class 1..12 jan = Months.new(1) jan + Months.new(2) # TypeError: `+` is not implemented for 'Months' @@ -96,26 +96,26 @@ match jan: _ -> log "Other" ``` -第二个参数 Impl 是要实现的特征 +The second argument, Impl, is the trait to implement. ### Inherit -继承一个类。您可以按原样使用基类方法 +Inherit a class. You can use the base class methods as they are. -### Trait +### Traits -创造一个新的特质。目前,只能指定记录类型 +Create a new trait. Currently, only record types can be specified. -### Typeof +### Type of -返回参数类型。如果要获取运行时类,请使用`classof`。 -如果您将其用于类型规范,则会出现警告。 +Returns the argument type. Use `classof` if you want to get the runtime class. +If you use it for type specification, Warning will appear. -```erg -x: Typeof i = ... +``` erg +x: Type of i = ... # TypeWarning: Typeof(i) == Int, please replace it ``` ### Deprecated -作为解码器使用。警告不推荐使用的类型或函数 \ No newline at end of file +Use as a decorator. Warn about deprecated types and functions. \ No newline at end of file diff --git a/doc/zh_CN/API/modules/external/alstruct.md b/doc/zh_CN/API/modules/external/alstruct.md index 1635c852..87e411e5 100644 --- a/doc/zh_CN/API/modules/external/alstruct.md +++ b/doc/zh_CN/API/modules/external/alstruct.md @@ -1,57 +1,42 @@ -# alstruct +# alstructuration +Modules qui fournissent des caractères représentant les structures et les parcelles d'algèbre. -提供表示代数结构的托盘和相应补丁的模块。 - -* member +- membres membres membres membres membres ## binop + 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 -``` erg -Kind 2 = Subsume Op(Self, Self. returntypeof Op), Additional: { -.ReturnTypeof = TraitType -> Type -} +## semi-groupe + SemiGroup Op: Kind 2 = Op(Self, Self) + + IntIsSemiGroupAdd = Patch Int, Impl=SemiGroupAdd + + Int <: SemiGroup Add -Nat <: BinOp Add -assert Nat. returntypeof (Add) == Nat -assert Nat.ReturnTypeof(Sub) == Int -assert Nat. returntypeof (Mul) == Nat -assert Nat.ReturnTypeof(Div) == Positive Ratio -``` +## amateurs + ## * 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 + } -## semigroup +## Application + ## * 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 + } -``` erg -SemiGroup Op: Kind 2 = Op(Self, Self) +## monad monad + Monad = Subsume Applicative, Additional: { + .bind|T, U: Type| = (Self(T), T -> Self U) -> Self U + } -IntIsSemiGroupAdd = Patch Int, Impl=SemiGroup Add - -Int <: SemiGroup Add -``` - -## functor - -``` erg -## * 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 -} -``` - -## applicative - -``` erg -## * Identity law: x.app(x. pure(id)) == x -Applicative = Subsume Functor, Additional: { -t: . pure | type | = t - > self t -. app | t, u: type | = (self (t), self (t - > u)) - > self u -} -``` - -## monad - -``` erg -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 index 9b7c5a92..a4091909 100644 --- a/doc/zh_CN/API/modules/repl.md +++ b/doc/zh_CN/API/modules/repl.md @@ -1,24 +1,24 @@ # module `repl` -provides REPL(Read-Eval-Print-Loop)-related APIs。 +provides REPL(Read-Eval-Print-Loop)-related APIs. ## functions -* ` gui _ help ` +* `gui_help` -在浏览器中显示关于对象的信息。离线也可以使用。 +View information about an object in a browser. Can be used offline. ## types ### Guess = Object -## ## methods +#### methods -* * ` . guess ` +* `.guess` -根据所给出的自变量和返回值来推测函数。 +Infers a function given its arguments and return value. ``` erg -guess((1,), 2) # -[1, 2] . guess(3、4),[1,2,3,4])# < array (t, n) . concat method > +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 index 83199149..a30b4ad0 100644 --- a/doc/zh_CN/API/modules/status.md +++ b/doc/zh_CN/API/modules/status.md @@ -1,6 +1,6 @@ # module `status` -定义了表示状态的类型。请根据情况排除选项使用。 +A type is defined to represent the state. Please use it by removing the option according to the situation. -* ExecResult ={“success”,“warning”,“failure”,“fatal”,“unknown”} -ExecStatus ={“ready”,“running”,“sleeping”,“plague”,“completed”,“terminated”} \ No newline at end of file +* 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 index 214c4033..781eefff 100644 --- a/doc/zh_CN/API/modules/unit.md +++ b/doc/zh_CN/API/modules/unit.md @@ -1,59 +1,59 @@ # module `unit` -`unit`模块是将数值计算中常用的单位定义为型的模块。 -Erg的数值型有`Nat`, `Int`, `Ratio`等。但是,这些模型并没有掌握“这意味着什么”的信息,只能进行米和码之间的加法等荒唐的计算。 -通过使用`unit`模块,可以防止将单位不同的数值传递给函数的错误。 -这样的失误是实际发生,而且[单位系的错误火星探测器失踪](http://www.sydrose.com/case100/287/)等,可能引起严重的bug。 -如果想在进行数值计算的基础上提高代码的鲁棒性的话应该事先使用这个模块。 +The `unit` module is a module that defines units that are often used in numerical calculations as types. +Erg numeric types include `Nat`, `Int`, `Ratio`, and so on. However, these types do not have information about "what the numbers mean", so nonsense calculations such as adding meters and yards can be performed. +By using the `unit` module, you can avoid mistakes such as passing numbers with different units to functions. +Mistakes like this actually occur, and serious bugs such as [Mars probe missing due to wrong unit system](http://www.sydrose.com/case100/287/) can cause it. +You should use this module if you want your code to be more robust when doing numerical computations. ``` erg {*} = import "unit" -等价于x = 6m# `x = Meter.new(6)` -等价于t = 3s# `t = c.new(3)` -# m/s是速度的单位对象,Velocity型 -print !x/ t# 2m/s -print !x + 4m# 10m -print !x + 2s# TypeError: `+`(Meter, Sec) is not implemented +x = 6m # equivalent to `x = Meter.new(6)` +t = 3s # equivalent to `t = Sec.new(3)` +# m/s is a velocity unit object, of type Velocity +print! x/t # 2m/s +print! x + 4m # 10m +print! x + 2s # TypeError: `+`(Meter, Sec) is not implemented ``` -`m`, `s`, `m/s`这样的对象被称为单位对象。它本身就有1m, 1s, 1m/s的意思。`m/s`可以说是m和s的合成产生的单位对象。 +The objects `m`, `s`, and `m/s` are called unit objects. It has the meaning of 1m, 1s, 1m/s by itself. `m/s` can be said to be a unit object created by combining m and s. -unit将以下单位定义为型。国际单位制(SI)。 +In unit, the following units are defined as types. It is called SI (International System of Units). -* 长度:Meter(单位常数:m) -* 质量:KiloGram(单位常数:kg, g = 0.001kg) -* 时间:Sec(分钟、时间、日、年等有由Sec生成的minute, hour, day, year等常数) -* 电流:Amper(单位常数:a) -* 温度:Kelvin(单位常数:k, Fahren,也有Celsius型,可相互转换) -* 物质的量:Mol(单位常数:Mol) -* 光度:Candela(单位常数:cd) +* Length: Meter (unit constant: m) +* Mass: KiloGram (unit constant: kg, g = 0.001kg) +* Time: Sec (minute, hour, day, year, etc. have constants such as minute, hour, day, year generated from Sec) +* Current: Amper (unit constant: a) +* Temperature: Kelvin (unit constant: k, Fahren, Celsius types are also available and can be converted to each other) +* Amount of substance: Mol (unit constant: mol) +* Luminous intensity: Candela (unit constant: cd) -另外,`Unit1`, `UnitMul`, `UnitDiv`这样的类型被定义,使用这个可以合成基本类型创建新的单位。 -例如,振动频率的单位赫兹(hertz)是用振动周期(秒)的倒数来定义的,所以`UnitDiv(Unit1, Sec)`。 -想要把这个类型视为有意义的类型(想要加上专用的方法,等等)的时候,[补丁](./../ . ./syntax/type/07_patch.md)。 +In addition, the types `Unit1`, `UnitMul`, and `UnitDiv` are defined, which can be used to create new units by combining basic types. +For example, `UnitDiv(Unit1, Sec)`, because the unit of frequency hertz (hertz) is defined as the reciprocal of the vibration period (seconds). +If you want to treat this type as a meaningful type (such as adding a dedicated method), you should create a [patch](./../../syntax/type/07_patch.md). ``` erg Hertz = Patch UnitDiv(Unit1, Sec) -SquareMeter = UnitMul(Meter, Meter) +SquareMeter = Patch UnitMul(Meter, Meter) ``` -辅助单位也被预先定义了几个。 +Some auxiliary units are also predefined. -* 振动频率:Hertz(hz) -* 力:Newton。 -* 能量:Joule(j) -* 工作量:Watt(w) -* 电势:Volt(v) -* 电阻:Ohm(Ohm) -* 速度:Velocity(m/s) -* 面积:SquareMeter(m**2) -* 体积:CubicMeter(m**3) (litre = 10e- 3m **3) -* 角度:Degree(deg) (rad = 180/pi deg) -* 长度:Feet, Yard, Inch, Mile, Ly, Au, Angstrom -* 重量:Pond +* Frequency: Hertz(hz) +* Force: Newton(newton) +* Energy: Joule(j) +* Power: Watt(w) +* Potential: Volt(v) +* Electrical resistance: Ohm(ohm) +* Velocity: Velocity(m/s) +* Area: SquareMeter(m**2) +* Volume: CubicMeter(m**3) (liter = 10e-3 m**3) +* Angle: Degree(deg) (rad = 180/pi deg) +* Length: Feet, Yard, Inch, Mile, Ly, Au, Angstrom +* Weight: Pound -另外,前缀也有定义。 +It also defines a prefix. * Femto = 1e-15 * Pico = 1e-12 @@ -68,6 +68,6 @@ SquareMeter = UnitMul(Meter, Meter) * Giga = 1e+9 * Tera = 1e+12 * Peta = 1e+15 -* Exa = 1e+18 +*Exa = 1e+18 -※与名字的由来相反,Erg基本上采用MKS单位制。cgs单位系unit模块的希望时,外部库([cgs] (https://github.com/mtshiba/cgs)等),请使用。 \ No newline at end of file +*Contrary to the origin of the name, Erg basically adopts the MKS unit system. If you want the unit module of the CGS unit system, please use an external library ([cgs](https://github.com/mtshiba/cgs) etc.). \ No newline at end of file diff --git a/doc/zh_CN/API/modules/unsound.md b/doc/zh_CN/API/modules/unsound.md index 90221567..28998a72 100644 --- a/doc/zh_CN/API/modules/unsound.md +++ b/doc/zh_CN/API/modules/unsound.md @@ -1,24 +1,24 @@ # module `unsound` -提供的api执行在Erg的类型系统中无法保证安全的不健全和不安全的操作。 +Provides APIs perform unsound and unsafe operations that cannot be guaranteed safe in Erg's type system. ## `unsafe!` -执行一个`Unsafe`过程。就像Rust一样,`Unsafe`的api不能被直接调用,而是全部作为高阶函数传递给这个过程。 +Executes an `Unsafe` procedure. Just like Rust, `Unsafe` APIs cannot be called directly, but are all passed as higher-order functions to this procedure. ``` erg unsound = import "unsound" -i = unsound.unsafe!do !: -# convert `Result Int` to `Int` -unsound.transmute input !() . try into (int), int +i = unsound. unsafe! do!: + # convert `Result Int` to `Int` + unsound.transmute input!().try_into(Int), Int ``` -## transmute +## transmit -将第一个参数的对象转换成第二个参数的类型。不进行模板检查。 -这个函数损害型系统的型安全性。使用的时候请进行验证等。 +Converts the object of the first argument to the type of the second argument. No type checking is done. +This function breaks the type safety of the type system. Please perform validation before using. ## auto_transmute -与`transmute`不同,自动转换为期待的类型。与Ocaml的`Obj.magic`作用相同。 \ No newline at end of file +Unlike `transmute`, it automatically converts to the expected type. Works the same as Ocaml's `Obj.magic`. \ No newline at end of file diff --git a/doc/zh_CN/API/operators.md b/doc/zh_CN/API/operators.md index 0df302ea..31b1f58b 100644 --- a/doc/zh_CN/API/operators.md +++ b/doc/zh_CN/API/operators.md @@ -1,64 +1,64 @@ -# 运算符 +# operator -## 中缀运算符 +## infix operator ### `_+_`|R; O; A <: Add(R, O)|(x: A, y: R) -> O -执行加法。 +Perform addition. ### `_-_`|R; O; S <: Sub(R, O)|(x: S, y: R) -> O -执行减法。 +Perform subtraction. ### `*`|R; O; M <: Mul R, O|(x: M, y: R) -> O -执行乘法。 +Perform multiplication. ### `/`|R; O; D <: Div(R, O)|(x: D, y: R) -> O -进行除法。 +Perform division. -## 中缀字母运算符 +## infix alphabet operator ### `and`(x: Bool, y: Bool) -> Bool -执行 and 操作。 +Executes the and operation. ### `or`(x: Bool, y: Bool) -> Bool -执行 and 操作。 +Executes the and operation. -## 前缀运算符 +## prefix operator ### `+_`|T <: Num|(x: T) -> T -默认与 id 相同。 +Same as id by default. ### `-_`|T <: Num|(x: T) -> T.Neg -例如 Nat.`-`: Nat -> Neg 和返回值不同。 +For example, Nat.`-`: Nat -> Neg and the return value is different. ### `!`|T <: Immut|(x: T) -> `T!` -从不可变对象创建可变对象。 -该运算符本身不是程序性的,可以在函数内部使用。 +Create a mutable object from an immutable object. +This operator itself is not procedural and can be used inside a function. ### `..`|T <: Ord|(x: T) -> Range T -在 x 的末尾创建一个没有下限的 Range 对象。 -x..x 仅返回 x 作为迭代器。 +Creates a Range object with no lower bound at the end of x. +x..x returns only x as an iterator. ### `..<`|T <: Ord|(x: T) -> Range T -x.. Range T -创建一个从 x 开始没有上限的 Range 对象。 +Creates a Range object with no upper bound starting at x. ### |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 index dfbdcff9..371b2f7c 100644 --- a/doc/zh_CN/API/procs.md +++ b/doc/zh_CN/API/procs.md @@ -1,34 +1,34 @@ -# 过程 +# procedures ## print! ``` erg -打印!(x)->无类型 +print!(x) -> NoneType ``` - 使用换行符返回 x。 + Returns x with a newline. -##调试&排除; +##debug! ``` erg -调试!(x,类型=信息)-> NoneType +debug!(x, type = Info) -> NoneType ``` -用换行符调试 x(文件名、行号、变量名一起显示)。 在发布模式中删除。 -支持表情符号的终端根据类型加前缀。 +Debug x with newline (file name, line number, variable name is displayed together). Removed in release mode. +Emoji-capable terminals are prefixed according to type. * type == Info: 💬 * type == Ok: ✅ * type == Warn: ⚠️ * type == Hint: 💡 -## for!i: Iterable T, block: T => NoneType +## for! i: Iterable T, block: T => NoneType -以块的动作遍历迭代器。 +Traverse the iterator with the action of block. -## while!cond: Bool!, block: () => NoneType +## while! cond: Bool!, block: () => NoneType -当cond为True时的执行块。 +Execute block while cond is True. ## Lineno!() -> Nat diff --git a/doc/zh_CN/API/special.md b/doc/zh_CN/API/special.md index 2a362bd0..698429dc 100644 --- a/doc/zh_CN/API/special.md +++ b/doc/zh_CN/API/special.md @@ -1,109 +1,109 @@ -# 特殊形式 +# Special form -特殊形式是不能在 Erg 类型系统中表达的运算符、子程序(等等)。它被`包围,但实际上无法捕获。 -此外,为方便起见,还出现了“Pattern”、“Body”和“Conv”等类型,但不存在此类类型。它的含义也取决于上下文。 +Special forms are operators, subroutines (and the like) that cannot be expressed in the Erg type system. It is surrounded by ``, but it cannot actually be captured. +Also, types such as `Pattern`, `Body`, and `Conv` appear for convenience, but such types do not exist. Its meaning also depends on the context. ## `=`(pat: Pattern, body: Body) -> NoneType -将 body 分配给 pat 作为变量。如果变量已存在于同一范围内或与 pat 不匹配,则引发错误。 -它还用于记录属性定义和默认参数。 +Assign body to pat as a variable. Raise an error if the variable already exists in the same scope or if it doesn't match pat. +It is also used in record attribute definitions and default arguments. -```erg +``` erg record = {i = 1; j = 2} f(x: Int, y = 2) = ... ``` -当主体是类型或函数时,`=` 具有特殊行为。 -左侧的变量名嵌入到右侧的对象中。 +`=` has special behavior when the body is a type or a function. +The variable name on the left side is embedded in the object on the right side. -```erg +``` erg print! Class() # > print! x: Int -> x + 1 # > C = Class() print! c # f = x: Int -> x + 1 print! f # -g x: Int = x + 1 +gx: Int = x + 1 print! g # -K X: Int = Class(...) +KX: Int = Class(...) print! K # L = X: Int -> Class(...) print! L # ``` -`=` 运算符的返回值为“未定义”。 -函数中的多个赋值和 `=` 会导致语法错误。 +The `=` operator has a return value of "undefined". +Multiple assignments and `=` in functions result in syntax errors. -``` 呃 -i = j = 1 # SyntaxError: 不允许多次赋值 +``` erg +i = j = 1 # SyntaxError: multiple assignments are not allowed print!(x=1) # SyntaxError: cannot use `=` in function arguments -# 提示:您的意思是关键字参数(`x: 1`)吗? +# hint: did you mean keyword arguments (`x: 1`)? if True, do: - i = 0 # SyntaxError: 块不能被赋值表达式终止 + i = 0 # SyntaxError: A block cannot be terminated by an assignment expression ``` ## `->`(pat: Pattern, body: Body) -> Func -生成匿名函数,函数类型。 +Generate anonymous functions, function types. ## `=>`(pat: Pattern, body: Body) -> Proc -生成匿名过程,过程类型。 +Generate anonymous procedure, procedure type. ## `:`(subject, T) -确定主题是否与 T 匹配。如果它们不匹配,则抛出编译错误。 +Determine if subject matches T. If they don't match, throw a compile error. -```erg +``` erg a: Int f x: Int, y: Int = x / y ``` -也用于 `:` 应用样式。 +Also used for `:` applied styles. -```erg -f x: +``` erg +fx: y z ``` -像`:`和`=`一样,运算的结果是不确定的。 +Like `:` and `=`, the result of the operation is undefined. -```erg -_ = x: Int # 语法错误: -print!(x: Int) # 语法错误: +``` erg +_ = x: Int # SyntaxError: +print!(x: Int) # SyntaxError: ``` ## `.`(obj, attr) -读取obj的属性。 -`x.[y, z]` 将 x 的 y 和 z 属性作为数组返回。 +Read attributes of obj. +`x.[y, z]` will return the y and z attributes of x as an array. ## `|>`(obj, c: Callable) -执行`c(obj)`。 `x + y |>.foo()` 与 `(x + y).foo()` 相同。 +Execute `c(obj)`. `x + y |>.foo()` is the same as `(x + y).foo()`. -### (x: Option T)`?` -> T | T +### (x: Option T)`?` -> T | T -后缀运算符。如果出现错误,请立即调用 `x.unwrap()` 和 `return`。 +Postfix operator. Call `x.unwrap()` and `return` immediately in case of error. ## match(obj, ...lambdas: Lambda) -对于 obj,执行与模式匹配的 lambda。 +For obj, execute lambdas that match the pattern. -```erg -match [1, 2, 3]: +``` erg +match[1, 2, 3]: (l: Int) -> log "this is type of Int" [[a], b] -> log a, b [...a] -> log a -# (1, 2, 3) +# (one two three) ``` ## del(x: ...T) -> NoneType | T -删除变量“x”。但是,无法删除内置对象。 +Delete the variable `x`. However, built-in objects cannot be deleted. -```erg +``` erg a = 1 del a # OK @@ -112,48 +112,48 @@ del True # SyntaxError: cannot delete a built-in object ## do(body: Body) -> Func -生成一个不带参数的匿名函数。 `() ->` 的语法糖。 +Generate an anonymous function with no arguments. Syntactic sugar for `() ->`. ## do!(body: Body) -> Proc -生成不带参数的匿名过程。 `() =>` 的语法糖。 +Generate an anonymous procedure with no arguments. Syntactic sugar for `() =>`. ## `else`(l, r) -> Choice -创建一个由两对组成的类元组结构,称为 Choice 对象。 -`l, r` 被懒惰地评估。也就是说,只有在调用 .get_then 或 .get_else 时才会计算表达式。 +Creates a tuple-like structure of two pairs called Choice objects. +`l, r` are evaluated lazily. That is, the expression is evaluated only when `.get_then` or `.get_else` is called. -```erg +``` erg choice = 1 else 2 assert choice.get_then() == 1 assert choice.get_else() == 2 assert True.then(choice) == 1 ``` -## 集合运算符 +## set operator ### `[]`(...objs) -从参数创建一个数组或从可选参数创建一个字典。 +Creates an array from arguments or a dict from optional arguments. ### `{}`(...objs) -从参数创建一个集合。 +Create a set from arguments. ### `{}`(...fields: ((Field, Value); N)) -生成记录。 +Generate a record. ### `{}`(layout, ...names, ...preds) -生成筛型,等级2型。 +Generates sieve type, rank 2 type. ### `...` -展开嵌套集合。它也可以用于模式匹配。 +Expand a nested collection. It can also be used for pattern matching. ``` erg -[x, ...y] = [1, 2, 3] +[x,...y] = [1, 2, 3] assert x == 1 and y == [2, 3] assert [x, ...y] == [1, 2, 3] assert [...y, x] == [2, 3, 1] @@ -162,14 +162,14 @@ assert x == 1 and yz == {y = 2; z = 3} assert {x; ...yz} == {x = 1; y = 2; z = 3} ``` -## 虚拟运算符 +## virtual operator -用户不能直接使用的运算符。 +Operators that cannot be used directly by the user. ### ref(x: T) -> Ref T | T -返回对对象的不可变引用。 +Returns an immutable reference to the object. -### ref!(x: T!) -> Ref!T! | T! +### ref!(x: T!) -> Ref! T! | T! -返回对可变对象的可变引用。 \ No newline at end of file +Returns a mutable reference to a mutable object. \ No newline at end of file diff --git a/doc/zh_CN/API/types.md b/doc/zh_CN/API/types.md index 7d564d92..2eba4b08 100644 --- a/doc/zh_CN/API/types.md +++ b/doc/zh_CN/API/types.md @@ -1,90 +1,90 @@ -# 内置 Erg 类型列表 +# List of built-in Erg types -类型本身的属性不存储在 `.__dict__` 中,不能从实例中引用 +Attributes of the type itself are not stored in the `.__dict__` and cannot be referenced from the instance -## 基本类型 +## Fundamental types -### 对象 +### Objects -* `__dir__`:将对象的属性作为数组返回(dir函数) -* `__getattribute__`: 获取并返回一个属性 -* `__hash__`:返回对象的哈希值 -* `__repr__`:对象的字符串表示(不存在丰富/默认实现) -* `__sizeof__`:返回对象的大小(包括在堆中分配的大小) +* `__dir__`: Returns the attributes of the object as an array (dir function) +* `__getattribute__`: get and return an attribute +* `__hash__`: returns the hash value of the object +* `__repr__`: string representation of the object (not rich/default implementation exists) +* `__sizeof__`: returns the size of the object (including the size allocated in the heap) -### 显示 +### Show -* `__str__`:返回对象的字符串表示(丰富) +* `__str__`: returns the string representation (rich) of the object -### Fmt +###Fmt -* `__format__`: 返回一个格式化的字符串 +* `__format__`: Returns a formatted string -### 文档 +### Doc -* `__doc__`:对象描述 +* `__doc__`: object description -### 命名 +### Named -* `__name__`: 对象的名称 +* `__name__`: the name of the object -### 泡菜 +### Pickles -* `__reduce__`: 用 Pickle 序列化对象 -* `__reduce_ex__`: __reduce__ 允许你指定协议版本 +* `__reduce__`: Serialize objects with Pickle +* `__reduce_ex__`: __reduce__ that allows you to specify the protocol version -## 对象系统 +## Object system -Trait 类相当于 Python 中的 ABC(抽象基类,接口) -实例属于1、True、“aaa”等。 -类是 Int、Bool、Str 等。 +Trait class is equivalent to ABC (abstract base class, interface) in Python +Instance belongs to 1, True, "aaa", etc. +Class is Int, Bool, Str, etc. -### 类型 +### Type -* `__supers__`:超类型(`__mro__` 是一个数组,但这个是一个 Set) +* `__supers__`: Supertypes (`__mro__` is an array, but this one is a Set) * `__basicsize__`: -* `__dictoffset__`:Evm 不支持 +* `__dictoffset__`: not supported by Evm * `__flags__`: -* `__itemsize__`:实例的大小(如果不是类,则为 0) -* `__weakrefoffset__`:Evm 不支持 -* `__membercheck__`: 相当于`ismember(x, T)` -* `__subtypecheck__`:等价于`issubtype(U, T)`,别名`__subclasshook__`(兼容CPython) +* `__itemsize__`: Size of instance (0 if not Class) +* `__weakrefoffset__`: not supported by Evm +* `__membercheck__`: equivalent to `ismember(x, T)` +* `__subtypecheck__`: Equivalent to `issubtype(U, T)`, with alias `__subclasshook__` (compatible with CPython) -### 实例 +### Instances -* `__class__`:返回创建实例的类(自动附加到使用 `.new` 创建的对象) +* `__class__`: Returns the class from which the instance was created (automatically attached to objects created with `.new`) ### Class -* `__mro__`:用于方法解析的类型数组(包括自身,始终以 Object 结尾) -* `__base__`:基本类型(`__mro__[1]` 如果有多个) -* `__new__`: 实例化 -* `__init__`: 初始化实例 -* `__init_subclass__`: 初始化实例 -* `__intstancecheck__`:使用类似于 `MyClass.__instancecheck__(x)`,等价于 `isinstance(x, MyClass)` -* `__subclasscheck__`:等价于 `issubclass(C, MyClass)` +* `__mro__`: Type array for method resolution (includes itself, always ends with Object) +* `__base__`: base type (`__mro__[1]` if there are multiple) +* `__new__`: instantiate +* `__init__`: Initialize the instance +* `__init_subclass__`: Initialize the instance +* `__intstancecheck__`: use like `MyClass.__instancecheck__(x)`, equivalent to `isinstance(x, MyClass)` +* `__subclasscheck__`: equivalent to `issubclass(C, MyClass)` -## 运算符 +## operator -此处指定以外的运算符没有特殊类型 +Operators other than those specified here have no special types -### 方程 +### Eq -* `__eq__(self, rhs: Self) -> Bool`: 对象比较函数 (==) -* `__ne__`: 对象比较函数 (!=),默认实现 +* `__eq__(self, rhs: Self) -> Bool`: object comparison function (==) +* `__ne__`: object comparison function (!=), with default implementation -### 秩序 +### Ord -* `__lt__(self, rhs: Self) -> Bool`: 对象比较函数 (<) -* `__le__`:对象比较函数(<=),默认实现 -* `__gt__`:对象比较函数(>),默认实现 -* `__ge__`:对象比较函数(>=),默认实现 +* `__lt__(self, rhs: Self) -> Bool`: Object comparison function (<) +* `__le__`: object comparison function (<=), with default implementation +* `__gt__`: object comparison function (>), with default implementation +* `__ge__`: object comparison function (>=), with default implementation -### BinAdd +### Bin Add -* 实现 `__add__(self, rhs: Self) -> Self`: `+` +* Implements `__add__(self, rhs: Self) -> Self`: `+` -### 添加R +### Add R * `__add__(self, rhs: R) -> Self.AddO` @@ -98,93 +98,93 @@ Trait 类相当于 Python 中的 ABC(抽象基类,接口) ### BinMul <: Mul Self -* `__pow__`:实现 `**`(默认实现) +* `__pow__`: implements `**` (with default implementation) ### Div R, O -* 实现 `__div__(self, rhs: Self) -> Self`: `/`,可能会因为 0 而恐慌 +* Implements `__div__(self, rhs: Self) -> Self`: `/`, may panic due to 0 ### BinDiv <: Div Self -* `__mod__`: 实现 `%` (默认实现) +* `__mod__`: implement `%` (with default implementation) -## 数值型 +## numeric type ### Num (= Add and Sub and Mul and Eq) -例如,除了Complex,Vector、Matrix和Tensor都是Num(Matrix和Tensor中的*分别与dot和product相同) +As an example other than Complex, Vector, Matrix, and Tensor are Num (* in Matrix and Tensor are the same as dot and product, respectively) ### Complex (= Inherit(Object, Impl := Num)) -* `imag: Ratio`:返回虚部 -* `real: Ratio`:返回实部 -* `conjugate self -> Complex`:返回复共轭 +* `imag: Ratio`: returns the imaginary part +* `real: Ratio`: returns the real part +* `conjugate self -> Complex`: returns the complex conjugate ### Float (= Inherit(FloatComplex, Impl := Num)) ### Ratio (= Inherit(Complex, Impl := Num)) -* `numerator: Int`: 返回分子 -* `denominator: Int`: 返回分母 +* `numerator: Int`: returns the numerator +* `denominator: Int`: Returns the denominator ### Int (= Inherit Ratio) ### Nat (= Inherit Int) -* `times!`: 运行 proc self 时间 +* `times!`: run the proc self times -## 其他基本类型 +## Other basic types -### 布尔值 +### Bool * `__and__`: * `__or__`: * `not`: -## 字符串 (<: 序列) +## Str (<: Seq) * `capitalize` -* `chomp`: 删除换行符 +* `chomp`: remove newline characters * `isalnum`: * `isascii`: * `isalpha`: * `isdecimal`: -* `isdight`: -* `isidentifier` -* `islower` -* `isnumeric` +* `is sight`: +* `is identifier` +*`islower` +* `is numeric` * `isprintable` * `isspace` -* `istitle` +* `is title` * `isupper` -* `lower` +*`lower` * `swapcase` * `title` * `upper` -## 其他 +## others -### 位 +### Bits -* `from_bytes`:从字节转换 -* `to_bytes`:转换为字节(指定长度和字节序(字节序)) -* `bit_length`:返回位长度 +* `from_bytes`: Convert from Bytes +* `to_bytes`: Convert to Bytes (specify length and endian (byteorder)) +* `bit_length`: returns bit length -### 可迭代 T +### Iterable T -请注意,它不是 `Iterator` 本身的类型。 `Nat` 是 `Iterable` 但你不能 `Nat.next()`,你需要 `Nat.iter().next()`。 +Note that it is not the type of `Iterator` itself. `Nat` is `Iterable` but you can't `Nat.next()`, you need to `Nat.iter().next()`. -* `iter`:创建一个迭代器。 +* `iter`: Create an Iterator. -### 迭代器 T +### Iterator T -Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter().fold (sum, n) -> sum + n*2`等是可能的。 -由于所有和任何在使用后都会被破坏,因此没有副作用。这些应该使用没有副作用的 `next` 来实现,但内部使用 `Iterator!.next!` 来提高执行效率。 +Nat and Range have Iterators, so `Nat.iter().map n -> n**2`, `(3..10).iter().fold (sum, n) -> sum + n*2` etc. are possible. +Since all and any are destroyed after use, there are no side effects. These are supposed to be implemented using `next` which has no side effects, but internally `Iterator!.next!` is used for execution efficiency. -* `next`:返回第一个元素和剩余的迭代器。 -* `all` -* `any` -* `filter` +* `next`: Returns the first element and the remaining Iterator. +*`all` +*`any` +*`filter` * `filter_map` * `find` * `find_map` @@ -192,21 +192,21 @@ Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter(). * `flatten` * `fold` * `for_each` -* `map` +*`map` * `map_while` * `nth` -* `pos` +*`pos` * `take` * `unzip` -* `zip` +*`zip` -### Iterator!T = IteratorT 和 ... +### Iterator!T = IteratorT and ... -* `next!`:获取第一个元素。 +* `next!`: Get the first element. -## SizedIterator T = 迭代器 T 和 ... +## SizedIterator T = Iterator T and ... -有限数量元素的迭代器。 +An Iterator over a finite number of elements. * `len`: * `chain`: @@ -221,42 +221,42 @@ Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter(). * `max`: * `min`: -## Seq T = SizedIterable T 和 ... +## Seq T = SizedIterable T and ... -* `concat`: 合并两个 Seq -* `__getitem__`:等同于使用 `[]` 访问(否则会出现恐慌) -* 与 `get`: __getitem__ 不同,它返回 Option -* `maketrans`:创建替换表(静态方法) -* `replace`: 替换 -* `translate`:根据替换表替换 -* `insert`: 添加到 idx -* `remove`: 删除 idx -* `prepend`: 前置 -* `dequeue`: 移除头部 -* `push`:添加到末尾 -* `pop`: 取尾巴 -* `dedup`:删除连续值 -* `uniq`:删除重复元素(通过 sort |> dedup 实现,因此顺序可能会改变) -* `swap`:交换元素 -* `reverse`:反转元素 -* `sort`: 排序元素 +* `concat`: Combine two Seqs +* `__getitem__`: Equivalent to accessing with `[]` (otherwise panics) +* Unlike `get`: __getitem__, it returns Option +* `maketrans`: Create a replacement table (static method) +* `replace`: replace +* `translate`: replace according to the replacement table +* `insert`: Add to idx +* `remove`: remove idx +* `prepend`: prepend +* `dequeue`: remove the head +* `push`: added to the end +* `pop`: take the tail +* `dedup`: remove consecutive values +* `uniq`: Remove duplicate elements (implemented by sort |> dedup, so order may change) +* `swap`: Swap elements +* `reverse`: reverse elements +* `sort`: sort elements * `first`: * `last`: -### Seq!T (= Seq T and ...) +### Seq! T (= Seq T and ...) * `__setitem__!`: * `__delitem__!`: -* `插入!`:添加到 idx -* `remove!`: 删除 idx -* `prepend!`:前置 -* `dequeue!`: 删除开头 -* `push!`:添加到末尾 -* `pop!`:拿尾巴 -* `dedup!`:删除连续值 -* `uniq!`: 删除重复元素(通过排序实现!|> dedup!,因此顺序可能会改变) -* `swap!`:交换元素 -* `reverse!`:反转元素 +* `insert!`: Add to idx +* `remove!`: remove idx +* `prepend!`: prepend +* `dequeue!`: remove the beginning +* `push!`: added to the end +* `pop!`: take the tail +* `dedup!`: remove consecutive values +* `uniq!`: Remove duplicate elements (implemented by sort! |> dedup!, so order may change) +* `swap!`: swap elements +* `reverse!`: reverse the element * `set!` -* `sort!`: 排序元素 +* `sort!`: sort elements * `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 index 1d020183..51902435 100644 --- a/doc/zh_CN/API/types/classes/Array!(T).md +++ b/doc/zh_CN/API/types/classes/Array!(T).md @@ -1,3 +1,4 @@ # Array! T -表示可变长度数组的类型。在编译时长度未知时使用。 有一个语法糖叫做` [t]!`。在`Array! T = ArrayWithMutLength! T, !_`中被定义 \ No newline at end of file +A type that represents a variable-length array. Use when the length is not known at compile time. There is a syntactic sugar called `[T]!`. +Defined by `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 index c186d029..78300991 100644 --- a/doc/zh_CN/API/types/classes/Array(T).md +++ b/doc/zh_CN/API/types/classes/Array(T).md @@ -1,3 +1,3 @@ # Array T: Type -由`Array T = ArrayWithLen T, _`定义。 有一种语法糖叫做`[T]`。 \ No newline at end of file +Defined by `Array T = ArrayWithLen T, _`. There is a syntactic sugar called `[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 index 3c1f20d1..c9dd51c3 100644 --- a/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md +++ b/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md @@ -1,34 +1,34 @@ # ArrayWithLen T: Type, N: Nat -`[T; N]`是语法糖。还有一个[`Array` 类型](./Array.md)省略了长度。 +`[T; N]` is syntactic sugar. There is also an [`Array` type](./Array.md) that omits the length. ## methods * values_at(self, selectors: [Nat; N]) -> [T; N] -```erg +``` erg assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] ``` * all(self, pred: T -> Bool) -> Bool - 返回是否所有元素都满足 pred。 - 如果元素为 0,则无论 pred 为 `True`,但会发出警告。 - 该规范本身已被多种语言采用,是逻辑一致性所必需的。 + Returns whether all elements satisfy pred. + If the element is 0, it will be `True` regardless of pred, but a Warning will be issued. + This specification itself has been adopted by many languages and is required for logical consistency. - ```erg - assert [].all(_ -> False) - ``` + ``` erg + assert[].all(_ -> False) + ``` - ```python - assert all(False for _ in []) - ``` + ```python + assert all(False for _in[]) + ``` ## methods of ArrayWithLen T, N | T <: Eq * freq self -> [{T: Nat}] - 返回对象出现的次数。 + Returns the frequency of occurrence of an object. -```erg +``` erg assert ["a", "b", "c", "b", "c", "b"].freq() \ == [{"a", 1}, {"b": 3}, {"c": 2}] -``` +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md index b219a60f..0a6fed5c 100644 --- a/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md +++ b/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md @@ -1,26 +1,34 @@ -# ArrayWithMutLength! T: Type, N: Nat! +# ArrayWithLen T: Type, N: Nat -一个可变长度数组,其长度在编译时已知。还有语法糖`ArrayWithMutLength(T, !N) == [T; !N]` +`[T; N]` is syntactic sugar. There is also an [`Array` type](./Array.md) that omits the length. ## methods -* push! ref! self(N ~> N+1, ...), elem: T +* values_at(self, selectors: [Nat; N]) -> [T; N] -* pop! ref! (N ~> N-1, ...) -> T +``` erg +assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] +``` -* sample!(ref! self) -> T -* sample! ref! self, M: Nat -> [T; M] - 随机选择里面的一个元素并返回一个副本 +* all(self, pred: T -> Bool) -> Bool + Returns whether all elements satisfy pred. + If the element is 0, it will be `True` regardless of pred, but a Warning will be issued. + This specification itself has been adopted by many languages and is required for logical consistency. -* shuffle!(ref! self) - 把里面的东西随机摆放 + ``` erg + assert[].all(_ -> False) + ``` -* assert_len ref! self(_ ~> N, ...), N: Nat -> () or Panic - 验证长度。 - `panic!` 如果长度无效。 + ```python + assert all(False for _in[]) + ``` -## Impl +## methods of ArrayWithLen T, N | T <: Eq -* From Range Int -* From [T; N] -* Num +* freq self -> [{T: Nat}] + Returns the frequency of occurrence of an object. + +``` erg +assert ["a", "b", "c", "b", "c", "b"].freq() \ +== [{"a", 1}, {"b": 3}, {"c": 2}] +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Complex.md b/doc/zh_CN/API/types/classes/Complex.md index 521b5b56..8e5bd75d 100644 --- a/doc/zh_CN/API/types/classes/Complex.md +++ b/doc/zh_CN/API/types/classes/Complex.md @@ -1,6 +1,6 @@ # Complex -表示复数的类型。 在 Erg 中表示数字的类型,例如 Float、Int 和 Nat,通常在顶部有这种类型 +A type that represents a complex number. Types that represent numbers in Erg, such as Float, Int, and Nat, usually have this type at the top. ## supers @@ -11,4 +11,4 @@ Num and Norm * abs * conjugate * imag -* real +* real \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Dict!.md b/doc/zh_CN/API/types/classes/Dict!.md index 0c5fa58e..8fa22607 100644 --- a/doc/zh_CN/API/types/classes/Dict!.md +++ b/doc/zh_CN/API/types/classes/Dict!.md @@ -1,7 +1,7 @@ # Dict! K, V -表示字典(哈希Map)的类型。 有一个语法糖叫做`{K: V}` +A type that represents a dictionary (hashmap). There is a syntactic sugar called `{K: V}`. ## methods -* invert!(self) -> Self! V, K +* invert!(self) -> Self! V, K \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Either.md b/doc/zh_CN/API/types/classes/Either.md index 900cc4d3..16f56740 100644 --- a/doc/zh_CN/API/types/classes/Either.md +++ b/doc/zh_CN/API/types/classes/Either.md @@ -1,6 +1,6 @@ # Either L, R = L or R -表示L或R的类型。 您可以将其视为Or类型的二元形式 +A type that represents "either L or R". You can think of it as a two-limited form of the Or type. ## methods @@ -9,4 +9,4 @@ * andl * andr * mapl -* mapr +* mapr \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Float.md b/doc/zh_CN/API/types/classes/Float.md index 02fe7aa8..387c4257 100644 --- a/doc/zh_CN/API/types/classes/Float.md +++ b/doc/zh_CN/API/types/classes/Float.md @@ -1,8 +1,8 @@ # Float size -表示实数(包含小数的数)的类型。符合IEEE 754的浮点数,在其他语言中一般是float的类型。 -Float的大小为8(1byte)~128(16byte)。如果只是Float,则表示`Float64`。 -Erg 中的 0.1 实际上属于 Ratio 类型,而不是 Float 类型。没有浮点类型字面量,它是由 `(Ratio object)f64` 生成的(例如 (1/2)f64, 15f64)。 f64 对应实数 1 +A type that represents real numbers (numbers with decimals). Represents an IEEE 754 compliant floating-point number and is the general equivalent of float in other languages. +The size of Float size is 8(1byte)~128(16byte). A simple Float represents `Float 64`. +0.1 in Erg actually belongs to the Ratio type, not the Float type. There is no Float type literal, it is generated by `(Ratio object)f64` (e.g. (1/2)f64, 15f64). f64 corresponds to the real number 1. ## supers @@ -11,11 +11,11 @@ Complex and Ord ## methods * sgn(self) -> {-1, 0, 1} - 返回标志 + returns the sign. * truncate(self) -> Int - 返回最接近自身的整数 + Returns the integer closest to itself. * separate(self) -> [Str] -* separate(self, dight: Nat) -> [Str] - 按digit位数划分。没有自变量 +* separate(self, date: Nat) -> [Str] + Separate by dight digits. 3 with no arguments. \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Function(N).md b/doc/zh_CN/API/types/classes/Function(N).md index 0955f2ec..e210780b 100644 --- a/doc/zh_CN/API/types/classes/Function(N).md +++ b/doc/zh_CN/API/types/classes/Function(N).md @@ -4,6 +4,6 @@ * then(self, g: Self) -> Self -```erg +``` erg assert f(g(x)) == f.then(g) x -``` +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Inf.md b/doc/zh_CN/API/types/classes/Inf.md index 0e7e02b9..cd8c3f71 100644 --- a/doc/zh_CN/API/types/classes/Inf.md +++ b/doc/zh_CN/API/types/classes/Inf.md @@ -1,7 +1,7 @@ # Inf -Inf是一个类,其唯一实例是inf。 -inf的主要用途是用于区间类型。 -例如,大于等于 2 的整数类型是 `2.. Self(L1+L2, R1+R2) -正常加法。 `Int` 和 `Nat` 的添加在此定义为假装它在每个类中定义 +normal addition. Addition of `Int` and `Nat` is defined here under the pretense that it is defined in each class. -```erg +``` erg 0..10 + 1..12 == 1..22 Int + 0..10 == _..|Int|_ + 0..10 == _..|Int|_ == Int Nat + Nat == 0.._ + 0.._ == 0.._ == Nat -``` +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Interval.md b/doc/zh_CN/API/types/classes/Interval.md index 001d85d6..5492537d 100644 --- a/doc/zh_CN/API/types/classes/Interval.md +++ b/doc/zh_CN/API/types/classes/Interval.md @@ -1,18 +1,18 @@ # Interval begin, end := WellOrder -表示有序集合类型 (WellOrder) 的子类型的类型。Interval 类型具有派生类型,例如 PreOpen(x<..y)。 +A type that represents a subtype of the well-ordered set type (WellOrder). The Interval type has derived types such as PreOpen(x<..y). -```erg +``` erg Months = 1..12 Alphabet = "a".."z" Weekdays = Monday..Friday Winter = November..December or January..February ``` -```erg -0..1 # 整数范围 -0.0..1.0 # 真实(有理)范围 -# 或 0/1..1/1 相同 +``` erg +0..1 # integer range +0.0..1.0 # real (rational) range +# or same for 0/1..1/1 ``` -计算机无法处理无限位数的数字,所以实数的范围实际上是有理数的范围。 \ No newline at end of file +Computers can't handle numbers with infinite digits, so the range of real numbers is actually the range of rational numbers. \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Matrix.md b/doc/zh_CN/API/types/classes/Matrix.md index 902029b2..eb926248 100644 --- a/doc/zh_CN/API/types/classes/Matrix.md +++ b/doc/zh_CN/API/types/classes/Matrix.md @@ -1,7 +1,7 @@ # Matrix T: Num, Shape: [M, N] -表示矩阵的类型。 它继承自 Tensor[M, N] +A type that represents a matrix. It inherits from Tensor[M, N]. ## def -Inherit Tensor T, [M, N] +Inherit Tensor T, [M, N] \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Nat.md b/doc/zh_CN/API/types/classes/Nat.md index afa30251..027d496a 100644 --- a/doc/zh_CN/API/types/classes/Nat.md +++ b/doc/zh_CN/API/types/classes/Nat.md @@ -1,10 +1,10 @@ # Nat -表示自然数的类型。 用于数组索引和范围类型 +A type that represents a natural number. Used for array indices and range types. -## def +##def -```erg +``` erg Nat = 0.._ ``` @@ -12,7 +12,7 @@ Nat = 0.._ * times!(self, p: () => NoneType) -> NoneType -```erg +``` erg 100.times! () => - print! "hello!" -``` + print! "hello!" +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Neg.md b/doc/zh_CN/API/types/classes/Neg.md index 7005a062..2c369f3c 100644 --- a/doc/zh_CN/API/types/classes/Neg.md +++ b/doc/zh_CN/API/types/classes/Neg.md @@ -1,8 +1,8 @@ # Neg -表示负整数的类型。 Pos和Neg和{0} == Int -它还具有一些值得注意的属性,例如不被零除和 Neg * Neg == Pos +A type that represents a negative integer. Pos and Neg and {0} == Int. +It also has some notable properties such as no division by zero and Neg * Neg == Pos. -## def +##def -Inf<..-1 +Inf<..-1 \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Never.md b/doc/zh_CN/API/types/classes/Never.md index 2f0cdd15..c6cdea6b 100644 --- a/doc/zh_CN/API/types/classes/Never.md +++ b/doc/zh_CN/API/types/classes/Never.md @@ -1,13 +1,13 @@ # Never -它是所有类型的子类型。 它是一个`Class`,因为它拥有所有的方法,当然还有 `.new`。但是,它没有实例,并且Erg会在即将创建的那一刻停止。 -还有一种叫做`Panic`的类型没有实例,但是`Never`用于正常终止或故意无限循环,`Panic`用于异常终止。 +It is a subtype of all types. It is a `Class` because it has all the methods and of course `.new`. However, it does not have an instance, and the Erg stops the moment it is about to be created. +There is also a type called `Panic` that does not have an instance, but `Never` is used for normal termination or an intentional infinite loop, and `Panic` is used for abnormal termination. -```erg +``` erg # 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 +The OR type of `Never`/`Panic`, eg `T or Never` can be converted to `T`. This is because `Never` is a semantically never-occurring option (if it does, the program stops immediately). +However, when using it in the return value type of a function, `or Never` cannot be omitted because it indicates that the program may terminate. \ 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 index 9a7d53b7..c54965f7 100644 --- a/doc/zh_CN/API/types/classes/NonZero.md +++ b/doc/zh_CN/API/types/classes/NonZero.md @@ -1,30 +1,30 @@ -# NonZero N +# NonZeroN -表示非零数的类。 保证除零的安全性 +A class that represents a non-zero number. The safety of division by zero is guaranteed. ```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 +class Diagram + 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 ``` ## methods @Impl SafeDiv R, O -.`/`: Self.(R) -> O +.`/`: Self.(R) -> O \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Object.md b/doc/zh_CN/API/types/classes/Object.md index 963f58f1..e7e2cf58 100644 --- a/doc/zh_CN/API/types/classes/Object.md +++ b/doc/zh_CN/API/types/classes/Object.md @@ -1,7 +1,7 @@ -# Object +# Objects -它是所有类型的超类型 +It is the supertype of all types. ## methods -* __sizeof__: Nat +* __sizeof__: Nat \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Operator.md b/doc/zh_CN/API/types/classes/Operator.md index 0b26bbe9..a22e91b9 100644 --- a/doc/zh_CN/API/types/classes/Operator.md +++ b/doc/zh_CN/API/types/classes/Operator.md @@ -1,7 +1,7 @@ # Operator [...T], O -是运算符的类型 +is the type of the operator. -## def +##def -Inherit Func [...T], O +Inherit Func [...T], O \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Option.md b/doc/zh_CN/API/types/classes/Option.md index 6eeb18b0..a66367d9 100644 --- a/doc/zh_CN/API/types/classes/Option.md +++ b/doc/zh_CN/API/types/classes/Option.md @@ -1,14 +1,14 @@ # Option T = T or NoneType -表示“可能失败”的类型。 +A type that represents "may fail". ## methods * unwrap(self, msg = "unwrapped a None value") -> T or Panic -提取它,期望内容是 `T` 类型。 如果是 `None`,则输出 `msg` 并恐慌 +Extract it expecting the contents to be `T` type. If it is `None`, output `msg` and panic. -```erg +``` erg 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 @@ -18,4 +18,4 @@ x.unwrap("failed to convert from string to number") # UnwrappingError: failed to * unwrap_or_exec(self, f: () -> T) -> T -* unwrap_or_exec!(self, p!: () => T) -> T +* unwrap_or_exec!(self, p!: () => T) -> T \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Pos.md b/doc/zh_CN/API/types/classes/Pos.md index 44831482..c3d4ca6a 100644 --- a/doc/zh_CN/API/types/classes/Pos.md +++ b/doc/zh_CN/API/types/classes/Pos.md @@ -1,8 +1,8 @@ # Pos -Pos是一种表示正数(大于或等于1的整数)的类型。 -由于不包括0,因此具有消除被零除的可能性等优点。 +Pos is a type that represents positive numbers (integers greater than or equal to 1). +Since 0 is not included, there are merits such as eliminating the possibility of division by zero. ## Def -`Pos = 1.._` +`Pos = 1.._` \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Ratio.md b/doc/zh_CN/API/types/classes/Ratio.md index 58b4211b..938357f3 100644 --- a/doc/zh_CN/API/types/classes/Ratio.md +++ b/doc/zh_CN/API/types/classes/Ratio.md @@ -1,5 +1,5 @@ -# Ratio +#Ratio -表示有理数的类型。 它主要用于当您要使用分数时。 -实际上,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类型之前,请进行真实的性能测试。 业余爱好者无条件偏爱较轻的模具。 +A type that represents a rational number. It is mainly used when you want to use fractions. +In fact, the / operator in Erg returns Ratio. 1/3 etc. is not evaluated as 0.33333... and is processed as 1/3. Also, 0.1 is equivalent to 1/10. So `0.1 + 0.2 == 0.3`. It sounds obvious, but in Python it is False. +However, the Ratio type tends to be slightly less efficient than the Float type. Float type should be used at the point where execution speed is important and the exact numerical value is not required. However, as Rob Pike says, premature optimization is the root of all evil. Do a real performance test before discarding the Ratio type and using the Float type. Amateurs unconditionally prefer lighter molds. \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Record.md b/doc/zh_CN/API/types/classes/Record.md index 4ff1126e..8e0bf5fc 100644 --- a/doc/zh_CN/API/types/classes/Record.md +++ b/doc/zh_CN/API/types/classes/Record.md @@ -1,14 +1,14 @@ # Record -记录所属的类。例如,`{i = 1}` 是`Structural {i = Int}` 类型的元素,并且是`{i = Int}` 类的实例 -请注意,其他类的实例是记录类型的元素,而不是记录类的实例 +Class to which the record belongs. For example, `{i = 1}` is an element of type `Structural {i = Int}`, and is an instance of the `{i = Int}` class. +Note that instances of other classes are elements of the record type but not instances of the record class. -```erg +``` erg assert not Structural({i = Int}) in Class assert {i = Int} in Class C = Class {i = Int} -c = C.new {i = 1} +c = C. new {i = 1} assert c in Structural {i = Int} assert not c in {i = Int} -``` +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Result.md b/doc/zh_CN/API/types/classes/Result.md index de89e41c..64824ce6 100644 --- a/doc/zh_CN/API/types/classes/Result.md +++ b/doc/zh_CN/API/types/classes/Result.md @@ -1,7 +1,7 @@ # Result T, E -```erg +``` erg Result T, E <: Error = Either T, E ``` -和 `Option` 一样,它代表“一个可能失败的值”,但它可以有失败的上下文。 用法与`Either`几乎相同。 \ No newline at end of file +Like `Option`, it represents "a value that may fail", but it can have the context of failure. Usage is almost the same as `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 index af0f1ee7..a790d1d3 100644 --- a/doc/zh_CN/API/types/classes/Str!.md +++ b/doc/zh_CN/API/types/classes/Str!.md @@ -1,3 +1,3 @@ -# StrWithLen! N: Nat! = Inherit StrWithLen N +# StrWithLen!N: Nat! = Inherit StrWithLenN -表示可变长度字符串的类型 +A type that represents a variable-length string. \ 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 index 9b4f21b8..5a185e01 100644 --- a/doc/zh_CN/API/types/classes/Str.md +++ b/doc/zh_CN/API/types/classes/Str.md @@ -1,9 +1,9 @@ # Str -(不变长度)表示字符串的类型。 简单的 `Str` 类型是删除了字符数的 `StrWithLen N` 类型(`Str = StrWithLen _`) +(Invariant length) A type that represents a string. The simple `Str` type is the `StrWithLen N` type with the number of characters removed (`Str = StrWithLen _`). ## methods -* isnumeric +*isnumeric -返回字符串是否为阿拉伯数字。 使用 `isunicodenumeric` 判断汉字数字和其他表示数字的字符(注意此行为与 Python 不同)。 \ No newline at end of file +Returns whether the string is an Arabic numeral. Use `isunicodenumeric` to judge kanji numerals and other characters that represent numbers (note that this behavior is different from Python). \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Subroutine.md b/doc/zh_CN/API/types/classes/Subroutine.md index 2350098c..c7533cac 100644 --- a/doc/zh_CN/API/types/classes/Subroutine.md +++ b/doc/zh_CN/API/types/classes/Subroutine.md @@ -1,19 +1,19 @@ -# Subroutine +# Subroutines -Func和Proc的基本类型。 +Base type of Func and Proc. ## methods * return -中断子程序并返回指定的值。 用于快速逃离嵌套 +Interrupts a subroutine and returns the specified value. Useful for quickly escaping from a nest. -```erg +``` erg f x = - for 0..10, i -> - if i == 5: - do - f::return i - do - log i -``` + for 0..10, i -> + if i == 5: + do + f::return i + do + log i +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Tensor.md b/doc/zh_CN/API/types/classes/Tensor.md index 131bb3c8..98488e92 100644 --- a/doc/zh_CN/API/types/classes/Tensor.md +++ b/doc/zh_CN/API/types/classes/Tensor.md @@ -1,16 +1,16 @@ # Tensor Shape: [Nat; N] - 用于有效操作多维数组的类。 它还定义了诸如多维数组上的乘法之类的操作 - Matrix、Vector 等都继承自该类型 + A class for efficiently manipulating multidimensional arrays. It also defines operations such as multiplication on multidimensional arrays. + Matrix, Vector, etc. inherit from this type. -```erg -Tensor.arange(0..9) # Tensor [10] +``` erg +Tensor.arrange(0..9) #Tensor[10] ``` * reshape(self, NewShape: [Nat; M]) -> Self NewShape -```erg -(1..9).into(Tensor).reshape [3, 3] +``` erg +(1..9).into(Tensor).reshape[3, 3] ``` * identity i: Nat -> Self shape: [Nat; N] @@ -20,5 +20,5 @@ Tensor.arange(0..9) # Tensor [10] * diag * linspace -* logspace -* geomspace +*logspace +* geomspace \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/TransCell(T).md b/doc/zh_CN/API/types/classes/TransCell(T).md index 078be645..9b042627 100644 --- a/doc/zh_CN/API/types/classes/TransCell(T).md +++ b/doc/zh_CN/API/types/classes/TransCell(T).md @@ -1,12 +1,12 @@ # TransCell! T: Type! -它是一个单元格,其内容可以针对每个模具进行更改。 由于它是T类型的子类型,因此它也表现为T类型 -当它在初始化时输入T时很有用,并且在某个点之后总是输入U +It is a cell whose contents can be changed for each mold. Since it is a subtype of T type, it also behaves as T type. +It's useful when it's type T at initialization, and it's always type U after a certain point. -```erg +``` erg a = TransCell!.new None a: TransCell! !NoneType a.set! 1 a: TransCell! !Int assert a + 1 == 2 -``` +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Tuple.md b/doc/zh_CN/API/types/classes/Tuple.md index b9b7667e..fb4b33ee 100644 --- a/doc/zh_CN/API/types/classes/Tuple.md +++ b/doc/zh_CN/API/types/classes/Tuple.md @@ -1,27 +1,27 @@ # Tuple T: ...Type -包含多种类型对象的集合 +A collection that holds objects of multiple types. ## methods * zip self, other - 组合两个有序集合(数组或元组) + Composites two ordered collections (arrays or tuples). - ```erg - assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4) - ``` + ``` erg + assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4) + ``` * zip_by self, op, other - 一种泛化 zip 的方法。 您可以指定一个二进制操作来组合 - `()`、`[]`、`{}`、`{:}` 也可以指定为运算符,分别生成元组、数组、集合和字典 - - ```erg - 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 - ``` + A method that generalizes zip. You can specify a binary operation to compose. + `()`, `[]`, `{}`, `{:}` can also be specified as operators, and generate tuples, arrays, sets, and dicts respectively. + + ``` erg + 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 + ``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Vector.md b/doc/zh_CN/API/types/classes/Vector.md index f9a159ed..ed14caa1 100644 --- a/doc/zh_CN/API/types/classes/Vector.md +++ b/doc/zh_CN/API/types/classes/Vector.md @@ -1,3 +1,3 @@ # Vector T: Num, N: Nat -表示向量的类型。与同名的Rust和C++类型不同,这种类型只处理数字。 \ No newline at end of file +A type that represents a vector. Unlike Rust and C++ types with the same name, this type only handles numbers. \ 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 index b10cd654..50374b29 100644 --- a/doc/zh_CN/API/types/patches/BinOp.md +++ b/doc/zh_CN/API/types/patches/BinOp.md @@ -1,7 +1,7 @@ # BinOp L, R, O -二元运算符的类型 +The type of the binary operator. ## Patches -Operator [L, R], O +Operator [L, R], O \ No newline at end of file diff --git a/doc/zh_CN/API/types/patches/UnaryOp.md b/doc/zh_CN/API/types/patches/UnaryOp.md index e06e07af..bdc35fe6 100644 --- a/doc/zh_CN/API/types/patches/UnaryOp.md +++ b/doc/zh_CN/API/types/patches/UnaryOp.md @@ -1,7 +1,7 @@ -# UnaryOp T, O +# Unary Op T, O -一元运算符的类型 +The type of the unary operator. -## def +##def -Operator [T], O +Operator [T], O \ No newline at end of file diff --git a/doc/zh_CN/API/types/traits/Add(R,O).md b/doc/zh_CN/API/types/traits/Add(R,O).md index 230d4f5c..952dd1b8 100644 --- a/doc/zh_CN/API/types/traits/Add(R,O).md +++ b/doc/zh_CN/API/types/traits/Add(R,O).md @@ -1,34 +1,34 @@ # Add R -```erg +``` erg Add R = Trait { - .AddO = Type - .`_+_` = (Self, R) -> Self.AddO + .AddO = Type + .`_+_` = (Self, R) -> Self.AddO } ``` -`Add`是一种定义加法的类型。加法有两种类型的`+`:方法和函数 -`+`作为二元函数,即`_+_`,定义如下: +`Add` is a type that defines addition. There are two types of `+` as addition: methods and functions. +`+` as a binary function, i.e. `_+_`, is defined as follows. -```erg +``` erg `_+_`(l: Add(R, O), r: R): O = l.`_+_` r ``` -这个定义的目的是让 `+` 可以被视为一个函数而不是一个方法 +The purpose of this definition is so that `+` can be treated as a function instead of a method. -```erg +``` erg assert [1, 2, 3].fold(0, `_+_`) == 6 call op, x, y = op(x, y) assert call(`_+_`, 1, 2) == 3 ``` -加法是这样输入的。 +Addition is typed like this. -```erg +``` erg 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 -``` +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/traits/Div(R,O).md b/doc/zh_CN/API/types/traits/Div(R,O).md index b0b5adf0..3f0906d6 100644 --- a/doc/zh_CN/API/types/traits/Div(R,O).md +++ b/doc/zh_CN/API/types/traits/Div(R,O).md @@ -1,9 +1,9 @@ # Div R, O -如果除以零没有错误,请使用“SafeDiv” +Use `SafeDiv` if there are no errors due to division by zero. -```erg +``` erg Div R, O = Trait { - .`/` = Self.(R) -> O or Panic + .`/` = Self.(R) -> O or Panic } -``` +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/traits/Into.md b/doc/zh_CN/API/types/traits/Into.md index 53c8e9a8..4b43a843 100644 --- a/doc/zh_CN/API/types/traits/Into.md +++ b/doc/zh_CN/API/types/traits/Into.md @@ -1,11 +1,11 @@ # Into T -一种类型,表明它可以被类型转换为类型T。 -即使Self和T之间没有继承关系,也是在关系可以相互转换的时候定义的。 -与继承不同,没有隐式转换。您必须始终调用 `.into` 方法。 +A type that indicates that it can be type-converted to type T. +Even if there is no inheritance relationship between Self and T, it is defined when the relationship is convertible to each other. +Unlike inheritance, there is no implicit conversion. You must always call the `.into` method. ## methods * into(self, T) -> T - 変換を行います。 + do the conversion. \ No newline at end of file diff --git a/doc/zh_CN/API/types/traits/Num.md b/doc/zh_CN/API/types/traits/Num.md index 5745c5ce..a49e9815 100644 --- a/doc/zh_CN/API/types/traits/Num.md +++ b/doc/zh_CN/API/types/traits/Num.md @@ -2,7 +2,7 @@ ## definition -```erg +``` erg Num R = Add(R) and Sub(R) and Mul(R) and Eq Num = Num Self ``` @@ -13,4 +13,4 @@ Add and Sub and Mul and Eq ## methods -* `abs` +*`abs` \ No newline at end of file diff --git a/doc/zh_CN/API/types/traits/SafeDiv(R,O).md b/doc/zh_CN/API/types/traits/SafeDiv(R,O).md index 54c3a1b1..d214d620 100644 --- a/doc/zh_CN/API/types/traits/SafeDiv(R,O).md +++ b/doc/zh_CN/API/types/traits/SafeDiv(R,O).md @@ -1,8 +1,8 @@ # SafeDiv R, O -```erg +``` erg SafeDiv R, O = Subsume Div, { - @Override - .`/` = Self.(R) -> O + @Override + .`/` = Self.(R) -> O } -``` +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/traits/Sample.md b/doc/zh_CN/API/types/traits/Sample.md index 93629a6a..a51d45ac 100644 --- a/doc/zh_CN/API/types/traits/Sample.md +++ b/doc/zh_CN/API/types/traits/Sample.md @@ -1,31 +1,31 @@ # Sample -具有“随机”选择实例的`sample`和`sample!`方法的特征。`sample`方法总是返回相同的实例,而`sample!`方法返回一个随机实例,该实例随调用而变化 +A trait that has a `sample` and `sample!` method that "randomly" picks an instance. The `sample` method always returns the same instance, and the `sample!` method returns a random instance that changes from call to call. -请注意,这是一个假设您想要一个适当的实例进行测试等的特征,并且它不一定是随机的。 如果您想要随机抽样,请使用“随机”模块。 +Note that this is a trait that assumes that you want an appropriate instance for testing, etc., and that it is not necessarily random. If you want random sampling, use the `random` module. -所有主要的值类都实现了 `Sample`。它还在由“Sample”类组成的元组类型、记录类型、Or类型和筛选类型中实现 +All major value classes implement `Sample`. It is also implemented in tuple types, record types, Or types, and sieve types that are composed of `Sample` classes. -```erg -assert Int.sample() == 42 -assert Str.sample() == "example" -# Int默认在64bit范围内采样 -print! Int.sample!() # 1313798 +``` erg +assert Int. sample() == 42 +assert Str. sample() == "example" +# Int is sampled in 64bit range by default +print! Int. sample!() # 1313798 print! {x = Int; y = Int}.sample!() # {x = -32432892, y = 78458576891} ``` -下面是一个`Sample`的实现示例 +Below is an implementation example of `Sample`. -```erg +``` erg EmailAddress = Class {header = Str; domain = Str}, Impl=Sample and Show @Impl Show -EmailAddress. +Email address. show self = "{self::header}@{self::domain}" @Impl Sample -EmailAddress. +Email address. 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} -``` + header = AsciiStr. sample!() + Self. new {header; domain} +``` \ No newline at end of file diff --git a/doc/zh_CN/API/types/traits/Unpack.md b/doc/zh_CN/API/types/traits/Unpack.md index 259beb3a..2b1c1d40 100644 --- a/doc/zh_CN/API/types/traits/Unpack.md +++ b/doc/zh_CN/API/types/traits/Unpack.md @@ -1,13 +1,13 @@ # Unpack -标记性状。实现时,元素可以像记录一样通过模式匹配来分解 +marker trait. When implemented, elements can be decomposed by pattern matching like records. -```erg -C = Class {i = Int}, Impl=Unpack +``` erg +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 -``` + (i: Int) -> i + ({i}: C) -> i +``` \ 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 index cf919c9f..a11955fa 100644 --- a/doc/zh_CN/compiler/TODO_recov_suggest.md +++ b/doc/zh_CN/compiler/TODO_recov_suggest.md @@ -5,7 +5,7 @@ * `Int and Str` => Multiple inheritance is not allowed, or `Int or Str`? * `: [1, 2]` => `: {1, 2}`? * `: [Int, 2]` => `: [Int; 2]`? -* `[Int; Str]` => `(Int, Str)` (Tuple) or `[Int: Str]` (Dict)? +* `[Int; Str]` => `(Int, Str)`(Tuple) or `[Int: Str]`(Dict)? * `{x: Int}` => `{x = Int}`? * `{x = Int}!` => `{x = Int!}`? -* `ref! immut_expr` => `ref!!immut_expr`? +* `ref! immut_expr` => `ref! !immut_expr`? diff --git a/doc/zh_CN/compiler/TODO_warn.md b/doc/zh_CN/compiler/TODO_warn.md index bc503a9f..0ba2ebf2 100644 --- a/doc/zh_CN/compiler/TODO_warn.md +++ b/doc/zh_CN/compiler/TODO_warn.md @@ -1,5 +1,5 @@ # warnings (not implemented yet) * `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)? +* `{I: Int | ...}!` => `{I: Int! | ...}` +* `return x`(`x != ()`) in for/while block => `f::return` (outer block)? diff --git a/doc/zh_CN/compiler/abandoned.md b/doc/zh_CN/compiler/abandoned.md index 2aca11d1..483fe374 100644 --- a/doc/zh_CN/compiler/abandoned.md +++ b/doc/zh_CN/compiler/abandoned.md @@ -1,10 +1,10 @@ -# 废弃/拒绝的语言规范 +# Abandoned/rejected language specifications -## 重载(临时多态性) +## Overloading (ad-hoc polymorphism) -被放弃了,因为它可以用参数+子类型多态来代替,并且与Python的语义不兼容。 有关详细信息,请参阅 [overload](../syntax/type/overloading.md) 文章。 +It was abandoned because it can be replaced by parametric + subtyping polymorphism, and it is incompatible with Python's semantics. See [overload](../syntax/type/overloading.md) article for details. -## 具有显式生命周期的所有权系统 +## Ownership system with explicit lifetime -原计划引入 Rust 之类的所有权系统,但由于与 Python 的语义不兼容以及需要引入生命周期注解等复杂规范而被放弃,并且所有不可变对象都是 RC。托管的可变对象现在只有一个所有权. -Dyne 没有 C# 和 Nim 那样的 GIL,策略是允许值对象和低级操作在安全范围内。 \ No newline at end of file +It was planned to introduce an ownership system like Rust, but it was abandoned due to its incompatibility with Python's semantics and the need to introduce complicated specifications such as lifetime annotations, and all immutable objects are RC. Managed, mutable objects now have only one ownership. +Dyne does not have a GIL like C# and Nim, and the policy is to allow value objects and low-level operations within a safe range. \ No newline at end of file diff --git a/doc/zh_CN/compiler/architecture.md b/doc/zh_CN/compiler/architecture.md index aca4bc0e..8db002b4 100644 --- a/doc/zh_CN/compiler/architecture.md +++ b/doc/zh_CN/compiler/architecture.md @@ -36,4 +36,4 @@ ## (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 index 6e241f3c..da4af20b 100644 --- a/doc/zh_CN/compiler/errors.md +++ b/doc/zh_CN/compiler/errors.md @@ -2,27 +2,27 @@ ## AssignError -尝试重写不可变变量时发生 +Raised when attempting to rewrite an immutable variable. ## AttributeError -尝试访问不存在的属性时发生 +Raised when trying to access an attribute that does not exist. ## PurityError -当您在不允许副作用的范围内(函数、不可变类型等)编写导致副作用的代码时发生 +Raised when writing code that causes side effects in scopes (functions, immutable types, etc.) where side effects are not allowed. ## MoveError -尝试访问已移动的变量时发生 +Raised when you try to access a variable that has already been moved. ## BorrowError -在存在对对象的借用时尝试获取可变引用时发生 +Raised when an attempt is made to obtain another variable reference while a borrow exists for an object. ## CyclicError -当你有一个明显不可阻挡的循环时发生 +Raised when there is an apparent non-stop cycle. ```erg i: Int = i @@ -38,58 +38,58 @@ U = T ## BytecodeError -当加载的字节码损坏时发生 +Raised if the bytecode read is corrupt. ## CompileSystemError -在编译器内部发生错误时发生 +Raised when an error occurs inside the compiler. ## EnvironmentError -如果您在安装期间没有访问权限,则会发生这种情况 +Raised when there is no access permission during installation. ## FeatureError -在检测到未正式提供的实验性功能时发生 +Raised when an experimental feature that is not officially provided is detected. ## ImportError ## IndentationError -检测到不良缩进时发生 -派生自SyntaxError +Raised when an invalid indentation is detected. +Derived from SyntaxError. ## NameError -当您访问不存在的变量时发生 +Raised when accessing a variable that does not exist. ## NotImplementedError -当您调用具有定义但没有实现的 API 时发生 -派生自 TypeError +Raised when calling an API that has a definition but no implementation. +Derived from TypeError. ## PatternError -当检测到非法模式时发生 -派生自SyntaxError +Raised when an invalid pattern is detected. +Derived from SyntaxError. ## SyntaxError -在检测到错误语法时发生 +Raised when an invalid syntax is detected. ## TabError -在使用制表符进行缩进/间距时发生 -派生自SyntaxError +Raised when a tab character is used for indentation/space. +Derived from SyntaxError. ## TypeError -当对象类型不匹配时发生 +Raised when the object type does not match. ## UnboundLocalError -在定义之前使用变量时发生 -更准确地说,它发生在以前使用过在范围内定义的变量时 +Raised when a variable is used before it is defined. +More precisely, it occurs when a variable defined in a scope is used before it is defined. ```erg i = 0 @@ -99,8 +99,8 @@ f x = y + i ``` -在这段代码中,`y = i + x` 中的 `i` 是一个未定义的变量 -但是,常量可以在定义之前在另一个函数中调用 +In this code, the `i` in `y = i + x` is an undefined variable. +However, if it is a constant, it can be called in another function before it is defined. ```erg f() = g() @@ -111,7 +111,7 @@ g() = f() ## SyntaxWarning -它在语法上很好,但是当我们检测到冗余或不常见的代码(不必要的 `()` 等)时就会发生这种情况 +This happens when syntactically sound but redundant or uncommon code is detected (e.g., unnecessary `()`). ```erg if (True): # SyntaxWarning: unnecessary parentheses @@ -120,12 +120,12 @@ if (True): # SyntaxWarning: unnecessary parentheses ## DeprecationWarning -在不推荐使用引用的对象时发生 -(开发人员在生成此警告时应始终提供替代方法作为提示) +Raised if the referenced object is deprecated. +(Developers should always provide an alternative Hint when raising this Warning.) ## FutureWarning -当您检测到将来可能导致问题的代码时发生 -此警告是由版本兼容性问题(包括库)以及语法和 API 的更改引起的 +Raised when code is detected that may cause problems in the future. +This warning is caused by version compatibility issues (including libraries) or changes in syntax or API. ## ImportWarning diff --git a/doc/zh_CN/compiler/hir.md b/doc/zh_CN/compiler/hir.md index 837b51a4..896e6e61 100644 --- a/doc/zh_CN/compiler/hir.md +++ b/doc/zh_CN/compiler/hir.md @@ -1,35 +1,35 @@ -# 高レベル中間表現(HIR, High-level Intermediate Representation) +# High-level Intermediate Representation (HIR) -HIR 是 Erg 编译器从 AST 生成的结构 -此结构包含源代码中每个表达式的完整类型信息,并且在语法上已脱糖 -AST与源代码一一对应(纯文本),但是HIR去掉了不必要的代码信息,添加了省略的类型信息,所以HIR可以转换为源代码很难恢复 -让我们在下面的代码中查看 HIR 的示例 +A HIR is a struct that the Erg compiler generates from an AST. +This struct contains the complete type information for every expression in the source code and is desugared syntactically. +AST has a one-to-one correspondence with the source code (as plain text), but HIR has unnecessary code information removed and omitted type information added, so HIR can be converted to source code is difficult to restore. +Let's see an example of HIR in the code below. -```erg +``` erg v = ![] for! 0..10, i => - v.push! i + v.push!i log v.sum() ``` -从此代码生成的 AST 如下所示: +The AST generated from this code looks like this: -```erg +``` erg AST(Module[ VarDef{ - sig: VarSignature{ + sig: VarSignature { pat: VarPattern::Ident(None, VarName("v")), spec_t: None, }, op: "=", body: Block[ - UnaryOp{ + Unary Op { op: "!", expr: Array([]), }, ], }, - Call{ + Call { obj: Accessor::Local("for!"), args: [ BinOp{ @@ -38,16 +38,16 @@ AST(Module[ rhs: Literal(10), }, Lambda{ - sig: LambdaSignature{ + sig: LambdaSignature { params: [ - ParamSignature{ + Param Signature { pat: ParamPattern::Name(VarName("i")), }, ], spec_ret_t: None, }, body: Block[ - Call{ + Call { obj: Accessor::Attr{"v", "push!"}, args: [ Accessor::Local("i"), @@ -57,10 +57,10 @@ AST(Module[ }, ], }, - Call{ + Call { obj: Accessor::Local("log"), args: [ - Call{ + Call { obj: Accessor::Attr("v", "sum"), args: [], } @@ -69,12 +69,12 @@ AST(Module[ ]) ``` -从 AST 生成的 HIR 如下所示: +And the HIR generated from the AST looks like this: -```erg +``` erg HIR(Module[ VarDef{ - sig: VarSignature{ + sig: VarSignature { pat: VarPattern::Ident(None, Name("v")), t: [0..10, _]!, }, @@ -87,7 +87,7 @@ HIR(Module[ }, ], }, - Call{ + Call { obj: Accessor::Local{ name: "for!", t: (Range Nat, Nat => NoneType) => NoneType, @@ -100,9 +100,9 @@ HIR(Module[ t: 0..10, }, Lambda{ - sig: LambdaSignature{ + sig: LambdaSignature { params: [ - ParamSignature{ + Param Signature { pat: ParamPattern::Name(Name("i")), t: 0..10, }, @@ -110,7 +110,7 @@ HIR(Module[ t: 0..10 => NoneType, }, body: Block[ - Call{ + Call { obj: Accessor::Attr{ obj: Accessor::Local("v"), field: "push!", @@ -124,13 +124,13 @@ HIR(Module[ }, ], }, - Call{ + Call { obj: Accessor::Local{ name: "log", t: ...Object => NoneType, }, args: [ - Call{ + Call { obj: Accessor::Attr{ obj: Accessor::Local("v"), field: "sum", @@ -144,5 +144,5 @@ HIR(Module[ ]) ``` -对象类型被推断为尽可能小。 另一方面,子例程推断实现存在的类型 -因此,实际参数的类型和形式参数的类型可能不匹配 \ No newline at end of file +Object types are inferred as small as possible. Subroutines, on the other hand, infer the type for which the implementation exists. +Therefore, the type of the actual argument and the type of the formal argument may not match. \ No newline at end of file diff --git a/doc/zh_CN/compiler/inference.md b/doc/zh_CN/compiler/inference.md index f5e8571e..4f513eb2 100644 --- a/doc/zh_CN/compiler/inference.md +++ b/doc/zh_CN/compiler/inference.md @@ -1,62 +1,70 @@ -# 类型推理算法 +# type inference algorithm -> :本节正在编辑中,可能包含某些错误。 +> __Warning__: This section is being edited and may contain some errors. -以下是使用的表示方法。 +The notation used below is shown. - -```erg -自由类型变量(类型,未绑定):?T, ?U,... -自由类型变量(值,未绑定):?a, ?b,... -输入环境 (Γ): { x: T,... } -类型分配规则 (S): { ?T --> T,...} -类型参数评估环境 (E): { e -> e',...} +``` erg +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', ... } ``` -下面的代码是一个示例。 +Let's take the following code as an example. - -```erg +``` erg v = ![] v.push! 1 print! v ``` -Erg 类型推理的主要框架是 Hindley-Milner 类型推理算法(但进行了各种扩展)。具体来说,类型推论是按照以下步骤进行的。术语描述将在后面介绍。 +Erg's type inference largely uses the Hindley-Milner type inference algorithm (although various extensions have been made). Specifically, type inference is performed by the following procedure. Terminology will be explained later. -1. 推断右边值的类型(search) -2. 使得到的类型具体化(instantiate) -3. 调用时进行类型赋值(substitute) -4. 体现单相特写(resolve traits) -5. 求值和简化类型变量值(eval) -6. 删除链接的类型变量(deref) -7. 对于可变依赖方法,传播更改(propagate) -8. 如果左侧值存在且可调用,则执行参数类型的一般化(generalize) -9. 如果有左侧值,则(返回值)类型一般化(generalize) -10. 如果赋值,则在符号表()中登记类型信息(update)。 +1. Infer the type of the rvalue (search) +2. instantiate the resulting type +3. If it is a call, perform type substitution (substitute) +4. Resolve traits that have already been monomorphized +5. Evaluate/reduce (eval) if there is a type variable value +6. Remove linked type variables (deref) +7. Propagate changes for mutable dependent methods +8. If there is an lvalue and it is Callable, generalize the argument type (generalize) +9. If there is an lvalue, generalize the (return value) type (generalize) +10. If it is an assignment, register the type information in the symbol table (`Context`) (update) -具体操作如下。 +The specific operations are as follows. line 1. Def{sig: v, block: ![]} get block type: get UnaryOp type: - get Array type: `['T; 0]`instantiate: `[?T; 0]`(substitute, eval are omitted) - update: `Γ: {v: [?T; 0]!}`expr returns `NoneType`: OK + getArray type: `['T; 0]` + instantiate: `[?T; 0]` + (substitute, eval are omitted) + update: `Γ: {v: [?T; 0]!}` + expr returns `NoneType`: OK -line 2. CallMethod{obj: v, name: push!, args: [1]} +line 2. CallMethod {obj: v, name: push!, args: [1]} get obj type: `Array!(?T, 0)` - search: `Γ Array!(?T, 0).push!({1})`get: `= Array!('T ~> 'T, 'N ~> 'N+1).push!('T) => NoneType`instantiate: `Array!(?T, ?N).push!(?T) => NoneType`substitute(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!(Nat) => NoneType`eval: `Array!(Nat, 0 ~> 1).push!({1}) => NoneType`update: `Γ: {v: [Nat; 1]!}` + search: `Γ Array!(?T, 0).push!({1})` + get: `= Array!('T ~> 'T, 'N ~> 'N+1).push!('T) => NoneType` + instantiate: `Array!(?T, ?N).push!(?T) => NoneType` + substitute(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!(Nat) => NoneType` + eval: `Array!(Nat, 0 ~> 1).push!({1}) => NoneType` + update: `Γ: {v: [Nat; 1]!}` expr returns `NoneType`: OK -line 3. Call{obj: print!, args: [v]} - get args type: `[[Nat; 1]!]`get obj type: - search: `Γ print!([Nat; 1]!)`get: `= print!(...Object) => NoneType` +line 3. Call {obj: print!, args: [v]} + get args type: `[[Nat; 1]!]` + get obj type: + search: `Γ print!([Nat; 1]!)` + get: `= print!(...Object) => NoneType` expr returns `NoneType`: OK -## 实现类型变量 - -类型变量最初在的中表示如下。虽然现在以不同的形式实现,但本质上是相同的想法,所以我用更简单的表达方式——这个实现来思考。的包装类型。 +## Implementation of type variables +Type variables were originally expressed as follows in `Type` of [ty.rs](../../src/common/ty.rs). It's now implemented in a different way, but it's essentially the same idea, so I'll consider this implementation in a more naive way. +`RcCell` is a wrapper type for `Rc>`. ```rust pub enum Type { @@ -66,150 +74,158 @@ pub enum Type { } ``` -类型变量可以实现在外部字典中具有实体类型,而类型变量本身仅具有该键。然而,使用实现通常更有效(需要验证,)。 +A type variable can be implemented by keeping the entity type in an external dictionary, and the type variable itself only has its keys. However, it is said that the implementation using `RcCell` is generally more efficient (verification required, [source](https://mobile.twitter.com/bd_gfngfn/status/1296719625086877696?s=21) ). -类型变量首先按进行初始化。此类型变量在代码分析过程中被重写,以确定类型。如果内容始终为 None,则会产生一个类型变量,不能(立即)确定为特定类型。例如,类型。我们将这种状态下的类型变量称为(确切术语未知)。与此相对,如果指定了某种特定类型,则称为。 +A type variable is first initialized as `Type::Var(RcCell::new(None))`. +This type variable is rewritten as the code is analyzed, and the type is determined. +If the content remains None until the end, it will be a type variable that cannot be determined to a concrete type (on the spot). For example, the type of `x` with `id x = x`. +I'll call a type variable in this state an __Unbound type variable__ (I don't know the exact terminology). On the other hand, we call a variable that has some concrete type assigned to it a __Linked type variable__. -这两种类型都是自由变量(很明显,我们认为这一术语是根据“自由变量”命名的)。这些是编译器用于推理的类型变量。这是因为它与程序员指定的类型变量不同,例如中的。 +Both are of the kind free type variables (the term is apparently named after "free variables"). These are type variables that the compiler uses for inference. It has such a special name because it is different from a type variable whose type is specified by the programmer, such as `'T` in `id: 'T -> 'T`. -未绑定变量应表示为和。在型理论的上下文中使用α和β的情况比较多,但是为了输入的简便化,采用了这个。请注意,这是一种用于一般讨论的符号,实际上并不是使用字符串标识符实现的。 +Unbound type variables are expressed as `?T`, `?U`. In the context of type theory, α and β are often used, but this one is used to simplify input. +Note that this is a notation adopted for general discussion purposes and is not actually implemented using string identifiers. -当未绑定的变量被置于类型环境中时,它被替换为。这就是我们所说的。它类似于程序员指定的类型变量,如。它的内容只是一个字符串,不像自由变量那样可以链接到特定类型。 +An unbound type variable `Type::Var` is replaced with a `Type::MonoQuantVar` when entering a type environment. This is called a __quantified type variable__. This is akin to the programmer-specified type variables, such as ``T``. The content is just a string, and there is no facility to link to a concrete type like a free-type variable. -将未绑定变量替换为量化变量的操作称为(或泛化)。如果仍然是未绑定的变量,则必须在一次调用中固定类型(例如,在调用后,的返回类型变为),因此必须将其一般化。这样,将在类型环境中注册包含量化变量的广义定义。 +The operation of replacing unbound type variables with quantified type variables is called __generalization__ (or generalization). If you leave it as an unbound type variable, the type will be fixed with a single call (for example, after calling `id True`, the return type of `id 1` will be `Bool`), so It has to be generalized. +In this way a generalized definition containing quantified type variables is registered in the type environment. -## 一般化、类型方案、具体化 +## generalizations, type schemes, reifications -将未绑定变量一般化的操作表示为。假设得到的广义变量为。在类型理论中,量化类型(例如,多相关数类型)通过在其前面加上来进行区分(例如,大块等符号称为(全称)量化器)。这种表达式(e.g.)称为类型方案。Erg 中的类型方案表示为等。类型方案通常不被视为一级类型。这样配置类型系统可能会导致类型推理无法正常工作。然而,在某些情况下,Erg 被视为主要类型。有关详细信息,请参见。 +Let's denote the operation of generalizing an unbound type variable `?T` as `gen`. Let the resulting generalized type variable be `|T: Type| T`. +In type theory, quantified types, such as the polycorrelation type `α->α`, are distinguished by prefixing them with `∀α.` (symbols like ∀ are called (generic) quantifiers. ). +Such a representation (e.g. `∀α.α->α`) is called a type scheme. A type scheme in Erg is denoted as `|T: Type| T -> T`. +Type schemes are not usually considered first-class types. Configuring the type system that way can prevent type inference from working. However, in Erg, it can be regarded as a first-class type under certain conditions. See [rank2 type](../syntax/type/advanced/rank2type.md) for details. -现在,当在类型推理中使用得到的类型方案(e.g.)时,必须取消一般化(e.g.)。这种反变换称为。我们将此操作称为。 +Now, when using the obtained type scheme (e.g. `'T -> 'T (id's type scheme)`) in type inference where it is used (e.g. `id 1`, `id True`), generalize must be released. This inverse transformation is called __instantiation__. We will call the operation `inst`. - -```erg +``` erg gen ?T = 'T inst 'T = ?T (?T ∉ Γ) ``` -重要的是,这两个操作都会替换该类型变量出现的所有位置。例如,如果将具体化,则得到。在实现过程中,需要 Dict 来替换它,但在一般化过程中,只需将链接到即可替换它。 +Importantly, both operations replace all occurrences of the type variable. For example, if you instantiate `'T -> 'T`, you get `?T -> ?T`. +A replacement dict is required for instantiation, but for generalization, just link `?T` with `'T` to replace it. -然后给出参数的类型,得到所需的类型。我们将此操作称为类型赋值(Type substitution),并将其表示为。此外,表示当表达式是调用时获得返回类型的操作。第一个参数是参数类型列表,第二个参数是目标类型。 +After that, give the type of the argument to get the target type. This operation is called type substitution, and will be denoted by `subst`. +In addition, the operation that obtains the return type if the expression is a call is denoted as `subst_call_ret`. The first argument is a list of argument types, the second argument is the type to assign to. -类型赋值规则表示将重写为同一类型。此操作称为也可以是类型变量。关于单一化的详细算法,请参见。单一化操作应表示为。 +The type substitution rule `{?T --> X}` means to rewrite `?T` and `X` to be of the same type. This operation is called __Unification__. `X` can also be a type variable. +A detailed unification algorithm is described in [separate section](./unification.md). We will denote the unify operation as `unify`. - -```erg +``` erg unify(?T, Int) == Ok(()) # ?T == (Int) -# Sは型代入規則、Tは適用する型 +# S is the type assignment rule, T is the applicable type subst(S: {?T --> X}, T: ?T -> ?T) == X -> X -# 型代入規則は{?T --> X, ?U --> T} +# Type assignment rules are {?T --> X, ?U --> T} subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y ``` -## 半单一化 +## semi-unification -单一化的一个亚种是半单一化(__Semi-unification__)。这是更新类型变量约束以满足子类型关系的操作。在某些情况下,类型变量可以是单一变量,也可以是不单一变量,因此称为“半”单一变量。 +A variant of unification is called semi-unification (__Semi-unification__). This is the operation that updates the type variable constraints to satisfy the subtype relation. +In some cases, type variables may or may not be unifying, hence the term "semi" unification. -例如,在赋值参数时会发生半单一化。实际参数类型必须是虚拟参数类型的子类型。如果参数的类型是类型变量,则必须更新子类型关系以满足该类型。 +Semi-unification occurs, for example, during argument assignment. +because the type of the actual argument must be a subtype of the type of the formal argument. +If the argument type is a type variable, we need to update the subtype relation to satisfy it. - -```erg -# 仮引数の型をTとすると +``` erg +# If the formal parameter type is T f(x: T): T = ... a: U -# U <: Tでなくてはならない、さもなければ型エラー +# must be U <: T, otherwise type error f(a) ``` -## 一般化 +## Generalization -一般化不是一项简单的工作。如果涉及多个范围,就需要对类型变量进行“级别管理”。为了了解等级管理的必要性,首先确认不引入等级管理的类型推理会产生问题。试着推论以下无名函数的类型。 +Generalization is not a simple task. When multiple scopes are involved, "level management" of type variables becomes necessary. +In order to see the necessity of level management, we first confirm that type inference without level management causes problems. +Infer the type of the following anonymous function. - -```erg +``` erg x -> y = x y ``` -首先,Erg 分配类型变量,如下所示。y 的类型也是未知的,但现阶段不指定它。 +First, Erg allocates type variables as follows: +The type of y is also unknown, but is left unassigned for now. - -```erg +``` erg x(: ?T) -> y = x y ``` -首先要确定的是右边值 x 的类型。右边的值是“使用”,因此它是具体化的。但是,x 的类型是一个自由变量,因此已经被具体化。因此,仍然是右边值的类型。 +The first thing to determine is the type of the rvalue x. An rvalue is a "use", so we reify it. +But the type `?T` of x is already instantiated because it is a free variable. Yo`?T` becomes the type of the rvalue. - -```erg +``` erg x(: ?T) -> y = x (: inst ?T) y ``` -在注册为类型 y 的左侧值时进行一般化。但是,稍后将会发现,这种一般化是不完整的,结果是错误的。 +Generalize when registering as the type of lvalue y. However, as we will see later, this generalization is imperfect and produces erroneous results. - -```erg +``` erg x(: ?T) -> - y(: gen ?T) = x (: ?T) + y(:gen?T) = x(:?T) y ``` - -```erg +``` erg x(: ?T) -> y(: 'T) = x y ``` -y 的类型现在是量化变量。在下一行中,被立即使用。具体化。 +The type of y is now a quantified type variable `'T`. In the next line, `y` is used immediately. Concrete. - -```erg +``` erg x: ?T -> y(: 'T) = x y(: inst 'T) ``` -需要注意的是,在实现过程中,必须生成与任何已存在的(自由)类型变量不同的(自由)类型变量(一般化也是如此)。这些类型变量称为新鲜类型变量。 +Note that instantiation must create a (free) type variable that is different from any (free) type variables that already exist (generalization is similar). Such type variables are called fresh type variables. - -```erg +``` erg x: ?T -> y = x y(: ?U) ``` -然后看得到的整个公式的类型。。但很明显,这个公式应该是,你会发现推理有问题。之所以会这样,是因为我们没有对类型变量进行“级别管理”。 +And look at the type of the resulting whole expression. `?T -> ?U`. +But obviously this expression should be `?T -> ?T`, so we know there is a problem with the reasoning. +This happened because we didn't "level manage" the type variables. -因此,使用以下符号引入类型变量的级别。级别以自然数表示。 +So we introduce the level of type variables with the following notation. Levels are expressed as natural numbers. - -```erg -# 通常のType型変数 +``` erg +# normal type variable ?T<1>, ?T<2>, ... -# 部分型制約を付けられた型変数 -?T<1>(<: U) or ?T(<: U)<1>, ... +# type variable with subtype constraint +?T<1>(<:U) or ?T(<:U)<1>, ... ``` -现在,我再试一次。 +Let's try again. - -```erg +``` erg x -> y = x y ``` -首先,按如下所示赋值级别变量。顶级级别为 1. 范围越深,等级就越高。函数的参数属于内部范围,因此它位于比函数本身大一个级别。 +First, assign a leveled type variable as follows: The toplevel level is 1. As the scope gets deeper, the level increases. +Function arguments belong to an inner scope, so they are one level higher than the function itself. - -```erg +``` erg # level 1 x (: ?T<2>) -> # level 2 @@ -217,85 +233,82 @@ x (: ?T<2>) -> y ``` -首先,将右边值具体化。和刚才一样,什么都不会改变。 +First, instantiate the rvalue `x`. Same as before, nothing changed. - -```erg +``` erg x (: ?T<2>) -> y = x (: inst ?T<2>) y ``` -从这里开始就是基莫。这是分配给类型左边值时的一般化。刚才这里的结果很奇怪,所以我们要改变广义算法。如果类型变量的级别小于或等于当前范围的级别,则一般化后将保持不变。 +Here is the key. This is a generalization when assigning to the type of lvalue `y`. +Earlier, the results were strange here, so we will change the generalization algorithm. +If the level of the type variable is less than or equal to the level of the current scope, generalization leaves it unchanged. - -```erg +``` erg gen ?T = if n <= current_level, then= ?T, else= 'T ``` - -```erg +``` erg x (: ?T<2>) -> # current_level = 2 - y (: gen ?T<2>) = x (: ?T<2>) + y(: gen ?T<2>) = x(: ?T<2>) y ``` -也就是说,左边值的类型为。 +That is, the lvalue `y` has type `?T<2>`. - -```erg +``` erg x (: ?T<2>) -> - # ↓ not generalized - y (: ?T<2>) = x + # ↓ not generalized + y(: ?T<2>) = x y ``` -y 的类型现在为未绑定变量。在下一行中进行说明。但是,类型并不通用,因此不会发生任何情况。 +The type of y is now an unbound type variable `?T<2>`. Concrete with the following lines: but the type of `y` is not generalized, so nothing happens. - -```erg +``` erg x (: ?T<2>) -> - y (: ?T<2>) = x + y(: ?T<2>) = x y (: inst ?T<2>) ``` - -```erg +``` erg x (: ?T<2>) -> y = x y (: ?T<2>) ``` -成功地得到了正确的类型。 +We successfully got the correct type `?T<2> -> ?T<2>`. -我再看一个例子。这是更常见的情况,函数,运算符应用,前向参照。 +Let's see another example. This is the more general case, with function/operator application and forward references. - -```erg -f x, y = id(x) + y +``` erg +fx, y = id(x) + y id x = x -f 10, 1 +f10,1 ``` -让我们一条一条地看。 +Let's go through it line by line. -在推论中,引用了后面定义的函数常量。在这种情况下,可以在之前插入一个声明,并分配一个自由变量。请注意,此时类型变量的级别为。这是为了避免在其他函数中被一般化。 +During the inference of `f`, the later defined function constant `id` is referenced. +In such a case, insert a hypothetical declaration of `id` before `f` and assign a free-type variable to it. +Note that the level of the type variable at this time is `current_level`. This is to avoid generalization within other functions. - -```erg +``` erg 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 ``` -类型变量之间的统一会将较高级别的类型变量替换为较低级别的类型变量。如果级别相同,这两个级别都可以。 +Unification between type variables replaces higher-level type variables with lower-level type variables. +It doesn't matter which one if the level is the same. -类型变量之间的半单一化,情况稍有不同。对于不同级别的类型变量,不能相互施加类型约束。 +Semiunification between type variables is a little different. +Type variables at different levels must not impose type constraints on each other. - -```erg +``` erg # BAD f x (: ?V<2>), y (: ?W<2>) = # ?V<2>(<: ?T<1>) @@ -303,71 +316,64 @@ f x (: ?V<2>), y (: ?W<2>) = id(x) (: ?U<1>) + y (: ?W<2>) ``` -这样,你就无法确定类型变量的具体体现位置。对于 Type 类型变量,请执行常规的单一化,而不是半单一化。也就是说,让他们单一化到低级别。 +This makes it impossible to determine where to instantiate the type variable. +For Type type variables, normal unification is performed instead of semi-unification. +In other words, unify to the lower level. - -```erg +``` erg # OK f x (: ?V<2>), y (: ?W<2>) = # ?V<2> --> ?T<1> id(x) (: ?U<1>) + y (: ?W<2>) ``` - -```erg +``` erg 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) + (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], inst |'L <: Add('R)| ('L, 'R) -> 'L .AddO) ``` - -```erg +``` erg 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) + (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], (?L(<: Add(?R<2>))<2>, ?R<2 >) -> ?L<2>.AddO) ``` - -```erg +``` erg id: ?T<1> -> ?U<1> f x (: ?T<1>), y (: ?W<2>) = - # ?U<1>(<: Add(?W<2>)) # 继承 ?L 的约束 + # ?U<1>(<: Add(?W<2>)) # Inherit the constraints of ?L # ?L<2> --> ?U<1> - # ?R<2> --> ?W<2> (?R(:> ?W), ?W(<: ?R)とはしない) + # ?R<2> --> ?W<2> (not ?R(:> ?W), ?W(<: ?R)) (id(x) + x) (: ?U<1>.AddO) ``` - -```erg +``` erg # current_level = 1 f(x, y) (: gen ?T<1>, gen ?W<2> -> gen ?U<1>.AddO) = id(x) + x ``` - -```erg +``` erg id: ?T<1> -> ?U<1> f(x, y) (: |'W: Type| (?T<1>, 'W) -> gen ?U<1>(<: Add(?W<2>)).AddO) = id(x) + x ``` - -```erg +``` erg f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) = id(x) + x ``` -在定义时进行升级以使其一般化。 +When defining, raise the level so that it can be generalized. - -```erg +``` erg # ?T<1 -> 2> # ?U<1 -> 2> id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>) ``` -如果已分配返回类型,则将返回类型与返回类型合并()。 +If the return type has already been assigned, unify with the resulting type (`?U<2> --> ?T<2>`). - -```erg +``` erg # ?U<2> --> ?T<2> f(x, y) (: |'W: Type| (?T<2>, 'W) -> ?T<2>(<: Add(?W<2>)).AddO) = id(x) + x @@ -375,62 +381,58 @@ f(x, y) (: |'W: Type| (?T<2>, 'W) -> ?T<2>(<: Add(?W<2>)).AddO) = id(x) (: gen ?T<2> -> gen ?T<2>) = x (: ?T<2>) ``` -如果一个类型变量只是一个类型变量,则它所依赖的类型变量也是一个类型变量。一般化类型变量在每个函数中都是独立的。 +If the type variable has been instantiated into a simple Type variable, +The type variable that depends on it will also be a Type type variable. +Generalized type variables are independent for each function. - -```erg +``` erg f(x, y) (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = id(x) + x id(x) (: |'T: Type| 'T -> gen 'T) = x ``` - -```erg +``` erg 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) +f(10, 1) (: subst_call_ret([inst {10}, inst {1}], inst |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T .AddO) ``` - -```erg -f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<1>) -> ?T<1>.AddO)) +``` erg +f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<1>) -> ? T<1>.AddO)) ``` -类型变量将扩展到其实现的最小类型。 +Type variables are bounded to the smallest type that has an implementation. - -```erg +``` erg # ?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 相对于第一个参数是协变的 +# The minimal implementation trait for Add(?W)(:> ?V) is Add(Nat) == Nat, since Add is covariant with respect to the first argument # {10} <: ?W<1> or {1} <: ?T<1> <: Add(?W<1>) <: Add(Nat) == Nat -# ?T(:> ?W(:> {10}) or {1}, <: Nat).AddO == Nat # 如果只有一个候选人,则固定评分 +# ?T(:> ?W(:> {10}) or {1}, <: Nat).AddO == Nat # If there is only one candidate, finalize the evaluation f(10, 1) (: (?W(:> {10}, <: Nat), ?W(:> {1})) -> Nat) -# 程序到此结束,所以去掉类型变量 +# This is the end of the program, so remove the type variable f(10, 1) (: ({10}, {1}) -> Nat) ``` -因此,整个程序的类型是这样的。 +The resulting type for the entire program is: - -```erg +``` erg 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 ``` -重新提示原始未显式输入的程序。 +I've also reprinted the original, unexplicitly typed program. - -```erg -f x, y = id(x) + y +``` erg +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 index 2da9366e..8cd43ef0 100644 --- a/doc/zh_CN/compiler/overview.md +++ b/doc/zh_CN/compiler/overview.md @@ -1,36 +1,36 @@ -# 概览 +# overview of `erg` -介绍每个图层的工作方式以及特别重要的函数和方法。 +We will introduce the function of each layer and the particularly important functions and methods. -## 1. 词法分析 +## 1. Lexical Analysis -* 执行词法分析。(作为迭代器实现)是词法分析的主要逻辑。将输出作为分析的结果。 +* The `Lexer` does the lexical analysis. `Lexer::next` (`Lexer` is implemented as an iterator) is responsible for the main logic of lexical analysis. `Token` is output as a result of parsing. -## 2. 语法分析 +## 2. Parsing -* 执行解析。尤其重要的是。作为分析的结果,将输出,它是的集合。 +* `Parser` does the parsing. Of particular importance is `Parser::parse_expr`. As a result of parsing, `AST` which is a collection of `ast::Expr` is output. -## 3. 脱糖 +## 3. Desugaring -* 进行脱糖。将输出。 +* Desugaring is done by `Desugarer`. `AST` will be output. -## 4. 类型检查/类型推理 +## 4. Type checking/type inference -* 用于输入数据。类型检查主要通过进行。特别重要的是(确定子类型关系),(对类型变量进行单一化/半单一化)和(定义嵌入式 API)。将输出作为分析的结果。 +* `ASTLowerer` does the typing. Type checking is primarily done by the `Context`. Especially important are `Context::supertype_of` (determine subtype relation), `Context::unify/sub_unify` (unify/semi-unify type variables), `Context::init_builtin_*`( defines built-in APIs). `HIR` is output as a result of analysis. -## 5. 副作用检查 +## 5. Side effect check -* 。 +* `SideEffectChecker` does. -## 6. 所有权检查 +## 6. Ownership check -* 。 +* `OwnershipChecker` does. -## 7. 字节码生成 +## 7. Bytecode Generation -* 将转换为保留字节码和执行设置。尤其重要的是。 +* `CodeGenerator` converts `HIR` to `CodeObj`. `CodeObj` holds bytecode and execution configuration. Of particular importance is `CodeGenerator::compile_expr`. --- -* 所有这些操作都由作为外立面进行总结。 -* 生成的字节码当然由 Python 执行,但它被称为。 +* All the above processing is put together by the `Compiler` as a facade. +* Of course Python executes the generated bytecode, which is called `DummyVM`. \ No newline at end of file diff --git a/doc/zh_CN/compiler/parsing.md b/doc/zh_CN/compiler/parsing.md index 54e8a20e..59d11bac 100644 --- a/doc/zh_CN/compiler/parsing.md +++ b/doc/zh_CN/compiler/parsing.md @@ -1,9 +1,9 @@ -# 解析 Erg 语言 +# Parsing the Erg language -## 处理空白 - -在 Erg 的语法中,特别的是 space-sensitive(根据空白进行区分)这一点。这是为了弥补的省略导致的表现力下降。同样的语法也可以在可以省略的 Nim 中看到。 +## Treatment of whitespace +A peculiarity of Erg's grammar is that it is space-sensitive. +This is to compensate for the loss of expressiveness caused by the omission of `()`. A similar syntax is found in Nim, which also allows the omission of `()`. ```erg f +1 == f(+1) @@ -14,18 +14,20 @@ f(1,) == f(1) (f() -> ...) == (f() -> ...) ``` -## 左侧值,右侧值 - -在 Erg 中,所谓左边值并不是的左侧这样简单的值。实际上,的左侧也存在右边值(非常容易混淆),的右侧也存在左边值。甚至在右边值中存在左边值。 +## Left-hand side value, right-hand side value +In Erg, left-hand side values are not as simple as the left-hand side of `=`. +In fact, there is (very confusingly) a right-sided value on the left side of `=`, and a left-sided value on the right side of `=`. +There can even be a left-side value within a right-side value. ```erg -# iは左辺値、Array(Int)と[1, 2, 3]は右辺値 +# i is the left-hand side value, Array(Int) and [1, 2, 3] are the right-hand side values i: Array(Int) = [1, 2, 3] -# `[1, 2, 3].iter().map i -> i + 1`は右辺値だが、->の左側のiは左辺値 +# `[1, 2, 3].iter().map i -> i + 1` is the right-hand side value, but i to the left of -> is the left-hand side value a = [1, 2, 3].iter().map i -> i + 1 -# {x = 1; y = 2}は右辺値だが、x, yは左辺値 +# {x = 1; y = 2} is the right side value, but x, y are the left side values r = {x = 1; y = 2} ``` -左边值、右边值的正确定义是“如果可以评价的话是右边值,如果不是的话是左边值”。以这一代码为例。第 2 个是可以评价的右边值,第 1 个是左边值。 +The precise definition of left- and right-hand side values is "right-hand side value if it is evaluable, otherwise left-hand side value". +As an example, consider the code ``i = 1; i``, where the second `i` is a right-sided value because it is evaluable, but the first `i` is a left-sided value. diff --git a/doc/zh_CN/compiler/refinement_subtyping.md b/doc/zh_CN/compiler/refinement_subtyping.md index c761154d..f6695330 100644 --- a/doc/zh_CN/compiler/refinement_subtyping.md +++ b/doc/zh_CN/compiler/refinement_subtyping.md @@ -1,19 +1,18 @@ -# 筛子型 +# Sieve type -筛型是指以下类型。 +The sieve type is the following type. - -```erg +``` erg {I: Int | I >= 0} {S: StrWithLen N | N >= 1} {T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0} ``` -在 Erg 中,通过将 Enum,Interval 型转换为筛子型,可以进行型的判定。 +Erg enables type determination by converting Enum and Interval types into sieve types. -## 转换为筛子类型 +## Convert to sieve type -在 [筛型] 一项中,区间型和列举型是筛型的糖衣句法。分别进行如下变换。 +In the section [Sieve types], we said that interval types and enum types are syntactic sugar for sieve types. Each is converted as follows. * {0} -> {I: Int | I == 0} * {0, 1} -> {I: Int | I == 0 or I == 1} @@ -24,37 +23,36 @@ * {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 的亚型的算法。在形式上,(所有)子类型确定定义如下。 +## Sieve type detection +An algorithm for determining whether a sieve type A is a subtype of another sieve type B is described. Formally, (all) subtyping is defined as follows: ```console A <: B <=> ∀a∈A; a ∈ B ``` -具体应用以下推论规则。布尔式简化完毕。 +Specifically, the following inference rules are applied. Boolean expressions are assumed to be simplified. -* 区间化规则(根据类型定义自动执行) +* intervalization rules (done automatically from type definition) * `Nat` => `{I: Int | I >= 0}` -* 切上规则 +* Round-up rule * `{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+ ε}` -* 反转规则 + * `{R: Ratio | R > n}` => `{R: Ratio | R >= n+ε}` +* reversal rule * `{A not B}` => `{A and (not B)}` -* 德-摩根定律 +* De Morgan's Law * `{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})` +* Distribution rule + * `{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})` -* 终止规则 +* termination rule * {I: T | ...} <: T = True * {} <: _ = True * _ <: {...} = True @@ -64,42 +62,41 @@ A <: B <=> ∀a∈A; a ∈ B * {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 >= a and I <= b} (a <= b) <: {I >= c or I <= d} (c > d) = ((a >= c) or (b <= d )) + * basic formula * {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。 +The simplification rules for Boolean expressions are as follows. min, max may not be removed. Also, multiple or, and are converted to nested min, max. -* 排序规则 +* ordering rules * `I == a` => `I >= a and I <= a` - * `i!= a` => `I >= a+1 or I <= a-1` -* 恒真规则 + * `i != a` => `I >= a+1 or I <= a-1` +* Consistency rule * `I >= a or I <= b (a < b)` == `{...}` -* 恒伪规则 +* Constancy rule * `I >= a and I <= b (a > b)` == `{}` -* 更换规则 - * 顺序表达式按,的顺序进行替换。 -* 延长规则 +* replacement rule + * Replace order expressions in the order `I >= n` and `I <= n`. +* Extension rule * `I == n or I >= n+1` => `I >= n` * `I == n or I <= n-1` => `I <= n` -* 最大规则 +* maximum rule * `I <= m or I <= n` => `I <= max(m, n)` * `I >= m and I >= n` => `I >= max(m, n)` -* 最小规则 +* minimum rule * `I >= m or I >= n` => `I >= min(m, n)` * `I <= m and I <= n` => `I <= min(m, n)` -* 删除规则 - * 左边的,在右边有时可以去除。 - * 如果不能移除左边的所有等式,则返回 False +* elimination rule + * `I == n` on the left side is removed when `I >= a (n >= a)` or `I <= b (n <= b)` or `I == n` on the right side can. + * False if all left-hand equations cannot be eliminated e.g. - ```python -1.._ <: Nat +1.._<: Nat => {I: Int | I >= 1} <: {I: Int | I >= 0} => {I >= 1} <: {I >= 0} => (I >= 0 => I >= 1) @@ -109,7 +106,6 @@ e.g. # {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} @@ -118,7 +114,6 @@ e.g. => False ``` - ```python {I: Int | I >= 0} <: {I: Int | I >= -3 and I <= 1} => {I >= 0} <: {I >= -3 and I <= 1} @@ -127,29 +122,28 @@ e.g. => 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} +=> {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} +=> {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} +=> {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 +=> 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 index 1dcd995e..f0d8b1a6 100644 --- a/doc/zh_CN/compiler/trait_method_resolving.md +++ b/doc/zh_CN/compiler/trait_method_resolving.md @@ -1,27 +1,33 @@ -# 解决修补程序方法 +# Resolving patch methods -是大于 0 的,即的子类型。本来不存在于 Python 的类阶层中。Erg 如何解决这个补丁的方法呢? +`Nat` is zero or more `Int`, a subtype of `Int`. +`Nat` does not exist in the Python class hierarchy. I wonder how Erg solves this patch method? - -```erg +``` erg 1.times do: - log "hello, world" + log "hello world" ``` -是的补丁方法。由于的实例,所以首先要沿着的 MRO(方法解析顺序)进行搜索。Erg 在的 MRO 中有。它来自 Python(在 Python 中)。方法在这两个方法中都不存在。从这里开始,进入该子类型的探索。 +`.times` is a `NatImpl` patch method. +Since `1` is an instance of `Int`, it is first searched by tracing the MRO (Method Resolution Order) of `Int`. +Erg has `Int`, `Object` in the MRO of `Int`. It comes from Python (`int.__mro__ == [int, object]` in Python). +The `.times` method does not exist in either of them. Now let's explore that subtype. ~ -整数在其上位型中显然应该具有实数和复数,甚至是整体数,但在与 Python 具有互换性的层中却不出现这一事实。但是实际上在 Erg 中,和。至于,虽然是与没有继承关系的类,但作为类型被判断为具有互换性。究竟是怎么回事? +Integers should obviously have reals, complexes, and even whole numbers in their supertypes, but that fact does not appear in the Python-compatible layer. +However, `1 in Complex` and `1 in Num` are actually `True` in Erg. +As for `Complex`, even though it is a class that does not have an inheritance relationship with `Int`, it is judged to be compatible as a type. What the hell is going on? ~ -对于某个对象,其所属的类型有无数个。但是实际上必须考虑的是拥有方法的类型,即只有拥有名字的类型。 +An object has an infinite number of types to which it belongs. +But we really only have to think about types with methods, i.e. types with names. -Erg 编译器拥有所有提供方法及其安装的补丁型散列映射。每次新定义类型时,此表都会更新。 +The Erg compiler has a hashmap of patch types with all provided methods and their implementations. +This table is updated each time a new type is defined. - -```erg +``` erg provided_method_table = { ... "foo": [Foo], @@ -31,46 +37,49 @@ provided_method_table = { } ``` -具有方法的类型为。从这些中,寻找符合型的。符合判定有两种。筛型判定和记录型判定。从筛型判定开始进行。 +Types that have a `.times` method are `Nat`, `Foo`. From among these, find one that matches the `{1}` type. +There are two types of conformity determination. They are sieve-type judgment and record-type judgment. This is done from the sieve type determination. -## 筛子型判定 +## Sieve type determination -检查候选类型是否与类型兼容。筛型中与兼容的有等。等有限元的代数运算类型,如果声明为基本类型,则被归一化为筛子类型(即,)。在这次的情况下,由于,所以是兼容的。 +Check if the candidate type is compatible with the type `{1}` of `1`. The sieve types compatible with `{1}` are `{0, 1}`, `0..9`, and so on. +Finite element algebraic types such as `0..1 or 3..4`, `-1..2 and 0..3` are normalized to sieve types when declared as base types (i.e. ` {0, 1, 3, 4}`, `{0, 1, 2}`). +In this case, `Nat` is `0.._ == {I: Int | I >= 0}`, so `{1}` is compatible with `Nat`. -## 记录类型判定 +## Determine record type -确认是否与候选类型为 1 的类兼容。此外,当的补丁,并且具有所有的要求属性时,也具有兼容性。 +Check if the candidate type is compatible with `Int`, a class of 1. +Others that are patches of `Int` and that `Int` has all the required attributes are also compatible. ~ -因此,是合适的。但是,当也符合时,根据的包含关系进行判定。也就是说,选择子类型的方法。如果两者没有包含关系,则会出现编译错误(这是一种安全措施,可防止执行与程序员意图相反的方法)。为了消除错误,必须明确指定修补程序。 +So `Nat` fit. However, if `Foo` also matches, it is determined by the containment relationship between `Nat` and `Foo`. +That is, subtype methods are selected. +If there is no containment relationship between the two, a compile error will occur (this is a safety measure against executing a method against the programmer's intention). +To eliminate the error, you need to specify the patch explicitly. - -```erg +``` erg o.method(x) -> P.method(o, x) ``` -## 全称补丁程序方法解析 +## method resolution for universal patches -定义如下补丁。 +Define a patch like this: - -```erg +``` erg FnType T: Type = Patch T -> T FnType.type = T ``` -在补丁的基础上可以进行以下代码。这又将如何解决呢? +Code like the following is possible under the `FnType` patch. I wonder how this will be resolved. - -```erg +``` erg assert (Int -> Int).type == Int ``` -首先,中以以下形式登录。 +First, `FnType(T)` is registered in `provided_method_table` in the following format. - -```erg +``` erg provided_method_table = { ... "type": [FnType(T)], @@ -78,9 +87,9 @@ provided_method_table = { } ``` -检查是否符合的补丁类型。此时,的补丁类型为。这符合。匹配后,进行单相化置换(取的 diff。)。 +`FnType(T)` is checked for matching types. In this case, `FnType(T)` patch type is `Type -> Type`. +This matches `Int -> Int`. If it fits, do monomorphization and replace (take a diff of `T -> T` and `Int -> Int`, `{T => Int}`). - -```erg +``` erg 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 index 49305a56..0f640339 100644 --- a/doc/zh_CN/compiler/transpile.md +++ b/doc/zh_CN/compiler/transpile.md @@ -1,13 +1,17 @@ -# Erg 代码如何转堆到 Python 代码中? +# How is Erg code transpiled to Python code? -准确地说,Erg 代码被转堆为 Python 字节代码。但是 Python 字节码几乎可以恢复为 Python 代码,所以这里给出一个等效的 Python 代码作为例子。顺便说一下,这里的示例是优化级别较低的示例。进一步的高级优化将清除不需要生成实体的内容。 +To be precise, Erg code is transpiled to Python bytecode. +However, since Python bytecode can almost be reconstructed into Python code, the equivalent Python code is used as an example here. +By the way, the example presented here is a low optimization level. +More advanced optimizations eliminate things that don't need to be instantiated. ## Record, Record type -变换成 namedtuple。有关 namedtuple 的信息,请参见。类似的功能包括 dataclass,但由于自动实现和,dataclass 的性能略有下降。 +It will be transpiled to a namedtuple. +For namedtuple, see [here](https://docs.python.jp/3/library/collections.html#collections.namedtuple). +There is a similar function, dataclass, but dataclass has a slight performance drop due to auto-implementation of `__eq__` and `__hash__`. - -```erg +``` erg Employee = Class {.name = Str; .id = Int} employee = Employee.new({.name = "John Smith"; .id = 100}) @@ -15,7 +19,6 @@ employee = Employee.new({.name = "John Smith"; .id = 100}) assert employee.name == "John Smith" ``` - ```python from typing import NamedTuple @@ -29,42 +32,39 @@ employee = Employee('John Smith', 100) assert employee.name == 'John Smith' ``` -如果可以进一步优化,它还将转换为简单的元组。 +It will also be converted to a simple tuple if it can be further optimized. ## Polymorphic Type -> WIP +> WIPs ## Instant Scope -如果名称空间中不发生冲突,则只会进行弯曲和展开。像这样的名称在字节码中使用,不能与 Python 代码相对应,但如果强行表示,则会出现以下情况。 +If no namespace conflicts occur, it will simply be mangled and expanded. +Names such as `x::y` are used in bytecode and cannot be associated with Python code, but if you force it to be expressed, it will be as follows. - -```erg +``` erg x = y = 1 - y + 1 + y+1 ``` - ```python x::y = 1 x = x::y + 1 ``` -如果发生冲突,请定义和使用只能在内部引用的函数。 +In case of conflict, define and use a function that can only be referenced internally. - -```erg +``` erg x = y = 1 - y + 1 + y+1 ``` - ```python def _(): - x = 1 + x=1 y = x return y + 1 x = _() @@ -72,20 +72,19 @@ x = _() ## Visibility -对于公共变量,它是 Python 的缺省值,因此不执行任何操作。私域变量是由 Munging 处理的。 +It does nothing for public variables as it is Python's default. +Private variables are handled by mangling. - -```erg -x = 1 +``` erg +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 index 1e79cd43..3c4fccfc 100644 --- a/doc/zh_CN/compiler/type_var_normalization.md +++ b/doc/zh_CN/compiler/type_var_normalization.md @@ -1,35 +1,39 @@ -# 归一化 +# Normalization -* Erg 的类型参数规范化使用 SymPy 的 simplify 函数。 +* Erg's type argument normalization is based on SymPy's simplify function. -例如,在定义时,必须不具体化类型变量和自变量而进行一致判定。等式判定自然是有界限的,目前可能的判定及其方式如下所示。 +For example, when you define `concat: |T, M, N|([T; M], [T; N] -> [T; M+N])`, you can match type variables and arguments without instantiating them. Judgment must be made. +Equality judgment naturally has its limits, but the judgments that are possible at present and their methods are as follows. -* 相加/乘法对称性: +* Addition/multiplication symmetry: `n+m == m+n` - 类型变量作为字符串进行分类并正规化。 + Type variables are sorted and normalized as strings. -* 加法与乘法、减法与除法的等效性: +* Equivalence of addition and multiplication, subtraction and division: `n+n == 2*n` - 归一化为Σ [c]x==c*x(c 为常数)。常量放在二项式演算的左边进行正规化。 + Normalize to Σ[c] x == c*x, where c is a constant. + Constants are normalized by placing them on the left side of binary operations. -* 复式等效性: +* Equality of double expressions: - `n+m+l == m+n+l == l+m+n ==...` `n+m*l == m*l+n` + `n+m+l == m+n+l == l+m+n == ...` + `n+m*l == m*l+n` - 通过分类进行正规化判定。乘法、除法的程序块在加法、减法的左侧出。块之间比较最左边的类型变量进行分类。 + Determined by normalizing by sorting. + Blocks for multiplication and division are placed to the left of addition and subtraction. Blocks are sorted by comparing the type variables on the leftmost side. -* 基本不公式: +* Basic inequalities: `n > m -> m + 1 > n` -* 等式: +* Equality: `n >= m and m >= n -> m == n` -* 不等式的推移性: +* Transitivity of inequalities: - `n > 0 -> n > -1` + `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 index a7591e0a..84853cb8 100644 --- a/doc/zh_CN/dev_guide/branches.md +++ b/doc/zh_CN/dev_guide/branches.md @@ -32,4 +32,4 @@ * 修复特定错误的分支(如果该问题是一个错误,则代替`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 index c517ec24..d31e879d 100644 --- a/doc/zh_CN/dev_guide/build_features.md +++ b/doc/zh_CN/dev_guide/build_features.md @@ -2,16 +2,18 @@ ## debug -进入调试模式。由此,在 Erg 内部的举动被逐次记录表示出来。独立于 Rust 的标志。 +Enter debug mode. As a result, the behavior inside Erg is sequentially displayed in the log. +Independent of Rust's `debug_assertions` flag. ## japanese -系统语言为日语。Erg 内的选项、帮助(如 help、copyright、license)和错误显示都保证为日语。 +Set the system language to Japanese. +Erg internal options, help (help, copyright, license, etc.) and error display are guaranteed to be Japanese. ## simplified_chinese -系统语言为简体中文。 +Set the system language to Simplified Chinese. ## traditional_chinese -系统语言为繁体中文。 +Set the system language to Traditional Chinese. \ No newline at end of file diff --git a/doc/zh_CN/dev_guide/directories.md b/doc/zh_CN/dev_guide/directories.md index 40947a37..a44615e3 100644 --- a/doc/zh_CN/dev_guide/directories.md +++ b/doc/zh_CN/dev_guide/directories.md @@ -21,4 +21,4 @@ ├─ 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 index 21108c16..26f717a9 100644 --- a/doc/zh_CN/dev_guide/doc_guideline.md +++ b/doc/zh_CN/dev_guide/doc_guideline.md @@ -1,13 +1,13 @@ -# 格式 +# format -所有不符合以下规则的文档都是修正的对象。 +Any document that does not follow the rules below is subject to correction. -* 代码注释或内部文档以这种方式编写。 -* 向外部(普通用户)展示的文档要用简单易懂的语言书写。 -* 文档中首次出现的术语必须同时记录定义、含义或链接。 -* ()作为补充,仅用于理解正文所必需的句子,而非理解正文所必需的句子则使用脚注。 -* 如果文档内容过期,则根据进行更新。 +* Write code comments or internal documentation in a certain tone. +* Documents to be shown to the outside (general users) should be written more and more. +* Always include definitions, meanings, or links to terms that appear for the first time in the document. +* Use parentheses as a proviso only for sentences that are supplementary but necessary for understanding the main text, and use footnotes for sentences that are not essential for understanding the main text[1](#1). +* If the content of the document is outdated, update it according to [this method](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362). --- -1脚注的写法参照此。 +1 See this for how to write footnotes. [↩](#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 index 3e1cd98c..ff6ab791 100644 --- a/doc/zh_CN/dev_guide/env.md +++ b/doc/zh_CN/dev_guide/env.md @@ -1,19 +1,19 @@ -# 开发环境 +# Development environment -## 需要安装的内容 +## What you need to install * Rust (installed with rustup) - * ver >= 1.63.0 - * 2021 edition + * ver >= 1.63.0 + * 2021 edition * [pre-commit](https://pre-commit.com/) -* Python3 解释器 +* Python3 interpreter -## 建议 +## Recommendation -* 编辑器:Visual Studio 代码 -* 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 -* 其他:pyenv,mold +* 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 | Mac OS Monterey +* Others: pyenv, mold \ 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 index c981fb8b..3bfa870b 100644 --- a/doc/zh_CN/dev_guide/faq_syntax.md +++ b/doc/zh_CN/dev_guide/faq_syntax.md @@ -1,6 +1,6 @@ # Erg design's "Why" and Answers -## 为什么拥有所有权系统仍然同时使用GC? +## 当我们有所有权系统时,为什么要与 GC 共存? 因为 Erg 推出所有权系统的动机并不是为了 Rust 那样的“不依赖 GC 的内存管理”。最初,由于 Erg 是一种语言,目前使用 Python VM,因此最终仍使用 GC。Erg 引入产权系统的目标是“可变状态的局部化”。在 Erg 中,可变对象具有所有权概念。这是根据共享可变状态容易成为 bug 的温床,甚至是类型安全性的侵犯(详见)来判断的。 @@ -95,7 +95,7 @@ A:没有那个计划。最重要的原因是,如果允许定义自己的运 首先,Erg 中没有变量的可变性。也就是不能重新赋值。一旦对象与一个变量关联,它将一直绑定到该变量,直到它脱离作用域并被释放。在 Erg 中,可变性是指对象的可变性。明白了这个,故事就简单了。例如,表示,但由于变量是不可重新赋值的,因此这种语法是非法的。还有一个 Erg 的设计原则是运算符没有副作用。Python 通常也是如此,但对于某些对象(如 Dict),扩展赋值运算符会更改对象的内部状态。这算不上是一个很漂亮的设计。因此,扩展赋值运算符被完全废弃。 -## 为什么 Erg 在语法上特别对待有副作用的物体? +## 为什么 Erg 在语法上特别对待有副作用的过程? 副作用的局部化是代码维护的一个关键因素。 @@ -103,4 +103,4 @@ A:没有那个计划。最重要的原因是,如果允许定义自己的运 什么情况下,可以说合一化是错的?一个指标是“是否会因其合一而难以看到错误信息”。Erg 设计师发现,将副作用特殊处理会使错误消息更容易阅读。 -Erg 有一个强大的类型系统,但并不是所有的类型都决定了它。如果这样做了,你的下场就跟 Java 试图用类来控制一切一样。 +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 index 9edaeffa..b3869922 100644 --- a/doc/zh_CN/dev_guide/i18n_messages.md +++ b/doc/zh_CN/dev_guide/i18n_messages.md @@ -1,4 +1,4 @@ -# Multilingualization of Messages +# 多语言错误信息 Erg 正在推动消息(开始、选项、文档、提示、警告、错误消息等)的多语言化。如果你不熟悉 Rust 或 Erg,也可以参与此项目。请务必配合。 @@ -33,7 +33,7 @@ switch_lang!( `{name}`部分是 Rust 的格式化功能,允许你将变量的内容(`name`)嵌入到字符串中。 -## Build +## 构建 现在,我们使用选项构建它。 @@ -52,4 +52,4 @@ Q:如果想添加自己的语言,该如何替换部分?答:目前支持 * "simplified_chinese" (简体中文) * "traditional_chinese" (繁体中文) -如果你想添加其他语言,请提出请求。 +如果你想添加其他语言,请提出请求。 \ No newline at end of file diff --git a/doc/zh_CN/dev_guide/rust_code_guideline.md b/doc/zh_CN/dev_guide/rust_code_guideline.md index 0545e5f5..fa26af68 100644 --- a/doc/zh_CN/dev_guide/rust_code_guideline.md +++ b/doc/zh_CN/dev_guide/rust_code_guideline.md @@ -1,23 +1,23 @@ -# Rust 代码准则 +# Guidelines for Rust code -## 本地规则 +## local rules -* 用于调试的输出使用(释放时所需的输出处理也使用等)。 -* 未使用或内部(专用和仅用于特定功能)的变量方法以一个开头。如果想避免与保留字的冲突,则在后面加上一个。 +* Use `log!` for output for debugging (use `println!` etc. for output processing that is also necessary for release). +* Unused or internal variables/methods (private and used only for specific functions) must be prefixed with `_`. If you want to avoid conflicts with reserved words, add one `_` to the end. -## 鼓励代码 +## Recommended code -* 定义并使用特定于域的 Enum,而不是数字枚举和 bool。 -* 存取修饰符为必要的最小限度。即使公开时也优先使用和。 -* for 表达式中的 iterable 对象显式转换为迭代器(,而不是)。 -* 延迟评估。例如,当不是文字时,使用而不是。 +* Define and use domain-specific Enums instead of numeric enumerations or bools. +* Keep access modifiers to a minimum. Prioritize using `pub(mod)` or `pub(crate)` even when publishing. +* Convert an iterable object in a for expression explicitly to an iterator (`for i in x.iter()` instead of `for i in x`). +* Lazy evaluation. For example, if `default` is non-literal, use `unwrap_or_else` instead of `unwrap_or`. -## 不鼓励的代码 +## Code not encouraged -* 经常使用 return type overloading。具体来说,经常使用不明确的的代码。这是因为型推论结果有时违反直觉。在这种情况下,建议使用代替。 -* 经常使用。这实质上引起了与继承相同的问题。 +* Make heavy use of return type overloading. Specifically code that uses a lot of non-obvious `.into`. This is because type inference results can be counter-intuitive. In this case it is recommended to use `from` instead. +* Make heavy use of `Deref`. This effectively poses the same problem as inheritance. -## 根据上下文判断不同的代码 +## Code that makes decisions based on context -* 定义未使用的 helper 方法。 -* 经常使用,。在某些情况下,有些人别无选择,只能这样做。 +* Define unused helper methods. +* Use `unwrap` and `clone` a lot. In some cases there is nothing better than doing so. \ No newline at end of file diff --git a/doc/zh_CN/dev_guide/terms.md b/doc/zh_CN/dev_guide/terms.md index bb7d1b9c..d3bbc42f 100644 --- a/doc/zh_CN/dev_guide/terms.md +++ b/doc/zh_CN/dev_guide/terms.md @@ -1,12 +1,13 @@ -# 术语词典 +# Glossary -## 符号 +## symbol ### ! -过程或附加在标识符末尾的标记,以指示其为可变类型。或者变量运算符。 +A marker added to the end of an identifier to indicate that it is a procedure or variable type. +Or the mutating operator. -### ../syntax/00_basic.md/# 注释 +### [#](../syntax/00_basic.md/# comment) ### $ @@ -14,7 +15,7 @@ ### & -### ′(single quote) +### ′ (single quote) ### () @@ -146,7 +147,7 @@ ## L -### [秩 1 多相] +### let-polymorphism -> [rank 1 polymorphism] ### [log] @@ -190,7 +191,7 @@ ### ref -### ref! +### ref! ### [Result] @@ -208,7 +209,7 @@ ## T -### Trait +### Traits ### [True] @@ -230,602 +231,609 @@ ## Z -## 阿行 +## A line -### 断言 +### [Assertion] -检查代码中的条件是否成立(通常是在运行时)。使用函数等进行操作。 +To check (typically at runtime) whether a condition is true in code. This is done using the `assert` function, etc. - -```erg +``` erg sum = !0 for! 0..10, i => - sum.add! i + sum.add!i assert sum == 55 ``` -### 值对象 +### Value Object -在 Erg 中,与基本对象相同。编译时可以进行评价,拥有不言而喻的比较方法。 +In Erg, equivalent to base object. It can be evaluated at compile time and has a trivial comparison method. -### 附着面片../syntax/29_decorate.md#attach +### [Attachment patch](../syntax/29_decorator.md#attach) -为 Tracet 提供标准实现的补丁程序。 +A patch that gives the trait a standard implementation. -### 即席多相-> +### Ad hoc polymorphism -> [No overloading](../syntax/type/overloading.md) -所谓超载的多相。 +Polymorphism with so-called overloading. -### 属性-属性 +### Attribute -> [attribute] -标识符中的部分。 +The `y` part in the `x.y` identifier. -### 安利 +### Arity -运算符使用多少个操作数。 +How many operands the operator takes. -### 依赖关系../syntax/type/dependent_type.md +### [Dependent type](../syntax/type/dependent_type.md) -以值(通常为非类型)为参数的类型。 +A type whose argument is a value (idiomatically, not a type). -### 可变体-> 不可变 +### immutable -> [immutable] -表示目标保持不变。在其他语言中,变量也具有可变/可变特性,但在 Erg 中,变量都是可变的。 +Indicates that the target will not change. +Variables in other languages ​​are also immutable/mutable, but in Erg all variables are immutable. -### 参数-> 参数 +### arguments -> [arguments] -### 实例 +### instance -类创建的对象。类类型的元素。 +An object created by a class. An element of class type. -### 即时块(../syntax/00_basic.md# 表达式分隔符) +### [instant block](../syntax/00_basic.md#expression separator) - -```erg +``` erg x = y = f(a) - z = g(b, c) - y + z + z = g(b,c) + y+z ``` -### 索引 +### index -形式为,或其中的部分。称为 Indexable 对象。 +of the form `x[i]`, or the `i` part thereof. We call `x` an Indexable object. -### 缩进../syntax/00_basic.md# 缩进 +### [indent](../syntax/00_basic.md#indent) -靠空格使句子向右靠。缩进。Erg 通过缩进来表现块。这叫做越位规则。 +Align text to the right by moving toward spaces. Indentation. +Ergs represent blocks by indentation. This is called the offside rule. -### 别名 +### Aliases -别名。 +Alias. -### 错误 +### error -规范规定的异常状态。 +Abnormal conditions defined in the specification. -* [エラーハンドリング] +* [Error handling] -### 运算符../syntax/06_operator.md +### [operator](../syntax/06_operator.md) -将运算应用于操作数的对象。或表示对象的符号。 +An object that applies an operation to its operands. or a symbol denoting that object. -* [演算子の結合強度] +* [operator binding strength] -### 覆盖 +### Override -用子类覆盖超类的方法。在 Erg 中,覆盖时必须安装装饰器。 +Overriding superclass methods in subclasses. +In Erg you have to add `Override` decorator when overriding. -### 禁止过载(../syntax/type/overloading.md) +### [No overloading](../syntax/type/overloading.md) -### 越位规则-> +### Offside rule -> [indent](../syntax/00_basic.md#indent) -### 对象 +### [object] -* 面向对象 +* Object-orientation -### 操作数-> +### operand -> [operand](../syntax/06_operator.md) -### 操作员-> +### operator -> [operator](../syntax/06_operator.md) -## 家行 +## Ka line -### 卡印(../syntax/type/advanced/kind.md) +### [kind](../syntax/type/advanced/kind.md) -所谓模子的模子。 +Types of so-called types. -### 可见性 +### [visibility] -标识符是否可从外部(范围外或单独模块、单独软件包)引用的性质。 +The property of whether an identifier can be referenced externally (out of scope, or in another module or package). -### 类型 +### [type] -要对项进行分组的对象。 +An object that groups terms. -* [型指定] -* 清除类型(../syntax/type/advanced/erasure.md) -* [型推論] -* 类型注释../syntax/type/conv_type.md -* [型引数] -* 添加类型(../syntax/type/advanced/erasure.md) -* 类型变量(../syntax/type/type_variable.md) -* [型制約] +* [type specification] +* [type erasure](../syntax/type/advanced/erasure.md) +* [type inference] +* [type annotation](../syntax/type/conv_type.md) +* [type argument] +* [type addition](../syntax/type/advanced/erasure.md) +* [type variable](../syntax/type/type_variable.md) +* [type constraint] -### 保护 +### [Guard] -### 封装 +### Encapsulation -隐藏实现细节。 +Hiding implementation details. -### 变量 +### [variable] -不可变。 +Must not be immutable. -* [可変オブジェクト] -* [可変型] -* [可変参照] -* [可変配列] -* [可変長引数] +* [mutable object] +* [variable] +* [variable reference] +* [variable array] +* [variable arguments] -### 函数../syntax/04_function.md +### [function](../syntax/04_function.md) -没有副作用的子程序。 +A subroutine with no side effects. -* 函数型编程(../syntax/23_scop.md# 避免变量状态函数型编程) +* [Functional programming](../syntax/23_scope.md#Avoiding mutable stateFunctional programming) -### 基本类型 +### base type -### 记名的 +### nominative -通过名称而不是对称结构来区分。 +Distinguish by name rather than by symmetrical structure. -* [记名型]-> -* [記名化] -* 记名部分类型../syntax/type/05_nst_vs_sst.md +* [named type] -> [class](../syntax/type/04_class.md) +* [Annunciation] +* [nominal subtype](../syntax/type/05_nst_vs_sst.md) -### 捕捉-> 闭包 +### capture -> [closure] -### 协变 +### [covariant] -在 Erg 中,当时,如果,则为协变。 +In Erg, if `T <: U` then `K(T) <: K(U)` then `K` is said to be covariant. -### 关键字参数 +### [keyword arguments] -函数调用形式中的。实际自变量可以用假自变量名而不是顺序指定。 +`k` in the form of function call `f(k: v)`. You can specify actual arguments by formal argument name instead of by order. -### 空集->[{}] +### empty set -> [{}] -### 区间 +### section -* 间隔类型(../syntax/type/11_interval.md) -* 区间运算符 +* [Interval type](../syntax/type/11_interval.md) +* interval operator -### 嵌入 +### Embedded -未在.er 文件中实现的 Erg 标准 API。 +Erg standard APIs not implemented in .er files. -### 类../syntax/type/04_class.md +### [class](../syntax/type/04_class.md) -具有继承功能的结构和抽象数据类型。在 Erg 中是为了实现记名式分型以及覆盖的类型。在其他语言中也有承担模块和型的责任和义务的情况,在 Erg 中,模块是模块对象,型是型对象承担其责任和义务。 +Structure/abstract data type with inheritance function. In Erg, it is a type to implement named subtyping and overriding. +In Erg, modules are the responsibility of module objects, and types are the type object, while other languages ​​may be responsible for modules and types. -### 闭合 +### [Closure] -### 全局变量 +### [global variables] -### 克隆 +### [Clone] -### 继承 +### [inheritance](../syntax/type/07_inheritance.md) -定义以某个类为上级集合的类。继承源的类称为超类,继承目标的类称为子类。子类具有超类的所有功能。 +To define a class that is a superset of another class. +The class that inherits is called the superclass, and the class that inherits is called the subclass. +A subclass has all the functionality of its superclass. -### 高阶 +### high floor -* 高阶../syntax/type/advanced/kind.md -* 高阶型 -* 高阶函数 +* [higher-order kind](../syntax/type/advanced/kind.md) +* higher order type +* Higher-order functions -### 公共变量 +### [public variables] -### 结构子类型 +### [structural subtype] -### ~~ 向后参照 ~~~->[向前参照] +### ~~back reference~~ -> [back reference] -### 复制 +### [copy] -### 注释 +### comment -### 集合../syntax/10_array.md +### [Collection](../syntax/10_array.md) -### 冒号->[:] +### Colon -> [:] -### 构造函数(../syntax/type/04_class.md) +### [constructor](../syntax/type/04_class.md) -### 集装箱 +### container -### 编译器 +### Compiler -### 编译时计算../syntax/04_function.md# 编译时函数 +### [compile-time computation](../syntax/04_function.md#compile-time function) -### 逗号->[,] +### comma -> [,] -## 差行 +## sa line -### 递归 +### recursion -指自己。 +Refer to yourself. -* 递归型 -* 递归函数../syntax/04_function.md# 递归函数 +* recursive +* [Recursive function](../syntax/04_function.md#Recursive function) -### 下标-> 索引 +### subscript -> [index] -### 多相子类型(../syntax/type/overloading.md) +### [subtyping polymorphism](../syntax/type/overloading.md) -多相分型。子类型是指在类型中与集合的包含关系相对应的类型。 +Polymorphism with subtyping. Subtyping corresponds to set containment in types. -### 子程序 +### Subroutine -模块化处理的对象。Erg 中函数、过程和方法的通用名称。 +An object that modularizes processing. A generic term for functions, procedures, and methods in Erg. -### 参考(../syntax/18_memory_management.md# 借用) +### [reference](../syntax/18_memory_management.md#borrowed) -* 引用对象 -* 参照计数 (RC) (../syntax/18_memory_management.md# 内存管理) -* 参考等效性-> +* reference object +* [Reference counting (RC)](../syntax/18_memory_management.md#memory management) +* Reference equality -> [side effect](../syntax/07_side_effect.md) -### 标识符(../syntax/02_variable.md/# 赋值) +### [identifier](../syntax/02_variable.md/# assignment) -### 签名 +### signature -* 类型签名 +* type signature -### 词典../syntax/11_dict.md +### [dict](../syntax/11_dict.md) -### 自然数->Nat +### [natural number] -> [Nat] -### 通用->[全称类型] +### Generics -> [Generic] -### 发电机 +### Generator -### 投影类型 +### [projective type] -### 借用-> +### borrow -> [reference](../syntax/18_memory_management.md#borrowed) -### 阴影(../syntax/02_name.md# 变量) +### [shadowing](../syntax/02_name.md# variables) -在内部作用域中定义一个同名的变量,并覆盖该变量的引用。 +To override a reference to a variable by defining a variable with the same name in an inner scope. -### 种子-> +### kind -> [kind](../syntax/type/advanced/kind.md) -大致是个模子。 +Roughly the type of type. -### 集-> 集 +### [set] -> [set] -在 Erg 中是 Set 对象。 +In Erg, it means a Set object. -### 谓语 +### Predicate -* [述語関数] +* [predicate function] -返回布尔类型的函数。 +A function that returns a bool type. -### 条件分歧 +### Conditional branch -### 所有权 +### [Ownership] -关于对象唯一性的概念。如果拥有对象的所有权,则可以对对象进行可变引用。 +The concept of object uniqueness. +If you have ownership of an object, you can take a mutable reference to it. -### 真伪类型-> 布尔 +### Boolean -> [Bool] -### 单吨 +### Singleton -从只能生成一个实例的类生成的实例。也指确保只生成一个类实例的设计模式。 +An instance created from a class that can create only one instance. A design pattern that ensures that only one instance of a class is created. -### 符号-> +### [Symbol] -> [Identifier](../syntax/02_name.md) -* [シンボル化] +* [symbolization] -### 脚本../syntax/00_basic.md# 脚本 +### [script](../syntax/00_basic.md# script) -描述 Erg 程序的文件。 +A file containing an Erg program. -### 范围 +### Scope -变量管理中的单位。外侧的范围不能参照存在于内侧范围的变量。另外,脱离范围时,参照点数为 0 的对象被释放。 +Units in variable management. An outer scope cannot refer to a variable that exists in an inner scope. +Objects with a reference count of 0 are freed when the scope exits. -### 跨页运算符-> 展开赋值 +### spread operator -> [expansion assignment] -### 切片../syntax/10_array.md# 切片 +### [slice](../syntax/10_array.md#slice) -以形式生成的表示数组子串的对象。 +An object representing a subsequence of the array, generated in the form `x[a..b]`. -### 控制字符 +### control characters -### 整数-> 输入 +### [Integer] -> [Int] -自然数加负数的集合。 +A set of natural numbers plus negative numbers. -### 集../syntax/12_set.md +### [set](../syntax/12_set.md) -### 分号->[;] +### Semicolon -> [;] -### 声明../syntax/03_declaration.md +### [Declaration](../syntax/03_declaration.md) -显式设置变量类型。 +Explicitly type variables. -### 全称 +### Full name -* 全称类型-> - * 封闭全称类型 - * 打开的全称类型 -* 全称函数-> 多相关数 -* 全称量化 +* universal type -> [polymorphic type](../syntax/type/quantified.md) + * closed universal + * Open Universal +* universal function -> polycorrelation function +* universal quantification -### 前缀运算符 +### prefix operator -以格式应用的运算符。 +Operator `∘` applied in the form `∘x`. -### 互相的递归 +### mutual recursion -### 下标-> 索引 +### subscript -> [index] -### 属性 +### [attributes] -* [属性的部分型] +* [attribute subtype] -## 多行 +## Ta line -### 代数../syntax/02_name.md +### [algebra](../syntax/02_name.md) -* 代数类型(../syntax/type/13_algebraic.md) -* 代数数据类型 +* [algebraic type](../syntax/type/13_algebraic.md) +* algebraic data types -### 赋值../syntax/02_variable.md/# 赋值 +### [assignment](../syntax/02_variable.md/#assignment) -### 多重 +### Multiple -* 多重继承(../syntax/type/07_inheritance.md/# 禁止多重继承) -* 多重赋值 -* 多重定义-> 禁止过载 +* [Multiple inheritance](../syntax/type/07_inheritance.md/#Prohibition of multiple inheritance) +* Multiple assignment +* Overload -> [No overloading] -### 多相 +### Polymorphism -* 多相类型(../syntax/type/quantified.md) -* 多相关数 +* [polymorphic type](../syntax/type/quantified.md) +* polycorrelation coefficient -### 多态-> 多态 +### polymorphism -> [polymorphism] -### 烤鸭打字 +### duck typing -### 元组(../syntax/11_tuple.md) +### [tuple](../syntax/11_tuple.md) -### 单相 +### Single-phase -* 单相化 -* 单相型 -* 单相关数 +* Single phase +* Single-phase type +* Single correlation coefficient -### 延迟初始化 +### [Lazy initialization] -### 抽出赋值 +### Extraction Assignment -### 抽象语法树->[AST] +### Abstract syntax tree -> [AST] -### 中置运算符 +### Infix operator -以格式应用的运算符。 +The operator `∘` applied in the form `x∘y`. -### 常量../syntax/02_name.md/# 常量 +### [constant](../syntax/02_name.md/#constant) -可执行的、编译时可评估的代数。 +Immutable, compile-time evaluable algebra. -* 常量类型(../syntax/type/advanced/const.md) -* 常量表达式(../syntax/type/advanced/const.md) +* [constant type](../syntax/type/advanced/const.md) +* [constant expression](../syntax/type/advanced/const.md) -### 定义 +### [definition] -分配与变量对应的对象。 +Allocating an object corresponding to a variable. -### 授课属性 +### Provided Attributes -可用作 API 的属性。特别是由trait自动实现的属性。 +Attributes available as API. Especially attributes auto-implemented by traits. -### 应用 +### [Apply] -将参数传递给函数对象以获得评估结果。 +To pass an argument to a function object and get the evaluation result. -### 装饰器../syntax/29_decorate.md +### [decorator](../syntax/29_decorator.md) - -```erg +``` erg @deco f x = ... ``` -的语法糖,或者。大约等于。本身只是一个高阶子程序。 +syntactic sugar, or `deco`. Roughly equal to `_f x = ...; f = deco _f`. `deco` itself is just a higher-order subroutine. -### 析构 +### destructor -销毁对象时调用的方法。 +Method called when the object is destroyed. -### 过程-> +### procedure -> [procedure](../syntax/08_procedure.md) -读取和写入可变状态的子程序。有时会解释程序根据调用顺序的不同,程序的执行结果也会发生变化,但如果说的是可换性的话,这是错误的。例如,作为函数子类型的运算符一般不是可换的。 +A subroutine that reads and writes mutable state. +It is sometimes said that the execution result of a program can change depending on the order in which the procedures are called, but this is incorrect if we are talking about commutativity. +For example, operators that are subtypes of functions are generally not commutative. -### 缺省参数../syntax/04_function.md/# 缺省参数 default-parameters +### [default arguments](../syntax/04_function.md/#default arguments default-parameters) -通过为虚拟自变量指定缺省值,调用时可以省略实际自变量指定的功能。 +A function that allows you to omit the specification of actual arguments at the time of calling by specifying default values ​​for formal arguments. -### 展开 +### Expand -* [展開演算子] -* [展開代入] +* [expansion operator] +* [expansion assignment] -### 特殊格式(../syntax/../API/special.md) +### [special format](../syntax/../API/special.md) -不能传递给实际参数的对象。 +An object that cannot be passed as an actual argument. -### 匿名函数-> +### anonymous function -> [anonymous function](../syntax/20_lambda.md) -由未命名函数运算符生成的函数对象。不用定义名字就能使用。 +A function object created by the anonymous function operator `->`. Can be used without defining a name. -### 点运算符()->[属性引用] +### dot operator (`.`) -> [attribute reference] -### 顶部 +### Top -* 顶部类型-> 结构对象 -* 顶级-> 对象 +* Top type -> [Structural Object] +* Top class -> [Object] -### TRAIT(../syntax/type/03_trait.md) +### [trait](../syntax/type/03_trait.md) -## 标题 +## na line -### 内涵符号../syntax/27_comprehension.md +### [Comprehension](../syntax/27_comprehension.md) -### 中置算子 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +### ~~Infix operator~~ -> [Infix operator] -### 名称空间 +### [namespace] -## 派系 +## is a line -### 阵列../syntax/10_array.md +### [Array](../syntax/10_array.md) -### 派生类型(../syntax/type/variances.md/# 用户定义类型的退化) +### [derived type](../syntax/type/variances.md/# user-defined type variations) -### 图案(匹配)../syntax/26_pattern_matching.md +### [pattern (match)](../syntax/26_pattern_matching.md) -### 软件包../syntax/33_package_system.md +### [package](../syntax/33_package_system.md) -### 哈希映射-> +### hashmap -> [dict](../syntax/11_dict.md) -### 面片../syntax/type/07_patch.md +### [patch](../syntax/type/07_patch.md) -### 公共变量-> +### public variables -> [public variables](../syntax/19_visibility.md) -### 参数-> +### parameter -> [argument](../syntax/04_function.md) -### 参数化多相(../syntax/type/overloading.md) +### [Parametric Polymorphism](../syntax/type/overloading.md) -### 反变(../syntax/type/advanced/variance.md) +### [contravariant](../syntax/type/advanced/variance.md) -### 比较 +### Compare -* [比較演算子] -* [比較可能型] +* [comparison operator] +* [comparable type] -### 私有变量../syntax/19_visibility.md +### [private variable](../syntax/19_visibility.md) -### 标准 +### standard -* 标准输出 -* 标准输入 -* 标准库 +* standard output +* standard input +* standard library -### 副作用../syntax/07_side_effect.md +### [side effects](../syntax/07_side_effect.md) -代码不能读取或写入外部可变状态。 +Code should/not read/write external mutable state. -### 复数-> +### complex number -> [Complex] -### 浮点数-> 浮点 +### [Float] -> [Float] -### 专用变量-> 专用变量 +### private variables -> [private variables] -### 布尔代数-> 布尔 +### Boolean algebra -> [Bool] -### 程序../syntax/08_procedure.md +### [procedure](../syntax/08_procedure.md) -### 参数(../syntax/04_function.md) +### [arguments](../syntax/04_function.md) -### 部分类型-> 子类型 +### Partial Typing -> [Subtyping] -### 不变 +### [immutable] -在 Erg 中,对象不改变其内容。 +In Erg, an object should never change its contents. -* [不変オブジェクト] -* [不変型] -* [不変参照] +* [immutable object] +* [immutable type] +* [immutable reference] -### 筛型(../syntax/type/12_refinement.md) +### [sieve type](../syntax/type/12_refinement.md) -### 块 +### [block] -### 分解赋值 +### Destructuring assignment -### 变量../syntax/02_variable.md +### [variable](../syntax/02_variable.md) -### 底部 +### bottom -* 底部->[{}] -* 底部类->Never +* bottom type -> [{}] +* Bottom class -> [Never] -### 多态 +### [Polymorphism] -## 真行 +## ma line -### 前缀运算符 ~~~~~~ 前缀运算符 +### ~~ prefix operator ~~ -> prefix operator -### 标记类型../syntax/type/advanced/marker_trait.md +### [marker type](../syntax/type/advanced/marker_trait.md) -### 无名函数../syntax/21_lambda.md +### [anonymous function](../syntax/21_lambda.md) -### 可变-> 可变 +### mutable -> [mutable] -### 移动 +### [move] -### 方法 +### methods -### 元字符 +### Metacharacters -### 模块(../syntax/24_module.md) +### [module](../syntax/24_module.md) -### 字符串->Str +### [String] -> [Str] -* 字符串插值(../syntax/01_literal.md/#Str 文字) +* [String interpolation](../syntax/01_literal.md/#Str literal) -### 返回值 +### Return value -## 夜行 +## or line -### 幽灵类型(../syntax/type/advanced/phantom.md) +### [phantom type](../syntax/type/advanced/phantom.md) -### 请求属性 +### Request Attributes -### 元素 +### [element] -### 调用 +### [call] -## 罗列 +## Ra line -### 库 +### [Library] -### 拉姆达公式-> +### lambda expression -> [anonymous function](../syntax/20_lambda.md) -### 等级 +### rank -* 通道 2 多相../syntax/type/advanced/rank2type.md +* [rank2 polymorphism](../syntax/type/advanced/rank2type.md) -### 文字(../syntax/01_literal.md) +### [literal](../syntax/01_literal.md) -* 文字标识符(../syntax/18_naming_rule.md/# 文字标识符) +* [literal identifier](../syntax/18_naming_rule.md/#literal identifier) -### 量化(../syntax/type/quantified.md) +### [quantified](../syntax/type/quantified.md) -### 布局(../syntax/type/mut.md) +### [Layout](../syntax/type/mut.md) -### 枚举类型(../syntax/type/10_enum.md) +### [enum](../syntax/type/10_enum.md) -### 记录../syntax/12_record.md +### [record](../syntax/12_record.md) -* [レコード型] -* 记录多相-> 列多相 +* [record type] +* Record Polymorphism -> [Column Polymorphism] -### 列多相 +### [column polymorphism] -### 局部变量../syntax/19_visibility.md +### [local variables](../syntax/19_visibility.md) -## 和行 +## line -### 通配符 +### Wildcard \ 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 index 4cb5b2bc..02806bf1 100644 --- a/doc/zh_CN/dev_guide/unify_terms.md +++ b/doc/zh_CN/dev_guide/unify_terms.md @@ -1,80 +1,56 @@ -# 术语统一 +# Unification of terminology -## 可见性、可见性 +## Accessibility, Visibility -使用“Visibility(可见性)”。 +Use Visibility. -## 完全(非、补) +## Type bound, Type constraint -使用否定类型。Complement 的结果不一定是 Not 型。 +A list of predicate expressions given to quantified and refinement types. Use type bounds. -## Diff(差分型、排除型、直差型) +## subroutines, routines, subprograms -使用排除类型。Diff 的结果不一定是 Not 型。 +Use subroutines. -## Intersection(交集、交集、笛卡尔) +## Referentially transparent/not, with/without side effects -使用交叉类型。不使用笛卡儿积型。这是因为也有将元组视为笛卡儿积型的用法。但是,从属性部分型的观点来看,是与 Erg 的 And 型本质上等价的概念。另外,Intersection 的结果不一定是 And 型。例如。 +Use with/without side effects. -## Nominal subtyping 的翻译 +## identifiers, algebra, variables, names, symbols -虽然有记名的/名目的/标称的部分定型,但是使用记名的部分定型。 +In its original meaning, -## Ratio 型译词 +* Symbol: Characters (except symbols, control characters, etc.) that are solid-written in source code that are not string objects (not enclosed in ""). Symbols exist as primitive types in Ruby, Lisp, etc., but they are not treated as objects in Erg. +* Identifier: A symbol that (and can) refer to some object, not a reserved word. For example, in Python class and def cannot be used as identifiers. Since Erg has no reserved words, all symbols can be used as identifiers except some symbols. +* Name: Almost same meaning as identifier. It is sometimes used synonymously with algebra in Erg. +* Algebra name: equivalent to identifier in Erg. In C, function names are identifiers, not algebraic names. "Algebra" refers to the language feature itself that allows you to assign objects with `=` (variable assignment operator) or `=` (constant assignment operator). -使用有理数型。由于 Float 是单独提供的,所以不称为浮点数型。 - -## Union(合并、直和) - -使用合并类型。Union 的结果不一定是 Or 型。 - -## 类型边界(Type bound)、类型约束(Type constraint) - -量化型、筛子型所给谓词式的列表。使用类型边界。 - -## 子程序,例程,子程序 - -中描述的相应参数的值。 - -## 参照透明/不透明,有/无副作用 - -使用有/无副作用。 - -## 标识符、代数、变量、名称、符号 - -原来的意思是, - -* 符号(Symbol):非字符串对象(未括在“”中)的纯文本源代码字符(符号、控制字符等除外)。Ruby 和 Lisp 等中作为基本类型的符号存在,但在 Erg 中不被作为对象处理。 -* 标识符(Identifier):指向(也可以)某个对象的符号,而不是保留字。例如,在 Python 中,class 和 def 不能作为标识符使用。由于 Erg 中没有保留字,所以除去一部分符号的所有符号都可以作为标识符使用。 -* 名称(Name):几乎等同于标识符。在 Erg 中也有与代数相同的意思使用。 -* 代数名(Algebra name):在 Erg 中等同于标识符。在 C 语言中,函数名是标识符,但不是代数名。“代数”是指能够用(变量赋值运算符)或(常量赋值运算符)赋值对象的语言功能本身。 - - -```erg -代数名 <: (名前 == 識別子) <: シンボル -変数 + 定数 == 代数 +``` erg +algebraic name <: (name == identifier) ​​<: symbol +variable + constant == algebra ``` -但是,本来应该被称为“代数”的多被称为“变量”。这是数学术语的影响。值的内容可能变化的变量是可互斥变量,值的内容不变的变量是可互斥变量。另外,常数一定是可变的。 +However, what should be called "algebra" is often called "variable". This is the effect of mathematical terminology. +A variable whose value content can change is a mutable variable, and a variable whose value content does not change is an immutable variable. +Note that constants are always immutable. -Erg 中代数名,不使用名称,用标识符统一。但是,一般来说,的被称为“变量 v”(“Variable v”),被称为“常数 C”(“Constant C”)。 +Algebraic names and names are not used in Erg, and uniform identifiers are used. +However, in general, `v` with `v = 1` is called "Variable v", and `C` with `C = 1` is called "Constant C". . -## 属性、字段和特性 +## Attribute, Field, Property -属性,使用属性。顺便一提,记录是指在没有类的情况下可以定义具有要素属性的对象的功能。 +Use attributes. By the way, a record is a function that can define an object with element attributes without a class. -## 应用(Application)、调用(Call) +## Application, Call -通过向子程序对象提供参数来获得结果。使用调用(Call)。因为 Application 具有“应用软件”的用法。 +Giving arguments to a subroutine object and getting a result. +Use Call. This is because Application has a usage of "application software". -## 数组、列表 +## Array, List -使用 Array。这是因为 Erg 的排列(通常)是在存储器上连续排列的。List 指的是所谓的连接列表,或者作为 Python 的数据类型的列表。 +Use Arrays. Erg arrays are (generally) contiguous in memory. +List refers to a so-called linked list, or a list as a Python data type. -## 过程,过程 +## lambda functions, lambda expressions, anonymous functions -与过程一致。子例程是函数(和运算符)、过程和方法的总称。Callable 是安装了的全部。 - -## Lambda 函数、Lambda 表达式、匿名函数、匿名函数 - -统一为无名函数。英语中为了缩短字数可以使用 Lambda,但正式名称是 Anonymous function。另外,Erg 的无名函数不是匿名的,所以不使用匿名函数。 +Unify with anonymous functions. In English, Lambda can be used to shorten the number of characters, but the official name is Anonymous function. diff --git a/doc/zh_CN/faq_general.md b/doc/zh_CN/faq_general.md index dfd1e6f4..331212e5 100644 --- a/doc/zh_CN/faq_general.md +++ b/doc/zh_CN/faq_general.md @@ -1,27 +1,37 @@ # Erg FAQ -本常见问题解答适用于一般 Erg 入门用户。请参阅以了解具体的(常见的)技术问题,或参阅以了解语法的决定(为什么出现这种语法)。 +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 兼容语言是什么意思? +## What does it mean that Erg is a Python compatible language? -~~A:Erg 的执行系统 EVM(Erg VirtualMachine,EVM)执行由 Python 字节代码扩展而成的 Erg 字节代码。这是在 Python 字节码中引入的静态定型系统(在不带参数的指令中引入参数,在空号中实现专有指令)。这使得 Erg 能够无缝调用 Python 的代码,并实现快速执行。~~ +~~A: Erg's executable system, EVM (Erg VirtualMachine), executes Erg bytecode, which is an extension of Python bytecode. It introduces a static typing system and other features into the Python bytecode (such as introducing arguments to instructions that do not take arguments, and implementing unique instructions in the free numbers). This allows Erg to call Python code seamlessly and execute it fast.~~ -答:Erg 脚本将转换成 Python 字节码。也就是说,它与 Python 在同一解释器上运行。最初,我们计划开发一个由 Python 解释器(CPython)扩展而成的向上兼容处理系统,并将其与编译器合并为“Erg”,但由于处理系统的开发远远落后于编译器,因此我们决定只先公开编译器。现在处理系统正在积极开发中。 +A: Erg code is transpiled into Python bytecode. That is, it runs on the same interpreter as Python. Originally, we planned to develop a Cpython-compatible interpreter, and to combine it with the compiler to form "Erg". However, since the development of the processing system has lagged far behind that of the compiler, we have decided to release only the compiler in advance (But the interpreter is still under development). -## Erg 受到了什么语言的影响? +## What languages have influenced Erg? -双手也受到无数种语言的影响,其中受影响特别强烈的是 Python/Rust/Nim/Haskell。Python 继承了许多与越位规则兼容的语义学,Rust 继承了面向表达式和trait,Nim 继承了过程,Haskell 继承了函数型编程相关的功能。 +We have been influenced by more languages than we can count on both hands, but Python, Rust, Nim, and Haskell have been the strongest influences. +We inherited many semantics from Python, expression-oriented and trait from Rust, procedures from Nim, and functional programming-related features from Haskell. -## 可以调用 Python 的语言包括 Julia。你为什么做 Erg? +## Languages that can call Python include Julia. Why did you create Erg? -答:Erg 的一个设计动机是,他想要一种语言,既易于使用,又具有强大的类型系统。即具有类型推理、卡印、依赖性等的语言。虽然 Julia 可以进行类型化,但它实际上是一种动态的类型化语言,不能提供静态类型化语言的编译时错误检测优势。 +A: One of the motivations for Erg's design was to have a language that is easy to use, yet has a powerful type system. That is, a language with type inference, Kind, dependent types, etc. +Julia can be typed, but it is really a dynamically typed language and does not have the compile-time error detection benefits of statically typed languages. -## Erg 支持多种样式,包括函数型编程和面向对象编程。这是不是与 Python 的“There should be one-and preferably only one--obvious way to do it.”背道而驰? +## Erg supports multiple styles of programming, including functional and object-oriented programming. Isn't this contrary to Python's "There should be one --and preferably only one-- obvious way to do it."? -A:在 Erg 中,这个词可以理解成更狭隘的意思。例如,Erg API 通常没有别名。在这个意义上,Erg 是“only one way”。在更大的意义和框架中,如函数类型或 OOP,只有一种方法不一定会带来便利。例如,JavaScript 有多个库来帮助创建可转换程序,而 C 语言有多个垃圾回收库。但是,如果有多个库来执行这些基本功能,不仅会占用选择时间,而且会在使用不同库的代码之间进行集成时产生明显的困难。即使是纯函数语言 Haskell 也有支持面向对象的库。如果没有程序员,他们就会自己创造出来。那样的话,我认为还是按标准提供比较好。这也符合 Python 的“Battery included”。 +A: In Erg, the term is taken in a more narrow context. For example, there are generally no aliases in the Erg API; Erg is "only one way" in this context. +In a larger context, such as FP or OOP, having only one way of doing things is not necessarily a convenience. +For example, JavaScript has several libraries to help create immutable programs, and C has several libraries for garbage collection. +However, having multiple libraries for even such basic features not only takes time to select, but also creates significant difficulties in integrating code that uses different libraries. +Even in Haskell, a purely functional language, there are libraries that support OOP. +If programmers don't have some stuffs, they will create them on their own. So, we think it would be better to provide them as a standard. +This also fits with Python's "Battery included" concept. -## Erg 名字的由来是什么? +## What is the origin of the name Erg? -名称来源于 cgs 单位制中能量的单位 erg。这是一种双重混合语言,它是一种人类工程学(ergonomic)语言,为程序员提供能量(虽然是后缀)。 +It is named after the unit of energy erg in the cgs unit system. It is a double meaning: an ergonomic language that gives programmers energy. -虽然还有一些其他候选,但由于它们最短(Ruby 的作者 Matz 说,语言的名称越短越好),并且具有相应的高格格不入性,因此决定了这一点。 +There were several other candidates, but this was chosen because it is the shortest (according to Matz, the developer of Ruby, the shorter the better for a language name) and has a reasonably high googlability. diff --git a/doc/zh_CN/faq_technical.md b/doc/zh_CN/faq_technical.md index d868873a..896b120a 100644 --- a/doc/zh_CN/faq_technical.md +++ b/doc/zh_CN/faq_technical.md @@ -1,25 +1,34 @@ -# 技术常见问题解答 +# Technical FAQ -本节回答了使用 Erg 语言的技术问题。即,以“What”、“Which”开头的问题,以及可以回答“Yes/No”的问题。 -关于根本语法的决定,请参阅,关于为什么创建这种语言,如何实现这种功能等更大的话题,请参阅。 +This section answers technical questions about using the Erg language. In other words, it contains questions that begin with What or Which, and questions that can be answered with Yes/No. -## Erg 没有异常机制吗? +For more information on how the grammar was determined, see [here](./dev_guide/faq_syntax.md) for the underlying syntax decisions, and [here](./dev_guide/../faq_general.md). -A:没有。Erg 使用类型代替。有关为什么 Erg 没有异常机制的信息,请参见。 +## Is there an exception mechanism in Erg? -## Erg 没有与 TypeScript 中的 Any 相对应的类型吗? +A: No. Erg uses the `Result` type instead. See [here](./dev_guide/faq_syntax.md) for why Erg does not have an exception mechanism. -A:没有。所有对象至少属于类,但此类型只提供最少的属性,不能像 Any 那样随心所欲。类通过动态检查(如)转换为所需的类型。它与 Java 中的类似。在 Erg 的世界里,不会出现像 TypeScript 那样追寻 API 定义的结果是 Any 的绝望和混乱。 +## Does Erg have a type equivalent to TypeScript's `Any`? -## Never,{},None,(),NotImplemented,Ellipsis 有什么不同? +A: No, there is not. All objects belong to at least the `Object` class, but this type only provides a minimal set of attributes, so you can't do whatever you want with it like you can with Any. +The `Object` class is converted to the desired type through dynamic inspection by `match`, etc. It is the same kind of `Object` in Java and other languages. +In the Erg world, there is no chaos and hopelessness like in TypeScript, where the API definition is ``Any''. -A:类型为“不可能发生”。生成运行时错误的子例程返回类型为(或的合并类型)。如果检测到这一点,程序将立即停止。尽管类型在定义上也是所有类型的子类,但类型对象不会出现在 Erg 代码中,也不会生成。等于是表示省略的对象,来自 Python。也来自 Python。这被用作未实现的标记,但 Erg 建议使用函数来生成错误。的实例。常用于类型。是单元类型,也是实例本身。如果要返回“无意义的值”(如过程的返回值),则使用此选项。 +## What is the difference between Never, {}, None, (), NotImplemented, and Ellipsis? -## 为什么有效,而是 EffectError? +A: `Never` is an "impossible" type. A subroutine that produces a runtime error has `Never` (or a merger type of `Never`) as its return type. The program will stop as soon as it detects this. Although the `Never` type is by definition also a subclass of all types, `Never` type objects never appear in Erg code and are never created. `{}` is equivalent to `Never`. +`Ellipsis` is an object that represents an ellipsis, and comes from Python. +`NotImplemented` is also from Python. It is used as a marker for not implemented, but Erg prefers the `todo` function which produces an error. +`None` is an instance of `NoneType`. It is often used with the `Option` type. +`()` is a unit type and an instance of itself. It is used when you want to return a "meaningless value" such as the return value of a procedure. -A:不是标记副作用的产物,而是标记可能产生副作用的物体。过程和可变类型可能会产生副作用,但例如,如果返回的类型为,则其本身不会产生副作用。 +## Why is `x = p!()` valid but `f() = p!()` causes an EffectError? -## 尝试使用 Python API 时,在 Erg 中,在 Python 中有效的代码出现类型错误。这是什么意思? +`!` is not a marker for the product of a side-effect, but for an object that can cause a side-effect. +Procedure `p!` and mutable type `T!` can cause side effects, but if the return value of `p!()`, for example, is of type `Int`, it itself no longer causes side effects. -答:Erg 的 API 尽量按照 Python 的 API 规范进行定型,但有些情况无论如何也无法表达。此外,根据 Erg 开发团队的判断,被认为有效但不期望的输入(例如,可以在应输入 int 的地方输入浮点的规范)可能是类型错误。 +## When I try to use the Python API, I get a type error in Erg for code that was valid in Python. What does this mean? + +A: The Erg API is typed as closely as possible to the Python API specification, but there are some cases that cannot be fully expressed. +Also, input that is valid according to the specification but deemed undesirable (for example, inputting a float when an int should be inputted) may be treated as a type error at the discretion of the Erg development team. diff --git a/doc/zh_CN/improved_points.md b/doc/zh_CN/improved_points.md index 18256623..dc8f71e0 100644 --- a/doc/zh_CN/improved_points.md +++ b/doc/zh_CN/improved_points.md @@ -1,13 +1,13 @@ -# Python 的改进 +# Improvements from Python -## 执行静态分析(静态检查、变量属性检查) +## Perform static analysis (static type checking, variable and property checking) -虽然静态检查的好处不必再强调了,但检查变量属性的存在也是一个非常有效的部分。 +The benefit of static type checking cannot be emphasized enough now, but checking for the existence of variables and properties is also a part that comes into play quite a bit. -## 严格处理范围 - -Python 中的语句没有作用域。因此,在和中定义的变量会影响外部。我不能随便命名变量。 +## Strict scope handling +In Python, statements do not have scopes. +Therefore, variables defined in a `for` or `if` have outside effects. You cannot name variables casually. ```python for i in range(10): @@ -16,31 +16,33 @@ for i in range(10): print(x) # 1 ``` -在 Erg 中,每一个区块都有一个范围,完全隔离。 +In Erg, all blocks have scope and are completely isolated. -## 可变对象和不变对象区别明显 - -Python 的可变对象和不变对象、堆对象和值对象之间的区别并不明显,因此,我们需要记住一些知识,比如元组是不变的,但列表是可变的……另外,当你想让自己的班级保持不变时,你必须遵循繁琐的步骤。 +## Clear distinction between mutable and immutable objects +Python is not clear on the distinction between mutable and immutable / heap and value objects, so you have to keep in mind that tuples are immutable but lists are mutable... You need to keep in mind that tuples are immutable, but lists are mutable... and so on. +Also, if you want to make your own classes immutable, you have to go through a tedious process. ```python -# このコードが過去のPythonでは有効だったと信じられますか? +# Can you believe this code is valid for the past versions of Python? i = 256 assert i is 256 i = 257 assert i is not 257 ``` -## trait +## Traits -就像 Java 的界面一样,它可以进行基于合约的编程。 +Just like Java's interface, you can do contract-based programming. -Python 也有一个抽象基类,但这种结构与静态定型结合在一起可以发挥最大的作用。 +Python also has ABC (Abstract Base Class), but this kind of structure works best with static typing. -## 静态解析依赖关系 +## Resolve dependencies statically -防止长时间运行后模块不足而导致错误等导致的游戏体验。 +This prevents the annoying experience of running a program for a long time and then running it with an error due to missing modules. -## 内置包管理器 +## Built-in package manager -使用标准化的目录结构和构建文件进行可重复的构建。当然,还会生成锁定文件并对其进行版本控制。我们不需要对 anaconda,pyenv,poetry,每个项目进行取舍和组合。 +Reproducible builds with a standardized directory structure and build files. +Lock file generation and version control are of course provided. +There is no need to choice or mix anaconda, pyenv, poetry, etc. for each project. diff --git a/doc/zh_CN/index.md b/doc/zh_CN/index.md index 87cf57ae..0dab9ad3 100644 --- a/doc/zh_CN/index.md +++ b/doc/zh_CN/index.md @@ -1,25 +1,25 @@ -# 指数 +# Index ## [API/](./API/index.md) - 描述 Erg 的内置或标准库提供的子程序、类型、常量等的规范。 + This section describes the specifications of subroutines, types, constants, etc. provided by Erg's built-in or standard libraries. ## [compiler/](./compiler/index.md) - 解释了 Erg 编译器(厘米)的设计。 + Describes the design of the Erg compiler (Centimetre). ## [dev_guide/](./dev_guide/index.md) - 项目的开发方针、贡献方式等进行了说明。 + It explains the development policy of the project, how to make contributions, etc. ## [python/](./python/index.md) - 解释了开发 Erg 所需的 Python 知识。 + The knowledge of Python required to develop Erg is explained. ## [syntax/](./syntax/00_basic.md) - Erg语法解释。 + The syntax of Erg is explained. ## [tools/](./tools/index.md) - Erg的外围工具,如何使用命令选项等进行了说明。 \ No newline at end of file + Explains how to use Erg's peripheral tools and command options. diff --git a/doc/zh_CN/migration_from_py.md b/doc/zh_CN/migration_from_py.md index 0ee9f06c..af3a0e43 100644 --- a/doc/zh_CN/migration_from_py.md +++ b/doc/zh_CN/migration_from_py.md @@ -1,28 +1,25 @@ -# Python 到 Erg 迁移的 Tips +# Tips for migrating from Python to Erg -## 要将字符串转换为 int 等 - -请使用类中的方法。它返回类型。 +## I want to convert a string to int etc. +Use the `parse` method of the `Str` class. It returns a `Result` type. ```python s: str i: int = int(s) ``` - -```erg +``` erg s: Str -res: Result(Int, IntParseError) = s.parse Int +res: Result(Int, IntParseError) = s. parse Int i: Int = res.unwrap() -f: Result(Float, FloatParseError) = s.parse Float +f: Result(Float, FloatParseError) = s. parse Float ``` -也可以使用方法。 +You can also use the `try_from` method. - -```erg +``` erg 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 index 32e580eb..e0427708 100644 --- a/doc/zh_CN/python/bytecode_instructions.md +++ b/doc/zh_CN/python/bytecode_instructions.md @@ -1,106 +1,114 @@ # Python Bytecode Instructions -Python bytecode 的变量操作系统的指令通过 namei(name index)进行访问。这是为了实现 Python 的动态变量访问(可以使用 eval 等以字符串访问)。1 命令为 2byte,命令、自变量用 little endian 收纳。不取参数的命令也使用 2byte(参数部分为 0)。 +Python bytecode variable manipulation commands are accessed through namei (name index). This is to achieve dynamic variable access in Python (which can be accessed as a string using eval, etc.). +One instruction is 2 bytes, and the instruction and arguments are stored in little endian. +Instructions that do not take arguments also use 2 bytes (the argument part is 0). ## STORE_NAME(namei) - ```python globals[namei] = stack.pop() ``` ## LOAD_NAME(namei) - ```python stack.push(globals[namei]) ``` -只能在顶层调用。 +Only called at top level. ## LOAD_GLOBAL(namei) - ```python stack.push(globals[namei]) ``` -这是为了在内部作用域中 Load 在顶层 STORE_NAME 后的内容,但如果在顶层,则与某个作用域代码对象中的 namei 不一定相同(名称相同,而不是 namei) +It is for loading STORE_NAME at the top level in the inner scope, but `namei` at the top level is not necessarily the same as namei in the code object of a certain scope (name is the same, not namei) ## LOAD_CONST(namei) - ```python stack.push(consts[namei]) ``` -从常量表中加载常量。目前(Python 3.9),CPython 将每个 Lambda 函数都命名为“\” - +Load constants in the constant table. +Currently (Python 3.9), in CPython, each lambda function is MAKE_FUNCTION with the name "\" ```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 +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(namei) -fastlocals[namei]=stack.pop()可能没有(或单个)与顶级 STORE_NAME 相对应的参照的变量被认为是这样存储的特意全局空间有自己的指令是为了优化? +fastlocals[namei] = stack.pop() +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 是 varnames? +stack.push(fastlocals[namei]) +fastlocals are varnames? ## LOAD_CLOSURE(namei) - ```python cell = freevars[namei] -stack.push(cell) +stack. push(cell) ``` -然后,只有在调用 BUILD_TUPLE 的闭包中才会调用 BUILD_TUPLE,cellvars 将每个 cell(包含引用的容器)push 到堆栈中,而 LOAD_DEREF 似乎存储闭包中的引用 +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) - ```python cell = freevars[namei] cell.set(stack.pop()) ``` -内部作用域中没有参照的变量被 STORE_FAST,但是被参照的变量被 STORE_DEREF 的 Python 中,在这个命令内进行参照计数的增减 +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) - ```python cell = freevars[namei] stack.push(cell.get()) ``` -## 名称列表 +## name list ### varnames -与 fast_locals 相对应的函数内部变量的名称列表 names 中具有相同名称的变量基本上不相同(新创建的变量,不能从该范围访问外部变量),即没有在范围内定义的外部参照的变量将包含在 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 -与 globals 相对应范围内使用的外部常量(仅引用)的名称列表(即使在顶层是普通变量,也会在 names 中)即,范围外定义的常量会在 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 -对应于 freevars 的闭包捕获的变量。在同一函数实例内进行 static 行为。 +Compatible with freevars +Variables captured by the closure. It behaves statically within the same function instance. ## cell variables -cellvars 对应函数内部闭包函数捕获的变量。复制后,原始变量保持不变。 +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/zh_CN/python/bytecode_specification.md b/doc/zh_CN/python/bytecode_specification.md index 8b96fc9b..9cf67b88 100644 --- a/doc/zh_CN/python/bytecode_specification.md +++ b/doc/zh_CN/python/bytecode_specification.md @@ -35,8 +35,8 @@ ## PyStringObject -* 如果我使用ascii以外的字符,它会变成PyUnicode吗? -* "あ", "𠮷“,”和“α”是PyUnicode(不再使用?) +* 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 @@ -50,8 +50,8 @@ ## PyShortAsciiObject -* 说是 short,100 个以上的字也是这个 -* 或者说不是 short 没有 ascii(short 是数据类型?) +* 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 @@ -59,7 +59,8 @@ ## PyInternedObject -** intern 化的对象注册在专用的 map 中,可以用 is 进行比较例如字符串等可以在不考虑长度的常量时间内进行比较 +* 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') diff --git a/doc/zh_CN/python/class_system.md b/doc/zh_CN/python/class_system.md index daa825ca..89b6d2e9 100644 --- a/doc/zh_CN/python/class_system.md +++ b/doc/zh_CN/python/class_system.md @@ -1,9 +1,10 @@ -# Python 类系统(与 Erg 相比) +# Python class system (compare with Erg) -## 方法 - -方法即使参照前方也没有关系,这并不是因为使用了特别的技术,而是因为方法的实际存在被动态检查。(在 Erg 中静态检查方法的实际存在。为了参照前方,必须将函数设为常量。) +## Methods +Methods may be forward referenced, but this is not a special technique used. +This is because the existence of a method is dynamically checked. +(In Erg, method existence is checked statically. For forward references, functions must be constants.) ```python >>> class C: @@ -13,10 +14,10 @@ ... def g(self, x): return self.f(x - 1) ``` -## 继承,覆盖 - -被覆盖的某个方法 m 仅仅像变量的再代入那样被覆盖,参照母类 m 的方法在子类中参照被覆盖的 m。 +## Inheritance, overriding +Some overridden method m is simply overwritten, like a variable reassignment. +A method that refers to m in the parent class will refer to the overridden m in the child class. ```python >>> class C: @@ -26,15 +27,14 @@ >>> class D(C): ... def f(self): return 2 ... ->>> D().g() +>>>> D().g() 2 ``` -因此,即使明显错误地被覆盖,在运行时也不会出现错误。 - +So, even if it is overridden by mistake obviously, it will not be an error until runtime. ```python ->>> class C: +>>>> class C: ... def f(self): return 1 ... def g(self): return self.f() + 1 ... @@ -43,13 +43,13 @@ ... >>> D().g() Traceback (most recent call last): - File "", line 1, in + File "", line 1, in ", line 3, in g TypeError: can only concatenate str (not "int") to str ``` -在 Erg 中静态检查与母类的一致性。在覆盖时,必须赋予装饰器,并且要覆盖的函数类型必须是要覆盖的函数类型的部分类型。 - +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 >>> C = Class() @@ -60,14 +60,14 @@ TypeError: can only concatenate str (not "int") to str ... .f self = "a" ... Error[#XX]: File "", line 5, in D -.f(self) is already defined in C. To override f, it must be added `Override` decorator and its type must be `Self.() -> Nat` or the subtype of that -.f(self)は既にCで定義されています。オーバーライドするためには`Override`デコレータを付与し、`Self.() -> Nat`型かそのサブタイプである必要があります。 +To override f, it must be added `Override` decorator and its type must be `Self.() -> Nat` or the subtype of that +f(self) is already defined in C. To override f, it must be added `Override` decorator and its type must be `Self. To override, it must be given an `Override` decorator and its type must be `Self.() -> Nat` or the subtype of that.f(self). ``` -## 类型检查 - -类型检查大体上只限于函数自变量的类型检查。在 Python 中,大部分的操作都是方法调用。调用时,如果对象所属的类中附有方法的话,就到此为止。 +## Type checking +Type checking is generally all about checking the type of function arguments. +In Python, most operations are method calls. If the class to which the object belongs does not have a method attached to it at the time of the call, that's it. ```python def f(x): @@ -81,7 +81,6 @@ f(c) f(1) # TypeError ``` - ```erg # f: |T, X <: {.m = Self.() -> T}| X -> T f(x) = x.m() diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md index 319b137e..4d643c3b 100644 --- a/doc/zh_CN/syntax/00_basic.md +++ b/doc/zh_CN/syntax/00_basic.md @@ -1,21 +1,23 @@ -# 基本信息 +# Basics -> :此文档尚未完成。未进行校样(文体、正确链接等)。此外,Erg 的语法在 0.* 版本之间可能会有颠覆性的改变,随之而来的文档更新可能跟不上。请事先谅解。 -> 此外,如果你发现本文档中的错误,请从或提出更正建议。 +> __Warning__: This document is incomplete. It has not been proofread (style, correct links, mistranslation, etc.). Also, Erg's syntax may be change destructively during version 0.*, and the documentation may not have been updated accordingly. Please be aware of this beforehand. +> If you find any errors in this document, please report then to [here form](https://forms.gle/HtLYRfYzWCAaeTGb6) or [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new). We would appreciate your suggestions. +> +> [The Erg book original version (Japanese)](http://mtshiba.me/TheErgBook/) -本文档介绍了 Erg 的基本语法。和位于不同的目录中。 +This document describes the basic syntax of Erg. The [Standard API](./API/index.md) and [internal documents for Erg contributors](./dev_guide/index.md) are located in another directory. -## Hello, World! - -首先按照惯例举办 Hello World 活动吧。 +## Hello, World! +First, let's do "Hello World". ```erg print!("Hello, World!") ``` -跟 Python 和同系语言差不多。引人注目的是后面的,我会慢慢解释它的含义。此外,在 Erg 中,如果解释不准确,可以省略括号。与 Ruby 类似,它可以省略括号,但它不能具有多个解释,也不能在参数为 0 时省略,就像 Python 一样。 - +This is almost identical to Python and other languages in the same family. The most striking feature is the `!`, the meaning of which will be explained later. +In Erg, parentheses `()` can be omitted unless there is some confusion in interpretation. +The omission of parentheses is similar to Ruby, but it is not possible to omit parentheses that can be interpreted in more than one way. ```erg print! "Hello, World!" # OK @@ -27,43 +29,71 @@ print! f x # OK, interpreted as `print!(f(x))` print!(f(x, y)) # OK print! f(x, y) # OK print! f(x, g y) # OK -print! f x, y # NG, can be taken to mean either `print!(f(x), y)` or `print!(f(x, y))` +print! f x, y # NG, can be taken to mean either `print!(f(x), y)` or `print!(f(x, y))` print! print!(f x, y) # NG, can be taken to mean either `print!(f(x), y)` or `print!(f(x, y))` print! f(x, g y, z) # NG, can be taken to mean either `print!(x, g(y), z)` or `print!(x, g(y, z))` ``` -## 脚本 +## Scripts -Erg 代码称为脚本。可以以文件格式(.er)保存和运行脚本。 +Erg code is called a script. Scripts can be saved and executed in file format (.er). -## 注释 +## REPL/File Execution -及更高版本将作为注释忽略。当你想要解释代码的意图,或者想要暂时禁用代码时,可以使用此选项。 +To start REPL, simply type: +```sh +> erg +``` + +`>` mark is a prompt, just type `erg`. +Then the REPL should start. + +```sh +> erg +Starting the REPL server... +Connecting to the REPL server... +Erg interpreter 0.2.4 (tags/?:, 2022/08/17 0:55:12.95) on x86_64/windows +>>> +``` + +Or you can compile from a file. + +```sh +> 'print! "hello, world!"' >> hello.er + +> erg hello.er +hello, world! +``` + +## Comments + +The code after `#` is ignored as a comment. Use this to explain the intent of the code or to temporarily disable the code. ```erg -# コメント -## `#`以降は改行されるまで無視されるので、`#`は何個あってもOK +# Comment +# `#` and after are ignored until a new line is inserted #[ -複数行コメント -対応する`]#`のところまでずっとコメントとして扱われます +Multi-line comment +Treated as a comment all the way up to the corresponding `]#` ]# ``` -## 表达式,分隔符 - -脚本是一系列表达式(expression)。表达式是一个可以计算和评估的东西,在 Erg 中几乎所有的东西都是表达式。使用分隔符-换行符或分号-分隔每个表达式。Erg 脚本基本上是从左到右、从上到下进行评估的。 +## Expressions, separators +A script is a series of expressions. An expression is something that can be calculated or evaluated, and in Erg almost everything is an expression. +Each expression is separated by a separator - either a new line or a semicolon `;`-. +Erg scripts are basically evaluated from left to right, top to bottom. ```erg -n = 1 # 代入式 -f(1, 2) # 関数適用式 -1 + 1 # 演算子適用式 +n = 1 # assignment expression +f(1, 2) # function-call expression +1 + 1 # operator-call expression f(1, 2); 1 + 1 ``` -有一个称为即时块的功能,它使用块中最后计算的表达式作为变量的值,如下所示。这与无参数函数不同,它不使用。请注意,方块只在现场评估一次。 - +As shown below, there is a syntax called instant block that takes the last expression evaluated in the block as the value of the variable. +This differs from a function with no arguments, which does not add `()`. Note that instant blocks are evaluated only once on the fly. ```erg i = @@ -72,24 +102,22 @@ i = assert i == 2 ``` -这不能通过分号()来实现。 - +This cannot be accomplished with a semicolon (`;`). ```erg i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses ``` -## 缩进 - -Erg 使用与 Python 相同的缩进来表示块。触发块开始的运算符(特殊格式)有五种:,(其他运算符不是,但也会生成缩进)。它们各自的含义将在后面介绍。 +## Indentation +Erg, like Python, uses indentation to represent blocks. There are five operators (special forms) that trigger the start of a block: `=`, `->`, `=>`, `do`, and `do!` (In addition, `:` and `|`, although not operators, also produce indentation). The meanings of each are described later. ```erg f x, y = x + y for! 0..9, i => - print! i + print! for! 0..9, i => print! i; print! i @@ -101,8 +129,7 @@ ans = match x: _ -> "unknown" ``` -如果一行太长,可以使用在中间换行。 - +If a line is too long, it can be broken using `\`. ```erg # this does not means `x + y + z` but means `x; +y; +z` diff --git a/doc/zh_CN/syntax/01_literal.md b/doc/zh_CN/syntax/01_literal.md index 2e5bfc1f..f8336328 100644 --- a/doc/zh_CN/syntax/01_literal.md +++ b/doc/zh_CN/syntax/01_literal.md @@ -1,43 +1,40 @@ # Literal -## 基本文字 - -### 整数文字(Int Literal) +## Basic Literals +### Int Literal ```erg 0, -0, 1, -1, 2, -2, 3, -3, ... ``` -### 有理数文字(Ratio Literal) - +### Ratio Literal ```erg 0.00, -0.0, 0.1, 400.104, ... ``` -如果文字中的整数或小数部分为,则可以省略。 - +If a `Ratio` literal has an integer or decimal part of `0`, you can omit the `0`. ```erg assert 1.0 == 1. assert 0.5 == .5 ``` -> :这个名为的函数用于指示相等。 -以下文档可能会使用来表示结果相等。 +> __Note__: This function `assert` was used to show that `1.0` and `1.` are equal. +Subsequent documents may use `assert` to indicate that the results are equal. -### 字符串文字(Str Literal) - -可以使用 Unicode 表示的任何字符串。与 Python 不同的是,不能进行标定。如果要在字符串中使用,请使用。 +### Str Literal +Any Unicode-representable string can be used. +Unlike Python, quotation marks cannot be enclosed in `'`. If you want to use `"` in a string, use `\"`. ```erg "", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "السَّلَامُ عَلَيْكُمْ", ... ``` -使用将表达式填充到字符串中。这称为字符串插值。如果要输出本身,请输入。 - +`{}` allows you to embed expressions in strings. This is called string interpolation. +If you want to output `{`, `}` itself, use `\{`, `\}`. ```erg assert "1 + 1 is 2" == "{1} + {1} is {1+1}" @@ -45,84 +42,74 @@ s = "1+1" assert "\{1+1}\" == "\{{s}\}" ``` -### 指数文字(Exponential Literal) - -这是在学术计算中经常使用的指数表示法的文字。它将成为类型为的实例。用于表示非常大/非常小的数字。与 Python 相同。 +### Exponential Literal +This is a literal representing exponential notation often used in academic calculations. It is an instance of type ``Ratio``. +The notation is the same as in Python. ```erg 1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ... ``` - ```erg assert 1e-10 == 0.0000000001 ``` -## 文字的组合(复合文字) +## Compound Literals -在文档中,这些文字都有单独的说明,有关详细信息,请参阅。 - -### 数组文字(./10_array.md) +Each of these literals has its own documentation describing them separately, so please refer to that documentation for details. +### [Array Literal](./10_array.md) ```erg [], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ... ``` -### 字典文字(./11_dict.md) - +### [Dict Literal](./11_dict.md) ```erg {:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ... ``` -### 元组文字(./12_tuple.md) - +### [Tuple Literal](./12_tuple.md) ```erg (), (1, 2, 3), (1, "hello", True), ... ``` -### 记录文字(./13_record.md) - +### [Record Literal](./13_record.md) ```erg {=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ... ``` -### 集文字(./14_set.md) - +### [Set Literal](./14_set.md) ```erg {}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ... ``` -与文字不同,删除重复元素。 - +As a difference from `Array` literals, duplicate elements are removed in `Set`. ```erg assert {1, 2, 1} == {1, 2} ``` -### 看起来像文字但不像文字的东西 - -## 真伪对象(Boolean Object) +### What looks like a literal but isn't +## Boolean Object ```erg True, False ``` -### None 对象 - +### None Object ```erg None ``` -## 范围对象(Range Object) - +## Range Object ```erg assert 0..5 == {1, 2, 3, 4, 5} @@ -131,29 +118,26 @@ assert 0..<10 notin 10 assert 0..9 == 0..<10 ``` -## 浮点对象(Float Object) - +## Float Object ```erg assert 0.0f64 == 0 assert 0.0f32 == 0.0f64 ``` -对象乘以,即的单位对象。 - -## 复杂对象(Complex Object) +Float objects are constructed by multiplying a `Ratio` object by `f64`, which is a `Float 64` unit object. +## Complex Object ```erg 1+2im, 0.4-1.2im, 0im, im ``` -对象仅通过与的运算组合来表示,是一个虚单位对象。 +A `Complex` object is simply an arithmetic combination of an imaginary unit object, `im`. ## *-less multiplication -Erg 可以省略表示乘法的,除非解释正确。但是,运算符的连接强度设置为大于。 - +In Erg, you can omit the `*` to indicate multiplication as long as there is no confusion in interpretation. However, the combined strength of the operators is set stronger than `*`. ```erg # same as `assert (1*m) / (1*s) == 1*(m/s)` diff --git a/doc/zh_CN/syntax/02_name.md b/doc/zh_CN/syntax/02_name.md index 8bc44707..8b87e4a2 100644 --- a/doc/zh_CN/syntax/02_name.md +++ b/doc/zh_CN/syntax/02_name.md @@ -1,56 +1,55 @@ -# 变量 +# Variable -变量是代数的一种。Erg 中的代数-有时也称为变量(如果正确)-是指命名对象并使其可从代码中的其他位置使用的功能。 - -变量定义如下。部分称为变量名(或标识符),称为赋值运算符,部分称为赋值。 +Variables are a type of algebra; algebra in Erg - sometimes simply referred to as variable if there is no confusion - refers to the feature to name objects and make them referable from elsewhere in the code. +A variable is defined as follows. +The `n` part is called the variable name (or identifier), `=` is the assignment operator, and the `1` part is the assigned value. ```erg n = 1 ``` -以这种方式定义的随后可用作表示整数对象的变量。此系统称为赋值(或绑定)。我们刚才提到了是一个对象。我们将在后面讨论对象是什么,但我们现在应该将其赋值到赋值运算符(例如)的右侧。 - -如果要指定变量的类型。类型是指对象所属的集合,这也将在后面介绍。指定为自然数()。 +The `n` defined in this way can thereafter be used as a variable to denote the integer object `1`. This system is called assignment (or binding). +We have just said that `1` is an object. We will discuss what an object is later, but for now we will assume that it is something that can be assigned to, i.e., on the right side of the assignment operator (`=`, etc.). +If you want to specify the "type" of a variable, do the following. The type is roughly the set to which an object belongs, as will be explained later. +Here we specify that `n` is a natural number (`Nat`) type. ```erg n: Nat = 1 ``` -请注意,与其他语言不同,多重赋值是不可能的。 - +Note that, unlike other languages, multiple assignments are not allowed. ```erg # NG -l1 = l2 = [1, 2, 3] # SyntaxError: 多重代入はできません +l1 = l2 = [1, 2, 3] # SyntaxError: multiple assignment not allowed # OK l1 = [1, 2, 3] l2 = l1.clone() ``` -也不能对变量进行重新赋值。可以使用的功能,即保持可变状态的功能将在后面讨论。 - +It is also not possible to reassign to a variable. The syntax that can be used instead, to hold mutable states, are described later. ```erg i = 1 i = i + 1 # AssignError: cannot assign twice ``` -你可以在内部范围内定义具有相同名称的变量,但它们只是放在上面,而不是破坏性地重写值。如果返回到外部范围,则值也将返回。请注意,这与 Python“语句”的作用域不同。这类功能通常称为阴影。但是,与其他语言的阴影不同,你不能在同一范围内进行阴影。 - +You can define a variable with the same name in the inner scope, but you are only covering it over, not destructively rewriting its value. If you go back to the outer scope, the value will return as well. +Note that this is a different behavior than the Python "statement" scope. +This kind of functionality is generally referred to as shadowing. However, unlike shadowing in other languages, you cannot shadow in the same scope. ```erg x = 0 # x = 1 # AssignError: cannot assign twice if x.is_zero(), do: - x = 1 # 外側のxとは同名の別物 + x = 1 # different from outer x with same name assert x == 1 assert x == 0 ``` -以下乍一看似乎可行,但还是不行。这不是技术限制,而是设计判断。 - +The following may seem possible at first glance, but it is still not possible. This is a design decision, not a technical constraint. ```erg x = 0 @@ -60,10 +59,10 @@ if x.is_zero(), do: assert x == 0 ``` -## 常数 - -常数也是代数的一种。如果标识符以大写字母开头,则将其视为常量。它被称为常量,因为它一旦定义就不会改变。部分称为常量名称(或标识符)。其他与变量相同。 +## Constants +Constants are also a type of algebra. If you start an identifier with a capital letter, it is treated as a constant. They are called constants because once defined, they do not change. +The `N` part is called the constant name (or identifier). Otherwise, it is the same as a variable. ```erg N = 0 @@ -72,10 +71,11 @@ if True, do: pass() ``` -常量在定义的范围之后变得不变。我也不能阴影。由于该性质,常量可用于模式匹配。后面我们会讨论模式匹配。 +Constants are immutable beyond the defined scope. They cannot be shadowed. Because of this property, constants can be used in pattern matching. Pattern matching is explained later. -你可能希望将常量用于不变的值,如数学常量或有关外部资源的信息。除之外的对象通常是全部大写字母(所有字符都是大写的样式)。 +For example, constants are used for mathematical constants, information about external resources, and other immutable values. +It is common practice to use all-caps (style in which all letters are capitalized) for identifiers of objects other than [types](./type/01_type_system.md). ```erg PI = 3.141592653589793 @@ -83,7 +83,6 @@ URL = "https://example.com" CHOICES = ["a", "b", "c"] ``` - ```erg PI = 3.141592653589793 match! x: @@ -91,20 +90,19 @@ match! x: other => print! "other" ``` -当为时,上面的代码输出。如果将更改为其他数字,则输出。 - -有些常量是不能赋值的。可变对象等等。可变对象是可以更改其内容的对象,如下所述。这是因为常量只能由常量表达式赋值。我们还将在后面讨论常数表达式。 +The above code prints `π` when `x` is `3.141592653589793`. If `x` is changed to any other number, it prints `other`. +Some objects cannot be bound as constants. Mutable objects, for example. Mutable objects are objects whose states can be changed, as described in detail later. +This is because of the rule that only constant expressions can be assigned to constants. Constant expressions are also discussed later. ```erg X = 1 # OK X = !1 # TypeError: cannot define Int! object as a constant ``` -## 删除代数 - -可以使用函数删除代数。所有依赖于代数(直接引用代数的值)的其他代数都将被删除。 +## Delete an Variable +You can delete an variable by using the `Del` function. All other variables that depend on the variable (that is, that refer directly to the value of the variable) are also removed. ```erg x = 1 @@ -119,27 +117,24 @@ Del y, Z f(2) # NameError: f is not defined (deleted in line 6) ``` -但是,只能删除模块中定义的代数。不能删除内置常量,如。 - +Note that `Del` can only delete variables defined in the user-defined module. Built-in constants such as `True` cannot be deleted. ```erg Del True # TypeError: cannot delete built-in constants Del print! # TypeError: cannot delete built-in variables ``` -## Appendix:赋值等价性 - -注意,当时,不一定是。例如有。这是由 IEEE 754 规定的正式浮点数的规格。 +## Appendix: Assignment and Equivalence +Note that `x == a` is not necessarily true when `x = a`. An example is `Float.NaN`. This is the formal specification of floating-point numbers as defined by IEEE 754. ```erg x = Float.NaN -assert x != Float.NaN -assert x != x +assert x ! = NaN +assert x ! = x ``` -其他,也存在原本就没有定义等值关系的对象。 - +There are other objects for which no equivalence relation is defined in the first place. ```erg f = x -> x**2 + 2x + 1 @@ -151,8 +146,8 @@ D = Class {i: Int} C == D # TypeError: cannot compare class objects ``` -严格地说,并不是将右边值直接代入左边的识别符。函数对象和类对象的情况下,对对象进行赋予变量名的信息等的“修饰”。但是结构型的情况不受此限制。 - +Strictly speaking, `=` does not assign the right-hand side value directly to the left-hand side identifier. +In the case of function and class objects, "modification" such as giving variable name information to the object is performed. However, this is not the case for structural types. ```erg f x = x diff --git a/doc/zh_CN/syntax/03_declaration.md b/doc/zh_CN/syntax/03_declaration.md index 2cdffa57..b609984e 100644 --- a/doc/zh_CN/syntax/03_declaration.md +++ b/doc/zh_CN/syntax/03_declaration.md @@ -1,11 +1,12 @@ -# 声明 - -声明是指定要使用的变量类型的语法。可以在代码中的任何地方声明,但不能只声明变量。必须始终初始化。赋值后声明可以检查类型是否与赋值对象匹配。 +# Declaration +Declaration is the syntax for specifying the type of variable to be used. +Declarations can be made anywhere in the code, but declarations alone do not refer to the variables. They must be initialized. +After the assignment, the declaration can be checked to ensure that the type is compatible with the object to which it is assigned. ```erg i: Int -# i: Int = 2可以与赋值同时声明 +# Can be declared at the same time as the assignment, like i: Int = 2 i = 2 i: Num i: Nat @@ -13,26 +14,24 @@ i: -2..2 i: {2} ``` -赋值后声明类似于类型检查,但在编译时进行检查。运行时使用进行类型检查可以用“可能是 XX”进行检查,但编译时使用进行类型检查是严格的。如果没有确定是“某某型”,就无法通过检查,就会出现错误。 - +Declaration after assignment is similar to type checking by `assert`, but has the feature that it is checked at compile time. +Type checking by `assert` at runtime can be checked for "may be type Foo", but type checking by `:` at compile time is strict: if the type is not determined to be "type Foo", it will not pass the check and an error will occur. ```erg -i = (-1..10).sample!() -assert i in Nat # 这可能会通过 -i: Int # 这通过了 -i: Nat # 这不起作用(因为 -1 不是 Nat 的元素) +i = (-1..10).sample! +assert i in Nat # this may pass +i: Int # this will pass +i: Nat # this will not pass (-1 is not an element of Nat) ``` -可以通过两种方式声明函数。 - +Functions can be declared in 2 different ways. ```erg f: (x: Int, y: Int) -> Int f: (Int, Int) -> Int ``` -如果显式声明参数名称,则在定义时如果名称不同,将导致类型错误。如果你想给出参数名称的任意性,可以使用第二种方法声明它。在这种情况下,类型检查只显示方法名称及其类型。 - +If you declare the argument names explicitly, a type error will result if the names are different at definition time. If you want to give the argument names arbitrary names, you can declare them in the second way. In that case, only the method name and its type will be seen by type checking. ```erg T = Trait { diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md index a500538c..be531d30 100644 --- a/doc/zh_CN/syntax/04_function.md +++ b/doc/zh_CN/syntax/04_function.md @@ -1,7 +1,6 @@ -# 函数 - -函数是一个块,它接受参数并对其进行处理,然后将其作为返回值返回。定义如下。 +# Function +A function is a block that takes an "argument", processes it, and returns it as a "return value". It is defined as follows. ```erg add x, y = x + y @@ -9,8 +8,10 @@ add x, y = x + y add(x, y) = x + y ``` -在定义函数时指定的参数通常称为伪参数(parameter)。相反,函数调用过程中传递的参数称为实际参数(argument)。是接受作为假参数,然后返回的函数。你可以按如下方式调用(应用)定义的函数。 - +The names specified after a function name are called parameters. +In contrast, the objects passed to a function are called arguments. +The function `add` is a function that takes `x` and `y` as parameters and returns the sum of them, `x + y`. +The defined function can be called (applied/invoked) as follows. ```erg add 1, 2 @@ -18,30 +19,26 @@ add 1, 2 add(1, 2) ``` -## 冒号样式 - -函数的调用方式如下:,但如果实际参数太多,一行太长,则可以使用(冒号)来应用。 +## Colon application style +Functions are invoked like `f x, y, ...`, but if there are too many arguments for a single line, they can be applied using `:` (colon). ```erg f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4 ``` - ```erg f some_long_name_variable_1 + some_long_name_variable_2: some_long_name_variable_3 * some_long_name_variable_4 ``` - ```erg f: some_long_name_variable_1 + some_long_name_variable_2 some_long_name_variable_3 * some_long_name_variable_4 ``` -上面三个代码都是同一个意思。此样式在使用函数时也很有用。 - +All three codes above mean the same thing. This style is also useful when using `if` functions, for example. ```erg result = if Bool.sample!(): @@ -53,26 +50,24 @@ result = if Bool.sample!(): 0 ``` -在之后,不能写注释以外的代码,必须换行。 +After `:`, no code other than comments may be written, and must always be on a new line. -## 关键字参数(Keyword Arguments) - -如果定义了具有大量参数的函数,则可能会导致传递参数的顺序错误。在这种情况下,使用关键字参数进行调用是安全的。 +## Keyword Arguments +If a function is defined with a large number of parameters, there is a danger of passing the arguments in the wrong order. +In such cases, it is safe to call the function using keyword arguments. ```erg f x, y, z, w, v, u: Int = ... ``` -上面定义的函数有很多参数,并且排列很难懂。我们不应该做这样的函数,但在使用别人写的代码时可能会碰到这样的代码。因此,我们使用关键字参数。关键字参数的名称优先于顺序,因此即使顺序不正确,也会将值从名称传递到正确的参数。 - +The functions defined above have many arguments and are arranged in a confusing order. You should not create such a function, but you may encounter such code when using code written by others. Therefore, we use keyword arguments. If you use keyword arguments, the values are passed from the name to the correct argument, even if they are in the wrong order. ```erg f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3 ``` -请注意,如果在关键字参数和之后立即换行,将被视为冒号应用样式。 - +Note that keyword arguments and a new line immediately after the `:` are considered a colon-call style. ```erg # means `f(x: y)` @@ -83,12 +78,11 @@ f x: y ``` -## 默认参数(Default parameters) +## Default parameters -如果一个参数在大多数情况下是固定的,并且你想要省略它,则可以使用默认参数。 - -缺省参数由(or-assign operator)指定。如果未指定,则将赋给。 +Default parameters are used when some parameters are mostly fixed and you want to be able to omit them. +Default parameters are specified by `:=`(walrus operator). If `base` is not specified, assign `math.E` to `base`. ```erg math_log x: Ratio, base := math.E = ... @@ -97,52 +91,46 @@ assert math_log(100, 10) == 2 assert math_log(100) == math_log(100, math.E) ``` -请注意,不指定参数和赋值是有区别的。 - +Note that there is a distinction between specifying no argument and assigning `None`. ```erg -p! x := 0 = print! x +p! x := 0 = print! p!(2) # 2 p!() # 0 p!(None) # None ``` -也可以与类型和模式一起使用。 - +Can also be used with type specification and patterns. ```erg math_log x, base: Ratio := math.E = ... f [x, y] := [1, 2] = ... ``` -但是,在缺省参数中,不能调用以下过程或赋值可变对象。 - +However, within the default arguments, it is not possible to call the procedures (described later) or assign mutable objects. ```erg f x := p! 1 = ... # NG ``` -此外,不能将刚定义的参数用作传递给缺省参数的值。 - +Also, the argument just defined cannot be used as the value passed to the default argument. ```erg f x := 1, y := x = ... # NG ``` -## 可变长度参数 - -函数将参数作为日志输出,可以接收任意数量的参数。 +## Variable-length arguments +The `log` function, which outputs a log (record) of its arguments, can take any number of arguments. ```erg log "Hello", "World", "!" # Hello World ! ``` -如果要定义这样的函数,请将作为参数。这样,参数就可以作为可变长度数组接收。 - +To define such a function, add `...` to a parameter. This way, the function receives arguments as a variable-length array. ```erg -f x: ...Int = +f ...x = for x, i -> log i @@ -150,8 +138,7 @@ f x: ...Int = f 1, 2, 3, 4, 5 ``` -## 多模式函数定义 - +## Function definition with multiple patterns ```erg fib n: Nat = @@ -161,8 +148,7 @@ fib n: Nat = n -> fib(n - 1) + fib(n - 2) ``` -如果函数的定义正下方出现,如上面所示,则可以重写如下所示。 - +Functions like the one above, where `match` appears directly under the definition, can be rewritten as follows. ```erg fib 0 = 0 @@ -170,20 +156,18 @@ fib 1 = 1 fib(n: Nat): Nat = fib(n - 1) + fib(n - 2) ``` -请注意,多模式函数定义不是所谓的过载(多重定义)。一个函数始终只有一个类型。在上面的示例中,必须与具有相同的类型。此外,与相同,模式匹配从上到下依次进行。 - -如果存在不同类的混合实例,则必须在最后一个定义中指明函数参数类型为 Or。 +Note that a function definition with multiple patterns is not so-called overloading (multiple definition); a function has only a single definition. In the example above, `n` must be of the same type as `0` or `1`. Also, as with `match`, pattern matching is done from top to bottom. +If instances of different classes are mixed, the last definition must specify that the function argument is of type `Or`. ```erg f "aa" = ... f 1 = ... -# `f x = ...` is invalid +# `f x = ... ` is invalid f x: Int or Str = ... ``` -它还必须具有包容性,如。 - +Also, like `match`, it must also be exhaustive. ```erg fib 0 = 0 @@ -191,8 +175,7 @@ fib 1 = 1 # PatternError: pattern of fib's parameter is not exhaustive ``` -但是,即使在上述情况下,也可以使用下面的显式指定类型来获得全面性。 - +However, it can be made exhaustive by explicitly specifying the type using the [refinement type](./type/12_refinement.md) described later. ```erg fib: 0..1 -> 0..1 @@ -201,12 +184,12 @@ fib 1 = 1 # OK ``` -## 递归函数 +## Recursive functions -递归函数是定义中包含自身的函数。 - -作为一个简单的例子,我们尝试定义函数来计算阶乘。阶乘是“乘以所有小于或等于的正数”的计算。5 的阶乘为。 +A recursive function is a function that includes itself in its definition. +As a simple example, let us define a function `factorial` that performs a factorial calculation. Factorial is a computation that "multiplies all positive numbers less than or equal to". +The factorial of 5 is `5*4*3*2*1 == 120`. ```erg factorial 0 = 1 @@ -214,10 +197,13 @@ factorial 1 = 1 factorial(n: Nat): Nat = n * factorial(n - 1) ``` -首先从阶乘定义开始,0 和 1 的阶乘都是 1. 按顺序计算,2 的阶乘为,3 的阶乘为,4 的阶乘为。如果你仔细观察这里,你会发现一个数字 n 的阶乘是它前面的数字 n-1 的阶乘乘以 n。如果你将其放入代码中,则会得到。是递归函数,因为的定义包含它自己。 - -注意,如果未指定类型,则会这样推断。 +First, from the definition of factorial, the factorial of 0 and 1 are both 1. +In turn, the factorial of 2 is `2*1 == 2`, the factorial of 3 is `3*2*1 == 6`, and the factorial of 4 is `4*3*2*1 == 24`. +If we look closely, we can see that the factorial of a number n is the factorial of the preceding number n-1 multiplied by n. +Putting this into code, we get `n * factorial(n - 1)`. +Since the definition of `factorial` contains itself, `factorial` is a recursive function. +As a reminder, if you do not add a type specification, it is inferred like this. ```erg factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int @@ -226,19 +212,20 @@ factorial 1 = 1 factorial n = n * factorial(n - 1) ``` -但是,即使可以推理,也应该明确指定递归函数的类型。在上面的示例中,像这样的代码是有效的, - +However, even if you can reason about it, you should explicitly specify the type of the recursive function. In the example above, a code like ``factorial(-1)`` would work, but ```erg factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ... ``` -,此计算不会停止。如果不仔细定义值的范围,递归函数可能会陷入无限循环。类型还有助于防止接受不想要的值。 +and this computation does not stop. Recursive functions must carefully define the range of values or you may end up in an infinite loop. +So the type specification also helps to avoid accepting unexpected values. -## 编译时函数 - -如果函数名以大写字母开头,则该函数为编译时函数。所有用户定义的编译时函数的参数都必须是常量,并且必须显式。编译函数能做的事情是有限的。在编译时函数中只能使用常量表达式,即某些运算符(四则运算,比较运算,类型构建运算等)和编译时函数。赋值的参数也必须是常量表达式。相反,计算可以在编译时进行。 +## Compile-time functions +A function name begins with an uppercase letter to indicate a compile-time function. User-defined compile-time functions must have all arguments as constants and must specify their types. +Compile-time functions are limited in what they can do. Only constant expressions can be used in compile-time functions, i.e., only some operators (such as quadrature, comparison, and type construction operations) and compile-time functions. Arguments to be passed must also be constant expressions. +In return, the advantage is that the computation can be done at compile time. ```erg Add(X, Y: Nat): Nat = X + Y @@ -252,18 +239,16 @@ math = import "math" Sin X = math.sin X # ConstantError: this function is not computable at compile time ``` -编译时函数通常用于多相类型定义等。 - +Compile-time functions are also used in polymorphic type definitions. ```erg Option T: Type = T or NoneType Option: Type -> Type ``` -## Appendix:比较函数 - -Erg 没有为函数定义。那是因为函数的结构等价性判定算法一般不存在。 +## Appendix: Function Comparison +Erg does not define `==` for functions. This is because there is no structural equivalence algorithm for functions in general. ```erg f = x: Int -> (x + 1)**2 @@ -272,18 +257,17 @@ g = x: Int -> x**2 + 2x + 1 assert f == g # TypeError: cannot compare functions ``` -和总是返回相同的结果,但这是非常困难的。我们得把代数学灌输给编译器。因此,Erg 放弃了整个函数比较,也会导致编译错误。这是与 Python 不同的规格,需要注意。 - +Although `f` and `g` always return the same result, it is extremely difficult to make that determination. We have to teach algebra to the compiler. +So Erg gives up on function comparisons entirely, and `(x -> x) == (x -> x)` also results in a compile error. This is a different specification from Python and should be noted. ```python # Python, weird example f = lambda x: x assert f == f -assert (lambda x: x) != (lambda x: x) +assert (lambda x: x) ! = (lambda x: x) ``` -## Appendix2:完成() - +## Appendix2: ()-completion ```erg f x: Object = ... @@ -299,7 +283,7 @@ f(a, b) # TypeError: f() takes 1 positional argument but 2 were given f((a, b)) # OK ``` -函数类型实际上是的语法糖。 +The function type `T -> U` is actually the syntax sugar of `(T,) -> U`.

Previous | Next diff --git a/doc/zh_CN/syntax/05_builtin_funcs.md b/doc/zh_CN/syntax/05_builtin_funcs.md index a843467c..f0b3075a 100644 --- a/doc/zh_CN/syntax/05_builtin_funcs.md +++ b/doc/zh_CN/syntax/05_builtin_funcs.md @@ -1,9 +1,8 @@ -# 内置函数 +# Built-in functions ## if -是一个函数,它可以根据条件改变操作。 - +`if` is a function that changes processing depending on a condition. ```erg result: Option Int = if! Bool.sample!(), do: @@ -12,8 +11,8 @@ result: Option Int = if! Bool.sample!(), do: print! result # None (or 1) ``` -随机返回集合的值。如果返回值为 true,则执行。还可以指定当条件为假时如何处理。第二个 do 块称为 else 块。 - +`.sample!()` returns a random set of values. If the return value is true, `print! "True"` is executed. +You can also specify what to do if the condition is false; the second do block is called the else block. ```erg result: Nat = if Bool.sample!(): @@ -26,8 +25,7 @@ result: Nat = if Bool.sample!(): print! result # 1 (or 0) ``` -如果只执行一行操作,则可以省略缩进。 - +If the process is a single line, you can omit indentation. ```erg result = if Bool.sample!(): @@ -37,8 +35,7 @@ result = if Bool.sample!(): ## for -你可以使用来编写重复的操作。 - +You can use `for` to write a repeating process. ```erg match_s(ss: Iterator(Str), pat: Pattern): Option Str = diff --git a/doc/zh_CN/syntax/06_operator.md b/doc/zh_CN/syntax/06_operator.md index 20b655e6..abe81367 100644 --- a/doc/zh_CN/syntax/06_operator.md +++ b/doc/zh_CN/syntax/06_operator.md @@ -1,13 +1,13 @@ -# 运算符 +# operator -运算符(操作符)是表示运算的符号。运算符(操作数)位于运算符的右侧(左),在 Erg 中它只是一个对象。 +Operators are symbols that represent operations. Operands are things to the (left) right of an operator. -运算符是一种函数,因此它本身也可以绑定到一级对象中的变量。绑定必须用包围。对于(和),必须指定(二元运算)/(一元运算)以实现唯一化,因为同时存在一元运算符和二元运算符。 +Operators are a kind of function, and thus are themselves first-class objects that can be bound to variables. When binding, it is necessary to enclose it with ``. +For `+` (and `-`), there are both unary and binary operators, so `_+_`(binary operation)/`+_`(unary operation ) must be specified. - -```erg +``` erg add = `+` # SyntaxError: specify `_+_` or `+_` -add = `_+_` +add=`_+_` assert f(1, 2) == 3 assert f("a", "b") == "ab" @@ -15,10 +15,9 @@ g = `*` # OK, this is binary only assert g(1, 2) == 2 ``` -但是,请注意,某些称为特殊格式的运算符不能被绑定。 +Some fundamental operators, called special forms, cannot be bound. - -```erg +``` erg def = `=` # SyntaxError: cannot bind `=` operator, this is a special form # NG: def x, 1 function = `->` # SyntaxError: cannot bind `->` operator, this is a special form diff --git a/doc/zh_CN/syntax/07_side_effect.md b/doc/zh_CN/syntax/07_side_effect.md index 85944adf..342cae82 100644 --- a/doc/zh_CN/syntax/07_side_effect.md +++ b/doc/zh_CN/syntax/07_side_effect.md @@ -1,36 +1,34 @@ -# 副作用和过程 - -到目前为止,我一直没有解释中的含义,现在我终于明白了它的含义。这个!直截了当地表示此对象是具有“副作用”的“过程”。过程对函数产生了一种称为“副作用”的效果。 +# Side effects and procedures +We have been neglecting to explain the meaning of the `!`, but now its meaning will finally be revealed. This `!` indicates that this object is a "procedure" with a "side-effect". A procedure is a function with a side-effect. ```erg f x = print! x # EffectError: functions cannot be assigned objects with side effects # hint: change the name to 'f!' ``` -上面的代码是编译错误。因为你在函数中使用过程。在这种情况下,必须将其定义为过程。 - +The above code will result in a compile error. This is because you are using a procedure in a function. In such a case, you must define it as a procedure. ```erg p! x = print! x ``` -,,...是代表过程的典型变量名称。以这种方式定义的过程也不能在函数中使用,因此副作用是完全隔离的。 +`p!`, `q!`, ... are typical variable names for procedures. +Procedures defined in this way also cannot be used within a function, so side-effects are completely isolated. -## 方法 - -每个函数和过程都有一个方法。函数方法仅保留的不变引用,过程方法保留的可变引用。是一个特殊参数,在方法上下文中是指调用的对象本身。引用的不能指定给任何其他变量。 +## Methods +Functions and procedures each can be methods. Functional methods can only take immutable references to `self`, while procedural methods can take mutable references to `self`. +The `self` is a special parameter, which in the context of a method refers to the calling object itself. The reference `self` cannot be assigned to any other variable. ```erg -C. +C!. method ref self = x = self # OwnershipError: cannot move out 'self' x ``` -该方法还可以剥夺的所有权。该方法的定义不包括。 - +Procedural methods can also take [ownership](./18_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition. ```erg n = 1 @@ -38,39 +36,39 @@ s = n.into(Str) # '1' n # ValueError: n was moved by .into (line 2) ``` -始终只能有一个过程方法具有可变引用。此外,当可变参照被取走时,将无法从原始对象获取参照。从这个意义上说,会对产生副作用。 - -但是,请注意,可以从可变参照生成(不变/可变)参照。这允许你在过程方法中递归或。 +Only one procedural methods can have a mutable reference at any given time. In addition, while a mutable reference is taken, no more mutable reference can be taken from the original object. In this sense, `ref!` causes a side-effect on `self`. +Note, however, that it is possible to create (immutable/mutable) references from mutable references. This allows recursion and `print!` of `self` in procedural methods. ```erg T -> T # OK (move) -T -> Ref T # OK +T -> Ref T # OK (move) T => Ref! T # OK (only once) Ref T -> T # NG Ref T -> Ref T # OK -Ref T => Ref! T # NG -Ref! T -> T # NG -Ref! T -> Ref T # OK -Ref! T => Ref! T # OK +Ref T => Ref! +T -> Ref T # NG +T -> Ref T # OK +T => Ref! ``` -## Appendix:严格定义副作用 +## Appendix: Strict definition of side-effects -代码有没有副作用的规则并不是马上就能理解的。在理解之前,建议先将其定义为函数,然后在出现错误时将其定义为过程。但是,对于那些想要掌握语言严格规范的人来说,下面我们会更详细地介绍副作用。 +The rules for whether a code has a side-effect or not are not immediately understandable. +Until you can understand them, we recommend that you leave it to the compiler to define them as functions for the time being, and if an error occurs, add `!` to treat them as procedures. +However, for those who want to understand the exact specifications of the language, the following is a more detailed explanation of side-effects. -首先,请注意,返回值的等价性与 Erg 中的副作用无关。对于任何,都有一个过程(例如,总是返回),也有一个函数是。 - -前一个示例是,后一个示例是以下函数。 +First, it must be stated that the equivalence of return values is irrelevant with respect to side effects in Erg. +There are procedures that for any given `x` will result in `p!(x) == p!(x)` (e.g. always return `None`), and there are functions that will result in `f(x) ! = f(x)`. +An example of the former is `print!`, and an example of the latter is the following function. ```erg nan _ = Float.NaN -assert nan(1) != nan(1) +assert nan(1) ! = nan(1) ``` -也有一些对象无法进行等价判定,例如类或函数。 - +There are also objects, such as classes, for which equivalence determination itself is not possible. ```erg T = Structural {i = Int} @@ -82,14 +80,13 @@ D = Class {i = Int} assert C == D # TypeError: cannot compare classes ``` -回到正题上来。“副作用”在 Erg 中的确切定义是, +Back to the point: the precise definition of "side-effect" in Erg is -* 访问外部可变信息 +* Accessing mutable external information. -中选择所需的墙类型。外部通常是指外部范围。“外部”不包括 Erg 无法接触的计算机资源或运行前/运行后信息。“访问”不仅包括写入,还包括读取。 - -以过程为例。看似没有重写任何变量。但是,如果这是一个函数,那么外部变量可以用这样的代码重写。 +"External" generally refers to the outer scope; computer resources that Erg cannot touch and pre-/post-execution information are not included in "external". "Access" includes reading as well as writing. +As an example, consider the `print!` procedure. At first glance, `print!` does not seem to rewrite any variables. But if it were a function, it could rewrite outer variables, for example, with code like this: ```erg camera = import "some_camera_module" @@ -97,17 +94,18 @@ ocr = import "some_ocr_module" n = 0 _ = - f x = print x # 仮にprintを関数として使えたとします + f x = print x # Suppose we could use print as a function f(3.141592) -cam = camera.new() # カメラはPCのディスプレイを向いています +cam = camera.new() # camera faces PC display image = cam.shot!() n = ocr.read_num(image) # n = 3.141592 ``` -模块是为相机产品提供 API 的外部库,是 OCR(光学字符识别)的库。直接副作用是由引起的,但显然,这些信息是从泄露的。因此,在性质上不能是函数。 - -然而,当你在函数中临时检查值时,你可能不希望将附加到相关函数中。在这种情况下,可以使用函数在执行整个代码后显示值。这不会传播副作用。 +Think of the `camera` module as an external library providing an API for a certain camera product, and `ocr` as a library for OCR (optical character recognition). +The direct side-effect is caused by `cam.shot!()`, but obviously that information is leaked from `f`. Therefore, `print!` cannot be a function by nature. +Nevertheless, there may be cases where you want to temporarily check a value in a function and do not want to add `!` in the related function just for that purpose. In such cases, the `log` function can be used. +`log` prints the value after the entire code has been executed. In this way, side-effects are not propagated. ```erg log "this will be printed after execution" @@ -116,7 +114,7 @@ print! "this will be printed immediately" # this will be printed after execution ``` -换句话说,如果程序没有反馈,即任何外部对象都不能使用该信息,则信息的“泄露”本身可能是允许的。不被“传播”就行了。 +If there is no feedback to the program, or in other words, if no external object can use the internal information, then the "leakage" of the information may be allowed. It is only necessary that the information not be "propagated".

Previous | Next diff --git a/doc/zh_CN/syntax/08_procedure.md b/doc/zh_CN/syntax/08_procedure.md index 28a74bcd..44363e46 100644 --- a/doc/zh_CN/syntax/08_procedure.md +++ b/doc/zh_CN/syntax/08_procedure.md @@ -1,7 +1,7 @@ -# 过程 - -处理可变对象时需要过程,但如果变量对象是参数,则不一定是过程。 +# Procedures +Procedures are necessary when dealing with mutable objects, but having a mutable object as an argument does not necessarily make it a procedure. +Here is a function takes a mutable object (not procedure). ```erg peek_str s: Str! = log s diff --git a/doc/zh_CN/syntax/09_builtin_procs.md b/doc/zh_CN/syntax/09_builtin_procs.md index 6b731630..5a78d28e 100644 --- a/doc/zh_CN/syntax/09_builtin_procs.md +++ b/doc/zh_CN/syntax/09_builtin_procs.md @@ -1,9 +1,10 @@ -# 内置过程 +# Built-in procedure ## id! -返回对象的唯一标识号。在纯 Erg 语义中,结构相同的对象之间没有差异,但实际上,对象在内存中的位置是不同的。返回表示此位置的数字。 - +Returns the unique identification number of the object. +Although in pure Erg semantics no difference can be found between objects with the same structure, in practice objects have different locations in memory. +`id!` returns a number representing this position. ```erg ``` diff --git a/doc/zh_CN/syntax/10_array.md b/doc/zh_CN/syntax/10_array.md index 067f9564..a3c8c20c 100644 --- a/doc/zh_CN/syntax/10_array.md +++ b/doc/zh_CN/syntax/10_array.md @@ -1,12 +1,12 @@ -# 排列 - -数组是最基本的。集合是可以在内部包含多个对象的对象。 +# Array +Arrays are the most basic __collection (aggregate)__. +A collection is an object that can hold multiple objects inside it. ```erg a = [1, 2, 3] -a: [Int; 3] # 型指定: セミコロンの後の数字は要素数 -# 要素数がわからない場合は省略可能 +a: [Int; 3] # Type specification: number after semicolon is the number of elements +# Can be omitted if the number of elements is not known a: [Int] mut_a = [!1, !2, !3] @@ -14,41 +14,37 @@ mut_a[0].inc!() assert mut_a == [2, 2, 3] ``` -通常,数组不能包含不同类型的对象。 +As a rule, arrays cannot contain objects of different types. - -```erg +```erg. [1, "a"] # TypeError: 1st element is Int, but 2nd element is Str ``` -但是,这种显式类型可以避免限制。 - +However, you can bypass the restriction by explicitly specifying the type like this. ```erg -[1, "a"]: [Int or Str] +[1, "a"]: [Int or Str]. ``` -## 切片 - -数组还可以同时检索多个值。我们管这个叫切片。 +## Slice +An array can also have multiple values taken out at once. This is called slicing. ```erg l = [1, 2, 3, 4] -# Pythonのl[1:3]に相当 -assert l[1..<3] == [2, 3] +# Same as l[1:3] in Python +assert l[1.. <3] == [2, 3] assert l[1..2] == [2, 3] -# l[1]と同じ +# Same as l[1] assert l[1..1] == [2] -# Pythonのl[::2]に相当 +# Same as l[::2] in Python assert l[..].step(2) == [2, 4] ``` -切片获得的对象是数组的(不可变)引用。 - +The object obtained by slicing is an (immutable) copy to an array. ```erg -print! Typeof l[1..2] # Ref [Int; 4] +print! Typeof l[1..2] # [Int; 4] ```

diff --git a/doc/zh_CN/syntax/11_tuple.md b/doc/zh_CN/syntax/11_tuple.md index ec52e918..75a942c3 100644 --- a/doc/zh_CN/syntax/11_tuple.md +++ b/doc/zh_CN/syntax/11_tuple.md @@ -1,7 +1,7 @@ -# 元 - -元组类似于数组,但可以包含不同类型的对象。这样的收藏称为非等质收藏。与此相对,等质集合包括数组和集合。 +# Tuple +Tuples are similar to arrays, but can hold objects of different types. +Such a collection is called an unequal collection. In contrast, homogeneous collections include arrays, sets, etc. ```erg t = (1, True, "a") @@ -9,8 +9,8 @@ t = (1, True, "a") assert(i == 1 and b == True and s == "a") ``` -元组可以以的形式检索第 n 个元素。请注意,与 Python 不同,它不是。这是因为元组元素的访问更接近于属性,而不是方法(数组中的是方法)(编译时检查元素是否存在,类型可以根据 n 而变化)。 - +The tuple `t` can retrieve the nth element in the form `t.n`; note that unlike Python, it is not `t[n]`. +This is because accessing tuple elements is more like an attribute (the existence of the element is checked at compile time, and the type can change depending on `n`) than a method (an array's `[]` is a method). ```erg assert t.0 == 1 @@ -18,97 +18,89 @@ assert t.1 == True assert t.2 == "a" ``` -不嵌套时,括号是可选的。 - +Parentheses `()` are optional when not nested. ```erg t = 1, True, "a" i, b, s = t ``` -元组可以包含不同类型的对象,但不能包含数组之类的小版本。 - +Tuples can hold objects of different types, so they cannot be iterated like arrays. ```erg t: ({1}, {2}, {3}) = (1, 2, 3) (1, 2, 3).iter().map(x -> x + 1) # TypeError: type ({1}, {2}, {3}) has no method `.iter()` -# すべて同じ型の場合配列と同じように`(T; n)`で表せるが、これでもイテレーションは出来ない +# If all types are the same, they can be represented by `(T; n)` like arrays, but this still does not allow iteration t: (Int; 3) = (1, 2, 3) assert (Int; 3) == (Int, Int, Int) ``` -但是,非等质集合(如元组)可以通过上传、Intersection 等转换为等质集合(如数组)。这叫做等质化。 - +However, nonhomogeneous collections (such as tuples) can be converted to homogeneous collections (such as arrays) by upcasting, intersecting, and so on. +This is called equalization. ```erg -(Int, Bool, Str) can be [T; 3] | T :> Int, T :> Bool, T :> Str +(Int, Bool, Str) can be [T; 3] where T :> Int, T :> Bool, T :> Str ``` - ```erg t: (Int, Bool, Str) = (1, True, "a") # non-homogenous a: [Int or Bool or Str; 3] = [1, True, "a"] # homogenous _a: [Show; 3] = [1, True, "a"] # homogenous _a.iter().map(x -> log x) # OK -t.try_into([Show; 3])?.iter().map(x -> log x) # OK +t.try_into([Show; 3])? .iter().map(x -> log x) # OK ``` -## 单位 - -具有 0 个元素的元组称为单元。单位是一个值,但也指其类型本身。 +## Unit +A tuple with zero elements is called a __unit__. A unit is a value, but also refers to its own type. ```erg unit = () (): () ``` -单元是所有元素 0 元组的超类。 - +Unit is a superclass of all element 0 tuples. ```erg () > (Int; 0) () > (Str; 0) ``` -此对象的用途包括参数、没有返回值的过程等。Erg 子例程必须具有参数和返回值。但是,在某些情况下,例如在过程中,可能会产生副作用,但没有有意义的参数返回值。在这种情况下,单位作为“没有意义的,形式上的值”来使用。 - +The use of this object is for procedures with no arguments and no return value, etc. Erg subroutines must have arguments and a return value. However, in some cases, such as a procedure, there may be no meaningful arguments or return value, only side effects. In such cases, we use units as "meaningless, formal values. ```erg -# ↓ 実はこの括弧はユニット -p!() = - # `print!`は意味のある値を返さない +# ↓ Actually, this parenthesis is a unit +p!() =. + # `print!` does not return a meaningful value print! "Hello, world!" p!: () => () ``` -但是,Python 在这种情况下更倾向于使用而不是单位。在 Erg 中,如果一开始就确定不返回有意义的值(如过程),则返回;如果操作失败,可能一无所获(如元素检索),则返回。 +However, Python tends to use `None` instead of units in such cases. +In Erg, you should use `()` when you are sure from the beginning that the operation will not return a meaningful value, such as in a procedure, and return `None` when there is a possibility that the operation will fail and you will get nothing, such as when retrieving an element. -## 参数和元组 - -实际上,Erg 的所有对象都是一个参数,一个返回值。具有 N 个参数的子程序仅接受“一个具有 N 个元素的元组”作为参数。 +## Arguments and Tuple +Actually, all of Erg's `Callable` objects are one argument and one return value; a subroutine that takes N arguments was just receiving "one tuple with N elements" as an argument. ```erg -# f x = ...は暗黙にf(x) = ...とみなされる +# f x = ... is implicitly assumed to be f(x) = ... is considered to be f x = x assert f(1) == 1 f(1, 2, 3) # ArgumentError: f takes 1 positional argument but 3 were given -# 可変個の引数を受け取る -g x: Int, ...y: Int = y +# ArgumentError: f takes 1 positional argument but 3 were given +g x: Int, . . y: Int = y assert (2, 3) == g 1, 2, 3 ``` -这将解释函数的类型。 - +This also explains the function type. ```erg assert f in T: {(T,) -> T | T} -assert g in {(Int, ...(Int; N)) -> (Int; N) | N: Nat} +assert g in {(Int, ... (Int; N)) -> (Int; N) | N: Nat} ``` -准确地说,函数的输入不是元组,而是具有默认属性的命名元组。这是一个特殊的元组,只能作为函数的参数使用,可以像记录一样命名并具有缺省值。 - +To be precise, the function's input is not a tuple but a "Named tuple with default attributes". This is a special tuple that can only be used in function arguments, can be named like a record, and can have a default value. ```erg f(x: Int, y=0) = x + y diff --git a/doc/zh_CN/syntax/12_dict.md b/doc/zh_CN/syntax/12_dict.md index 04d4d305..2bbfbfd0 100644 --- a/doc/zh_CN/syntax/12_dict.md +++ b/doc/zh_CN/syntax/12_dict.md @@ -1,40 +1,37 @@ # Dict -Dict 是一个包含键值对的集合。 - +Dict is a collection of key/value pairs. ```erg ids = {"Alice": 145, "Bob": 214, "Charlie": 301} assert ids["Alice"] == 145 ``` -如果密钥为 Hash,则该密钥可以不是字符串。 - +The key does not have to be a string if it is a `Hash` object. ```erg -# rangeオブジェクトをキーにするのは非推奨(スライスと混同される) +# deprecated to use a range object as a key (confused with slice) r = {1..3: "1~3", 4..6: "4~6", 7..9: "7~9"} assert r[1..3] == "1~3" l = {[]: "empty", [1]: "1"} assert l[[]] == "empty" ``` -顺序对迪奇并不重要。也不能有重复的元素。在这一点上,Dict 与相似。Dict 也可以说是一个有价值的 Set。 - +Order does not matter for Dict. It also cannot have duplicate elements. In this respect, Dict is similar to Set. +You could say that a Dict is a Set with values. ```erg {"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214} ``` -从 Dict 文字生成 Dict 时,将检查是否存在重复的键。如果存在重复项,则会导致编译错误。 - +When generating a dict from a dict literal, it is checked for duplicate keys. +Any duplicates will result in a compile error. ```erg {"Alice": 145, "Alice": 1} # KeyError: Duplicate key "Alice" ``` -使用生成空 Dict。请注意,表示空数组。 - +Empty Dict is created with `{:}`. Note that `{}` denotes an empty set. ```erg mut_dict = !{:} @@ -45,25 +42,24 @@ assert mut_dict["Alice"] == 145 ## Heterogeneous Dict -键值的类型可以不是单一的,这样的字典称为。 - +There need not be a single key/value type. Such a dictionary is called a __heterogenous dict_. ```erg -d: {Str: Int, Int: Str} = {”a”: 1, 1: “a”} -assert d[”a”] == 1 -assert d[1] == “a” +d: {Str: Int, Int: Str} = {"a": 1, 1: "a"} +assert d["a"] == 1 +assert d[1] == "a" ``` -但是,不能将相同类型的值应用于不同类型的键,也不能将不同类型的值应用于不同类型的键。在这些情况下,请改用 Or 类型(Union)。 - +However, it is not possible to assign values of the same type to keys of different types, or values of different types to keys of the same type. +In such cases, use the type Or instead. ```erg -invalid1 = {1: “a”, “a”: “b”} -invalid2 = {1: “a”, 2: 2} +invalid1 = {1: "a", "a": "b"} +invalid2 = {1: "a", 2: 2} -# Ergの型推論はOr型を推論しないので、型指定が必要 -valid1: {Int or Str: Str} = {1: “a”, “a”: “b”} -valid2: {Int: Int or Str} = {1: “a”, 2: 2} +# Erg type inference does not infer Or type, so type specification is required +valid1: {Int or Str: Str} = {1: "a", "a": "b"} +valid2: {Int: Int or Str} = {1: "a", 2: 2} ```

diff --git a/doc/zh_CN/syntax/13_record.md b/doc/zh_CN/syntax/13_record.md index fbbebec9..8fb4c524 100644 --- a/doc/zh_CN/syntax/13_record.md +++ b/doc/zh_CN/syntax/13_record.md @@ -1,7 +1,7 @@ -# 记录 - -记录是一个集合,它具有通过键访问的 Dict 和在编译时检查访问的元组的性质。如果你使用过 JavaScript,请将其视为对象文字符号(更高级)。 +# Record +A record is a collection that combines the properties of a Dict accessed by key and a tuple whose access is inspected at compile time. +If you know JavaScript, think of it as a (more enhanced) kind of object literal notation. ```erg john = {.name = "John"; .age = 21} @@ -12,33 +12,34 @@ assert john in {.name = Str; .age = Nat} john["name"] # Error: john is not subscribable ``` -和部分称为属性,部分称为属性值。 - -它与 JavaScript 对象文字的区别在于不能以字符串形式访问。也就是说,属性不仅仅是字符串。这可能是因为它在编译时决定对值的访问,也可能是因为字典和记录是不同的。也就是说,是 Dict,是记录。那么,词典和记录该如何区分使用呢?通常建议使用记录。记录具有以下优点:编译时检查元素是否存在,并且可以指定。可见性规范相当于 public/private 规范,例如在 Java 语言中。有关详细信息,请参见。 +The `.name` and `.age` parts are called attributes, and the `"John"` and `21` parts are called attribute values. +The difference from JavaScript object literals is that they are not accessible as strings. That is, attributes are not just strings. +This is because access to the value is determined at compile-time, and because dictionaries and records are different things. In other words, `{"name": "John"}` is a Dict and `{name = "John"}` is a record. +So how should we use dictionaries and records? +In general, we recommend using records. Records have the advantages of being checked at compile-time for the existence of elements and of being able to specify __visibility_. +Specifying visibility is equivalent to specifying public/private in Java and other languages. For details, see [visibility](./15_visibility.md) for details. ```erg a = {x = 1; .y = x + 1} a.x # AttributeError: x is private -# Hint: declare as `.x` +# Hint: declare as `.x`. assert a.y == 2 ``` -对于熟悉 JavaScript 的人来说,上面的例子可能很奇怪,但如果简单地声明,则外部无法访问,如果加上,则可以通过访问。 - -还可以显式指定属性的类型。 +The above example may seem strange to someone familiar with JavaScript, but simply declaring `x` makes it inaccessible from the outside. `. `. `. +You can also explicitly specify the type of an attribute. ```erg anonymous = { - .name: Option! Str = !None + .name: Option! Str = ! .age = 20 } anonymous.name.set! "John" ``` -记录也可以有方法。 - +A record can also have the method. ```erg o = { @@ -51,28 +52,27 @@ o.inc!() assert o.i == 1 ``` -关于记录有一个值得注意的语法。当记录的所有属性值都是类(结构类型不允许)时,记录本身将其属性视为请求属性。这种类型称为记录类型。有关详细信息,请参阅记录部分。 - +There is a notable syntax with respect to records. When all the attribute values of a record are classes (not structural types), the record itself behaves as a type with its own attributes as required attributes. +Such a type is called a record type. See the section [Record] for more details. ```erg -# レコード +# record john = {.name = "John"} -# レコード型 +# record type john: {.name = Str} Named = {.name = Str} john: Named greet! n: Named = print! "Hello, I am {n.name}" -greet! john # "Hello, I am John" +john # "Hello, I am John" print! -print! Named.name # Str +Named.name # Str ``` -## 分解记录 - -可以按如下方式分解记录。 +## Deconstructing a record +Records can be deconstructed as follows. ```erg record = {x = 1; y = 2} @@ -88,8 +88,8 @@ match point: {x = x; y = y; z = z} -> "({x}, {y}, {z})" ``` -此外,如果记录具有与属性同名的变量,则可以将或省略为,将省略为。但是,如果只有一个属性,则必须使用将其与集合区分开来。 - +`x = ...` can also be abbreviated to `x` when there is a variable with the same name as the attribute, for example, `x = x` or `x = .x` to `x`, and `.x = .x` or `.x = x` to `.x`. +However, when there is only one attribute, it must be followed by `;` to distinguish it from a set. ```erg x = 1 @@ -106,8 +106,7 @@ tuple = {x} assert tuple.1 == 1 ``` -此语法可用于分解记录并将其赋给变量。 - +This syntax can be used to deconstructed a record and assign it to a variable. ```erg # same as `{x = x; y = y} = xy` @@ -120,10 +119,9 @@ assert a == 1 assert b == 2 ``` -## 空记录 - -空记录由表示。与 Unit 一样,空记录也是其类本身。 +## Empty Record +An empty record is represented by `{=}`. An empty record is also its own class, like Unit. ```erg empty_record = {=} @@ -134,23 +132,26 @@ empty_record: Structural {=} {x = 3; y = 5}: Structural {=} ``` -空记录不同于空 Dict或空集。尤其要注意它与的含义正好相反(在 Python 中,是一个空字典,而在 Erg 中,它是)。作为枚举类型,是空类型,不包含任何元素。类型是对其进行的类化。相反,记录类中的没有请求实例属性,因此所有对象都是它的元素。是此别名。(修补程序)具有非常基本的提供方法,如。 - +An empty record is different from an empty Dict `{:}` or empty set `{}`. In particular, note that it is the opposite of `{}` in meaning (in Python, `{}` is an empty dictionary, while in Erg it is `!{:}` in Erg). +As an enumerated type, `{}` is an empty type that contains nothing in its elements. The `Never` type is a classification of this type. +Conversely, the record class `{=}` has no required instance attribute, so all objects are elements of it. An `Object` is an alias of this. +An `Object` (a patch of `Object`) is an element of `. __sizeof__` and other very basic provided methods. ```erg AnyPatch = Patch Structural {=} - .__sizeof__ self = ... + . __sizeof__ self = ... .clone self = ... ... Never = Class {} ``` -请注意,没有其他类型和类在结构上与,类型等效,如果用户定义类型时在右边指定,则会出错。这可以防止将转换为的错误。此外,如果定义组合结果为的类型(例如),则会发出警告,将其简单地定义为。 +Note that no other type or class can be structurally equivalent to the `{}`, `Never` type, and it is an error if the user defines a type with `{}`, `Class {}` on the right side. +This means that, for example, `1..10 or -10. -1`, but `1..10 and -10... -1`. `-1` when it should be `1..10 or -10...-1`, for example. +Also, if you define a type (such as `Int and Str`) that results in a composition `Object`, you will be warned to simply set it to `Object`. -## 即时块 - -Erg 还有一个语法叫即时块,它只是返回最后评估的值。不能保留属性。 +## Instant Block +Erg has another syntax, instant block, which simply returns the last value evaluated. Attributes cannot be retained. ```erg x = @@ -163,10 +164,10 @@ y = .x = 1 # SyntaxError: cannot define an attribute in an entity block ``` -## 数据类 - -如果尝试单独实现方法,则必须直接在实例中定义原始记录(由记录文本生成的记录)。这效率很低,而且随着属性数量的增加,错误显示等很难看到,也很难使用。 +## Data Class +A bare record (a record generated by a record literal) must be defined directly in the instance if you try to implement a method on its own. +This is inefficient, and as the number of attributes increases, error messages and the like become difficult to see and use. ```erg john = { @@ -176,11 +177,11 @@ john = { .inc_age! ref! self = self::age.update! x -> x + 1 } john + 1 -# TypeError: + is not implemented for {name = Str; age = Int; .greet! = Ref(Self).() => None; inc_age! = Ref!(Self).() => None}, Int +# TypeError: + is not implemented for {name = Str; age = Int; .greet! = Ref(Self). () => None; inc_age! = Ref! () => None}, Int ``` -因此,在这种情况下,我们将继承记录类。此类类称为数据类。我们将在部分详细讨论这一点。 - +So, in such a case, you can inherit a record class. Such a class is called a data class. +This is described in [class](./type/04_class.md). ```erg Person = Inherit {name = Str; age = Nat} @@ -194,5 +195,5 @@ john + 1 ```

- Previous | Next + Previous | Next

diff --git a/doc/zh_CN/syntax/14_set.md b/doc/zh_CN/syntax/14_set.md index 648b9d0a..324b4969 100644 --- a/doc/zh_CN/syntax/14_set.md +++ b/doc/zh_CN/syntax/14_set.md @@ -1,18 +1,16 @@ -# 集 +# Set -集代表一个集合,在数据结构上是重复的、没有顺序的数组。 +A set represents a collection, which is structurally a duplicate, unordered array. - -```erg +``` erg assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3} -assert {1, 2} == {1, 1, 2} # 重複は自動で削除される +assert {1, 2} == {1, 1, 2} # duplicates are automatically removed assert {1, 2} == {2, 1} ``` -集合可以进行集合运算。 +Sets can perform set operations. - -```erg +``` erg assert 1 in {1, 2, 3} assert not 1 in {} assert {1} or {2} == {1, 2} @@ -20,31 +18,29 @@ assert {1, 2} and {2, 3} == {2} assert {1, 2} not {2} == {1} ``` -布景是一个等质的收藏。要使不同类中的对象共存,必须使它们相等。 +A set is a homogeneous collection. In order for objects of different classes to coexist, they must be homogenized. - -```erg +``` erg s: {Int or Str} = {"a", 1, "b", -1} ``` -## 设置为类型 +## Sets as types -套也可以当作一种类型。这些类型称为。 +Sets can also be treated as types. Such types are called __Enum types__. - -```erg +``` erg i: {1, 2, 3} = 1 assert i in {1, 2, 3} ``` -集的元素将变为类型元素。需要注意的是,布景本身是不一样的。 +Elements of the set are directly elements of the type. +Note that the sets themselves are different. - -```erg +``` erg mut_set = {1, 2, 3}.into {Int; !3} mut_set.insert!(4) ```

Previous | Next -

+

\ No newline at end of file diff --git a/doc/zh_CN/syntax/15_type.md b/doc/zh_CN/syntax/15_type.md index f793b020..8430dc74 100644 --- a/doc/zh_CN/syntax/15_type.md +++ b/doc/zh_CN/syntax/15_type.md @@ -1,7 +1,7 @@ -# 类型 +# types -类型在 Erg 中是一个非常重要的功能,因此我们提供了。请看那边。 +Types are a very important feature in Erg, so we have a [dedicated section](./type/01_type_system.md). Please see there.

- Previous | Next -

+ Previous | Next +

\ No newline at end of file diff --git a/doc/zh_CN/syntax/16_iterator.md b/doc/zh_CN/syntax/16_iterator.md index 4bda6cf0..302d197b 100644 --- a/doc/zh_CN/syntax/16_iterator.md +++ b/doc/zh_CN/syntax/16_iterator.md @@ -1,36 +1,33 @@ -# 迭 - -迭代器是用于检索容器元素的对象。 +# Iterator +An iterator is an object used to retrieve elements of a container. ```erg for! 0..9, i => print! i ``` -此代码输出 0 到 9 之间的数字。将每个数字(=Int 对象)赋给,并执行以下操作(=):这种重复执行称为。 - -现在,我们来看一下过程的类型签名。 +This code prints the numbers 0 through 9. +Each number (=Int object) is assigned to `i` and the following operation (=`print! i``) is executed. This kind of repetitive execution is called __iteration__. +Now let's look at the type signature of the `for!` procedure. ```erg for!: |T: Type, I <: Iterable T| (I, T => None) => None ``` -第一个参数似乎接受类型为的对象。 - -是具有属性和方法的请求方法类型。 +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 Iterable T = Trait { .Iterator = {Iterator} - .iter = Self(T).() -> Self.Iterator T + .iter = Self(T). () -> Self.Iterator T } ``` -属性类型是所谓的设置卡印(卡印在中描述)。 - +The type `{Iterator}` of the `.Iterator` attribute is so-called set-kind (kind is described [here](./type/advanced/kind.md)). ```erg assert [1, 2, 3] in Iterable(Int) @@ -38,12 +35,13 @@ assert 1..3 in Iterable(Int) assert [1, 2, 3].Iterator == ArrayIterator assert (1..3).Iterator == RangeIterator -log [1, 2, 3].iter() # +log [1, 2, 3].iter() # ``` -和都是实现的类,它们的存在只是为了赋予小版本功能。这种设计模式称为伴随类。而修补程序是小版本功能的核心。只需要一个方法,实际上提供了几十个方法。只需实现方法即可使用的实现方法。由于这种便利性,标准库实现了许多迭代器。 - +Both `ArrayIterator` and `RangeIterator` are classes that implement `Iterator` and exist only to give `Array` and `Range` iteration functions. +Such a design pattern is called companion class [1](#1). +And the `IteratorImpl` patch is the core of the iteration functionality. `Iterator` requires only one `.next` method, `IteratorImpl` provides dozens of methods indeed. `ArrayIterator` and `RangeIterator` can use the implementation method of `IteratorImpl` just by implementing the `.next` method. For this convenience, the standard library implements a number of iterators. ```mermaid classDiagram @@ -80,11 +78,11 @@ classDiagram Range <-- RangeIterator ``` -提供一个接口的类型,如,在本例中为)是静态调度,但可以统一处理,这种类型称为伴随类适配器。 +Types such as `Iterable` that provide an interface for handling traits (in this case `Iterator`) in a static dispatch yet unified manner are called companion class adapters. --- -1这个模式似乎没有统一的名字,但在 Rust 中被称为,并以此为参照命名。 +1 There doesn't seem to be a uniform name for this pattern, but in Rust, there is [companion struct pattern]( 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), and was named after it. [↩](#f1)

Previous | Next diff --git a/doc/zh_CN/syntax/17_mutability.md b/doc/zh_CN/syntax/17_mutability.md index 4ac7a2cc..e88b87b1 100644 --- a/doc/zh_CN/syntax/17_mutability.md +++ b/doc/zh_CN/syntax/17_mutability.md @@ -1,7 +1,7 @@ # Mutability -正如我们已经看到的,Erg 中的所有变量都是不变的。但是 Erg 的对象有一个可变性的概念。以下代码为示例。 - +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 a = [1, 2, 3] @@ -9,8 +9,9 @@ a = a + [4, 5, 6] print! a # [1, 2, 3, 4, 5, 6] ``` -上面的代码实际上是 Erg 无法实现的。因为不能再赋值。这个代码可以运行。 +The above code cannot actually be executed by Erg. This is because it is not reassignable. +This code can be executed. ```erg b = ![1, 2, 3] @@ -18,8 +19,8 @@ b.concat! [4, 5, 6] 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 a = [1, 2, 3] @@ -28,46 +29,45 @@ _a = a + [4, 5, 6] print! id! _a # 0x000002A798DFE980 ``` -过程返回对象所在内存中的地址。 - -是的“动态”数组。对象的内容会发生变化,但变量指向相同的内容。 +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 -b = [1,2,3].into [Int; !3] +b = ![1, 2, 3] print! id! b # 0x000002A798DFE220 b.concat! [4, 5, 6] print! id! b # 0x000002A798DFE220 ``` - ```erg i = !0 -if! True: +if! True. do! do! i.inc!() # or i.add!(1) do pass 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 Point = Class {.x = Int; .y = Int} -# この場合.xは可変化し、yは不変のまま +# In this case .x is made mutable and .y remains immutable Point! = Class {.x = Int!; .y = Int} -Point!.inc_x! ref! self = self.x.update! x -> x+1 +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 ``` -## 常数 - -与变量不同,常量在所有作用域中指向相同的内容。常量由运算符声明。 +## Constant +Unlike variables, constants point to the same thing in all scopes. +Constants are declared with the `=` operator. ```erg PI = 3.141592653589 @@ -75,17 +75,28 @@ match! x: PI => print! "this is pi" ``` -常量在全局以下的所有范围内都是相同的,不能被覆盖。因此,不能通过进行重新定义。此限制允许你在模式匹配中使用它。在模式匹配中使用是因为它们是常数。此外,常量始终指向不变对象。类型(如)不能是常量。所有内置类型都是常量,因为它们应该在编译时确定。也可以生成非常量类型,但不能用于指定类型,只能作为记录使用。反过来说,类型也可以说是编译时内容已确定的记录。 +Constants are identical in all scopes below the global and cannot be overwritten. Therefore, they cannot be redefined by ``=``. This restriction allows it to be used in pattern matching. +The reason why `True` and `False` can be used in pattern matching is because they are constants. +Also, constants always point to immutable objects. Types such as `Str!` cannot be constants. +All built-in types are constants because they should be determined at compile time. Types that are not constants can be generated, but they cannot be used to specify a type and can only be used like a simple record. Conversely, a type is a record whose contents are determined at compile time. ## Variable, Name, Identifier, Symbol -现在,我们来整理一下 Erg 中有关变量的术语。 +Let's clear up a few terms related to variables in Erg. -“变量”(Variable)是一种为对象命名(Name)并允许其重复使用的机制(或指该名称)。标识符(Identifier)是用于指定变量的语法元素。符号是表示名称的语法元素和标记。 +A Variable is a mechanism to give an object a Name so that it can be reused (or point to that Name). +Identifier is a grammar element that specifies a variable. +A symbol is a grammatical element, a token, that represents a name. -只有不是符号的字符才是符号,符号是运算符,但不是符号。例如,是标识符和符号。也是一个标识符,但它不是一个符号。是符号。即使没有与任何对象关联,仍然是 Symbol 和 Identifier,但不是 Variable。形式为的标识符称为字段存取器。此外,形式的标识符称为下标存取器。 +Only non-symbolic characters are symbols, and symbols are not called symbols, although they can be identifiers as operators. +For example, `x` is an identifier and a symbol. `x.y` is also an identifier, but it is not a symbol. `x` and `y` are symbols. +And even if `x` were not tied to any object, `x` would still be a Symbol and an Identifier, but it would not be called a Variable. +Identifiers of the form `x.y` are called Field Accessors. +Identifiers of the form `x[y]` are called Subscript Accessors. -变量和标识符之间的区别,如果说 Erg 语法理论意义上的变量,那么这两个变量实际上是相同的。变量和标识符不等效的语言包括 C 语言。在 C 语言中,类型或函数不能赋给变量。int,main 是标识符,但不是变量(严格来说,它可能是可赋值的,但有限制)。但在 Erg 中,“一切都是物体”。函数和类型,甚至运算符都可以赋给变量。 +The difference between a variable and an identifier is that if we are talking about a variable in the sense of Erg's grammatical theory, the two are in effect the same. +In C, types and functions cannot be assigned to variables; int and main are identifiers, but not variables (strictly speaking, they can be assigned, but there are restrictions). +However, in Erg, "everything is an object". Not only functions and types, but even operators can be assigned to variables.

Previous | Next diff --git a/doc/zh_CN/syntax/18_ownership.md b/doc/zh_CN/syntax/18_ownership.md index 14607388..1f1e0232 100644 --- a/doc/zh_CN/syntax/18_ownership.md +++ b/doc/zh_CN/syntax/18_ownership.md @@ -1,37 +1,42 @@ -# 所有权制度 +# Ownership system -由于 Erg 是以 Python 为主机语言的语言,因此管理内存的方式依赖于 Python 的处理系统。然而,从语义上讲,Erg 的内存管理与 Python 的内存管理不同。显著的区别体现在所有权制度和禁止循环引用。 +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 有一个所有权系统受到Rust的影响。Rust 的所有权系统通常被称为晦涩难懂,但 Erg 的所有权系统被简化为直观。Erg 拥有的所有权,一旦失去所有权,就无法查看该对象。 +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 +``` erg v = [1, 2, 3].into [Int; !3] push! vec, x = vec.push!(x) vec -# vの中身([1, 2, 3])の所有権は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] ``` -例如,在将对象传递到子例程时会发生所有权移动。如果你希望在传递后仍拥有所有权,则必须复制(cloning)、冻结(freeze)或借用(borrowing)。但是,如下文所述,可以借用的场合有限。 +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. -## 复制 +## replication -复制对象并转移其所有权。通过将方法应用于实际参数来完成此操作。复制的对象与原始对象完全相同,但它们彼此独立,不受更改的影响。 +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. -复制相当于 Python 的深度副本,因为要重新创建整个相同的对象,所以与冻结和借用相比,通常计算和内存成本更高。需要复制对象的子例程称为使用参数子例程。 +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!() +``` erg +capitalize s: Str!= + s. capitalize!() s s1 = !"hello" @@ -39,13 +44,15 @@ s2 = capitalize s1.clone() log s2, s1 # !"HELLO hello" ``` -## 冻结 +## freeze -利用可变对象可以从多个位置引用,将可变对象转换为不变对象。这叫冻结。冻结可用于创建可变阵列的迭代器。变量数组无法直接创建迭代器,因此将其转换为不变数组。如果不想破坏数组,请使用 [方法] (./type/mut.md)等。 +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 -# イテレータが出す値の合計を計算する +``` erg +# Compute the sum of the values ​​produced by the iterator sum|T <: Add + HasUnit| i: Iterator T = ... x = [1, 2, 3].into [Int; !3] @@ -54,15 +61,15 @@ i = x.iter() # TypeError: [Int; !4] has no method `iter` y = x.freeze() i = y.iter() assert sum(i) == 10 -y # この後もyは触れられる +y # y can still be touched ``` -## 借用 +## borrow -借用比复制和冻结成本更低。在以下简单情况下,可以借用。 +Borrowing is cheaper than duplicating or freezing. +Borrowing can be done in the following simple cases: - -```erg +``` erg peek_str ref(s: Str!) = log s @@ -70,34 +77,34 @@ s = !"hello" peek_str s ``` -对于原始对象,借用的值称为。你可以将引用“转借”给另一个子例程,但不能消费,因为它只是借用。 +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 +``` erg steal_str ref(s: Str!) = - # log関数は引数を借用するだけなので、又貸しできる + # Since the log function only borrows the arguments, it can be sub-leased log s - # discard関数は引数を消費するので、エラー + # error because the discard function consumes arguments discard s # OwnershipError: cannot consume a borrowed value # hint: use `clone` method ``` - -```erg +``` erg steal_str ref(s: Str!) = - # これもダメ(=は右辺を消費する) + # This is no good either (= consumes the right side) x = s # OwnershipError: cannot consume a borrowed value x ``` -Erg 引用比 Rust 具有更强的约束。引用是第一级语言对象,但不能显式生成,只能通过/指定实际参数的传递方式。这意味着你不能将引用合并到数组中,也不能创建以引用为属性的类。 +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 a natural specification in languages ​​without references in the first place, and they are not so inconvenient. -## 循环引用 +## circular references -Erg 的设计目的是防止意外发生内存泄漏,当内存检查器检测到循环引用时,它会发出错误消息。在大多数情况下,可以使用弱引用来解决此错误。但是,由于这无法生成具有循环结构的对象(如循环图),因此我们计划实现一个 API,该 API 可以生成循环引用作为 unsafe 操作。 +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/zh_CN/syntax/19_visibility.md b/doc/zh_CN/syntax/19_visibility.md index 6ebbb9bd..e5ef1e80 100644 --- a/doc/zh_CN/syntax/19_visibility.md +++ b/doc/zh_CN/syntax/19_visibility.md @@ -1,58 +1,56 @@ -# 可见性(Visibility) +# Visibility -Erg 中的变量具有的概念。我们看到的所有变量都称为。这是一个外界不可见的变量。例如,在模块中定义的私有变量不能被另一个模块引用。 +Erg variables have the concept of __visibility__. +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 +``` erg # foo.er x = "this is an invisible variable" ``` - -```erg -# bar.er +``` erg +#bar.er foo = import "foo" foo.x # AttributeError: Module 'foo' has no attribute 'x' ('x' is private) ``` -与此相对,也有,这是可从外部参照的。公共变量定义为。 +On the other hand, there are also __public variables__, which can be referenced from the outside. +Public variables are defined with `.`. - -```erg +``` erg # foo.er .x = "this is a visible variable" ``` - -```erg -# bar.er +``` erg +#bar.er foo = import "foo" assert foo.x == "this is a visible variable" ``` -你不需要为私有变量指定任何内容,但也可以指定或(例如,)以表明它是私有的。模块也可以是。 +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 -::x = "this is a invisible variable" +``` erg +::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 purely sequential execution, private variables are almost synonymous with local variables. It can be referenced from the inner scope. - -```erg +``` erg ::x = "this is a private variable" y = - x + 1 # 正確にはmodule::x + x + 1 # exactly module::x ``` -你可以使用来区分作用域中的同名变量。在左侧指定要引用的变量的范围。对于顶级,指定。如果未指定,则引用最内部的变量,就像在正常情况下一样。 +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 +``` erg ::x = 0 assert x == 0 y = @@ -66,42 +64,38 @@ y = assert module::x == 0 ``` -对于未命名子程序的范围,指定其范围。 +In the anonymous subroutine scope, `self` specifies its own scope. - -```erg +``` erg 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 +``` erg x = 0 C = Class {x = Int} C. - # トップレベルのxが参照される(module::xにするようwarningが出る) + # Top-level x is referenced (warning to use module::x) f1 self = x - # インスタンス属性のxが参照される + # 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. - -```erg +``` erg # foo.er .Foo = Class() ``` - -```erg -# bar.er +``` erg +#bar.er {Foo; ...} = import "foo" Foo:: @@ -115,10 +109,11 @@ Foo. foo::private() # AttributeError ``` -但是,这两种方法只能在模块中使用。只有在定义模块中,类的方法才能引用外部定义的私有方法。公开方法在类之外公开,但不在模块之外公开。 +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 +``` erg # baz.er {Foo; ...} = import "foo" @@ -126,35 +121,33 @@ foo = Foo.new() foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defined in module 'bar') ``` -此外,不能为要 Re-export 的类型定义方法。这是为了防止导入模块导致方法丢失或找到的混淆。 +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 +``` erg +#bar.er {.Foo; ...} = import "foo" .Foo:: private self = pass # Error -.Foo. +Foo. public self = self::private() # Error ``` -如果要这样做,请定义。 +If you want to do something like this, define a [patch](./type/07_patch.md). - -```erg -# bar.er +``` erg +#bar.er {Foo; ...} = import "foo" FooImpl = Patch Foo FooImpl :=: private self = pass -FooImpl. +Foo Impl. public self = self::private() ``` - -```erg +``` erg # baz.er {Foo; ...} = import "foo" {FooImpl; ...} = import "bar" @@ -163,12 +156,12 @@ foo = Foo.new() foo.public() ``` -## 受限制的公共变量 +## restricted public variables -变量的可见性并不只有完全的公开或非公开。也可以有限制地发布。 +Variable visibility is not limited to complete public/private. +You can also publish with restrictions. - -```erg +``` erg # foo.er .record = { .a = { @@ -186,8 +179,7 @@ _ = .record.a.y # OK _ = .record.a.z # OK ``` - -```erg +``` erg foo = import "foo" _ = foo.record.a.x # VisibilityError _ = foo.record.a.y # VisibilityError @@ -196,4 +188,4 @@ _ = foo.record.a.z # OK

Previous | Next -

+

\ 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 index 59640a40..dee0d1cf 100644 --- a/doc/zh_CN/syntax/20_naming_rule.md +++ b/doc/zh_CN/syntax/20_naming_rule.md @@ -1,52 +1,50 @@ -# 命名规则 +# Naming convention -如果要将变量用作常量表达式,则必须以大写字母开头。两个以上的字符可以是小写的。 +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 +``` erg i: Option Type = Int match i: t: Type -> log "type" None -> log "None" ``` -具有副作用的对象始终以结尾。过程和过程方法,以及变量类型。但是,类型本身不是可变类型。 +Objects with side effects always end with `!`. Procedures and procedural methods, and mutable types. +However, the `Proc` type itself is not mutable. - -```erg +``` erg # Callable == Func or Proc c: Callable = print! match c: - p! -> log "proc" #`:Proc` 可以省略,因为它是不言自明的 + p! -> log "proc" # `: Proc` can be omitted since it is self-explanatory f -> log "func" ``` -如果你想要将属性公开到外部,请首先使用进行定义。如果未在开始时添加,则不公开。不能在同一范围内共存,以避免混淆。 +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 +``` erg o = {x = 1; .x = 2} # SyntaxError: private and public variables with the same name cannot coexist ``` -## 文字标识符(Literal Identifiers) +## Literal Identifiers -可以通过将字符串括在单引号(‘’)中来避免上述规则。也就是说,过程对象也可以赋值,而不使用。但是,即使值是常量表达式,也不会将其视为常量。这种用单引号括起来的字符串标识符称为文字标识符。它用于调用其他语言的 API(FFI),如 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 +``` erg bar! = pyimport("foo").'bar' ``` -如果标识符对 Erg 也有效,则不需要用‘’括起来。 +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 +``` erg '∂/∂t' y 'test 1: pass x to y'() ```

Previous | Next -

+

\ No newline at end of file diff --git a/doc/zh_CN/syntax/21_lambda.md b/doc/zh_CN/syntax/21_lambda.md index 81b02c5a..08415e13 100644 --- a/doc/zh_CN/syntax/21_lambda.md +++ b/doc/zh_CN/syntax/21_lambda.md @@ -1,102 +1,95 @@ -# 匿名函数(anonymous function) +# anonymous function -匿名函数是一种语法,用于在不命名的情况下生成函数对象。 +Anonymous functions are a syntax for creating function objects on the fly without naming them. - -```erg -# `->`は無名関数演算子 +``` erg +# `->` 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 the `()` if there is only one argument. - -```erg +``` erg 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 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 +``` erg for 0..9, i: Int -> ... ``` -在未命名函数中,由于空格而存在语法差异。 +In anonymous functions, there is a difference in parsing due to whitespace. - -```erg -# この場合は`T(() -> Int)`と解釈される -i: T () -> Int -# この場合は(U()) -> Intと解釈される +``` erg +# 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. - -```erg -# `=>`は無名プロシージャ演算子 +``` erg +# `=>` is an anonymous procedure operator p! = () => print! "`p!` was called" -# `() ->`, `() =>`には`do`, `do!`という糖衣構文がある +# `() ->`, `() =>` have syntax sugar `do`, `do!` # p! = do! print! "`p!` was called" p!() # `p!` was called ``` -无参数函数可用于延迟初始化。 +No-argument functions can be used for lazy initialization. - -```erg +``` erg time = import "time" date = import "datetime" now = if! True: do!: - time.sleep! 1000 + time. sleep! 1000 date.now!() do date.new("1970", "1", "1", "00", "00") ``` -还可以进行打字和模式匹配。因此,函数几乎是通过无名函数的力量来实现的。函数参数中的无名函数将从上到下依次尝试。所以,上面的需要描述特殊情况,越往下越需要描述一般情况。如果顺序错误(尽可能),编译器将发出警告。 +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 +``` erg n = (Complex or Ratio or Int).sample!() -i = match n: - PI -> PI # 定数PIに等しい場合 - (i: 1..10) -> i # 1~10のIntの場合 - (i: Int) -> i # Intの場合 - (c: Complex) -> c.real() # Complexの場合。Int < Complexだが、フォールバックできる - _ -> panic "cannot convert to Int" # 以上のいずれにも該当しない場合。matchは全パターンを網羅していなくてはならない +i = matchn: + PI -> PI # if equal to constant PI + 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 is also generally done using `?` or `match`. - -```erg +``` erg 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 polycorrelation coefficient - -```erg +``` erg # same as id|T| x: T = x id = |T| x: T -> x ```

Previous | Next -

+

\ No newline at end of file diff --git a/doc/zh_CN/syntax/22_subroutine.md b/doc/zh_CN/syntax/22_subroutine.md index fd6d79ae..0128c059 100644 --- a/doc/zh_CN/syntax/22_subroutine.md +++ b/doc/zh_CN/syntax/22_subroutine.md @@ -1,8 +1,7 @@ -# Subroutine signatures +# Subroutine Signatures ## Func - ```erg some_func(x: T, y: U) -> V some_func: (T, U) -> V @@ -10,7 +9,6 @@ some_func: (T, U) -> V ## Proc - ```erg some_proc!(x: T, y: U) => V some_proc!: (T, U) => V @@ -18,41 +16,40 @@ some_proc!: (T, U) => V ## Func Method -不能从外部指定方法类型。 - +The method type cannot be specified externally with ``Self``. ```erg .some_method(self, x: T, y: U) => () -# Self.(T, U) => ()はselfの所有権を奪う -.some_method: Ref(Self).(T, U) => () +# Self.(T, U) => () takes ownership of self +.some_method: Ref(Self). (T, U) => () ``` ## Proc Method (dependent) -下面,假定类型采用类型参数。如果从外部指定,请使用类型变量。 - +In the following, assume that the type `T!` takes the type argument `N: Nat`. To specify it externally, use a type variable. ```erg T!: Nat -> Type -# ~>は適用前後の型引数の状態を示す(このときselfは可変参照でなくてはならない) +# ~> 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) => () ``` -请注意,的类型为。类型参数转换()不适用于没有的方法,即应用后将被剥夺所有权。 - -所有权被剥夺的情况如下。 +As a note, the type of `.some_method` is `Ref!(T(N ~> N+X)). ({X}) => () | N, X: Nat`. +For methods that do not have `ref!`, i.e., are deprived of ownership after application, the type argument transition (`~>`) cannot be used. +If ownership is taken, it is as follows. ```erg -# Nを使わないなら_で省略可 +# 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) ``` ## Operator -用括起来,可以像定义常规函数一样定义函数。可以将等中置字母运算符括起来,将其定义为中置运算符。 +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 and(x, y, z) = x and y and z diff --git a/doc/zh_CN/syntax/23_closure.md b/doc/zh_CN/syntax/23_closure.md index 0a89b21c..52c6c917 100644 --- a/doc/zh_CN/syntax/23_closure.md +++ b/doc/zh_CN/syntax/23_closure.md @@ -1,34 +1,32 @@ -# 封闭 +# Closure -Erg 子例程具有一个名为“闭包”的功能,用于捕获外部变量。 +Erg subroutines have a feature called a "closure" that captures external variables. - -```erg +``` erg outer = 1 f x = outer + x assert f(1) == 2 ``` -可以捕捉可变对象,也可以捕捉不变对象。 +As with immutable objects, mutable objects can also be captured. - -```erg +``` erg sum = !0 for! 1..10, i => - sum.add! i + sum.add!i assert sum == 45 -p! x = - sum.add! x +p!x= + sum.add!x p!(1) assert sum == 46 ``` -但需要注意的是,函数无法捕获可变对象。如果可以在函数中引用可变对象,则可以编写如下所示的代码。 +Note, however, that functions cannot capture mutable objects. +If a mutable object can be referenced in a function, you can write code like the following. - -```erg -# !!! 这个代码实际上给出了一个错误!!! +``` erg +# !!! This code actually gives an error !!! i = !0 f x = i + x assert f 1 == 1 @@ -36,33 +34,31 @@ i.add! 1 assert f 1 == 2 ``` -函数应该为相同的参数返回相同的值,但假设已被破坏。请注意,是在调用时首次计算的。 +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. -如果需要函数定义时可变对象的内容,则调用。 +Call `.clone` if you want the contents of the mutable object at the time the function was defined. - -```erg +``` erg 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 ``` -## 避免可变状态,函数编程 +## avoid mutable state, functional programming - -```erg +``` erg # Erg sum = !0 for! 1..10, i => - sum.add! i + sum.add!i assert sum == 45 ``` -在 Python 中,可以按如下方式编写上面的等效程序。 - +The equivalent program above can be written in Python as follows: ```python # Python @@ -72,28 +68,29 @@ for i in range(1, 10): assert sum == 45 ``` -但 Erg 建议使用更简单的写法。使用局部化使用函数的状态的样式,而不是使用子例程和可变对象来维护状态。这称为函数型编程。 +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 +``` erg # Functional style sum = (1..10).sum() assert sum == 45 ``` -上面的代码与刚才的结果完全相同,但我们可以看到它要简单得多。 +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 do more than sum. +`fold` is an iterator method that executes the argument `f` for each iteration. +The initial value of the counter that accumulates results is specified in `init` and accumulated in `acc`. - -```erg +``` erg # start with 0, result will sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i) assert sum == 45 ``` -Erg 的设计是为了使用不变的对象进行编程,从而提供自然简洁的描述。 +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/zh_CN/syntax/24_module.md b/doc/zh_CN/syntax/24_module.md index 2582cd36..2a7c92d9 100644 --- a/doc/zh_CN/syntax/24_module.md +++ b/doc/zh_CN/syntax/24_module.md @@ -1,47 +1,42 @@ -# 模块 - -Erg 可以将文件本身视为一条记录。我们称之为模块。 +# module +Erg allows you to think of the file itself as a single record. This is called a module. ```erg: foo.er # foo.er .i = 1 ``` - -```erg -# 定义 foo 模块和定义这条记录几乎一样 +``` erg +# Defining the foo module is almost the same as defining this record foo = {.i = 1} ``` - ```erg: bar.er -# bar.er +#bar.er foo = import "foo" print! foo # assert foo.i == 1 ``` -模块化也是一种记录类型,因此可以进行分解赋值。 +Since module types are also record types, deconstruction assignment is possible. - -```erg +``` erg {sin; cos; ...} = import "math" ``` -## 模块可见性 - +## module visibility ```console └─┬ ./src - ├─ lib.er - ├─ foo.er - ├─ bar.er - └─┬ bar - ├─ baz.er - └─ qux.er + ├─ lib.er + ├─ foo.er + ├─bar.er + └─┬ bar + ├─ baz.er + └─ qux.er ```

- Previous | Next -

+ Previous | Next +

\ 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 index d3b37693..c02573ea 100644 --- a/doc/zh_CN/syntax/25_object_system.md +++ b/doc/zh_CN/syntax/25_object_system.md @@ -1,21 +1,21 @@ -# 对象 +# Object -可以分配给变量的所有数据。类具有以下属性。 +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__`: 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 generated by a record literal (`{attr = value; ...}`). +This object has basic methods such as `.clone` and `.__sizeof__`. - -```erg +``` erg obj = {.x = 1} assert obj.x == 1 @@ -23,55 +23,60 @@ obj2 = {...x; .y = 2} assert obj2.x == 1 and obj2.y == 2 ``` -## 属性 +## Attribute -与对象相关联的对象。特别是将其自身()作为隐式第一参数的子程序属性称为方法(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 -# private_attrには`.`がないことに注意 +``` erg +# 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 -属于特定类型的对象(其中.g.是类型的元素)。所有对象都至少是类型的元素。有时称为实例(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 -表示作为函数或过程实例的对象(包括方法)。表示子例程的类是。通常,实现的对象称为(可调用对象)。 +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(可调用对象) +## Callable -实现的对象。也是的超类。 +An object that implements `.__call__`. It is also the superclass of `Subroutine`. -## 类型 +## Type -定义请求属性并使对象公用的对象。“多相类型”(Polymorphic Type)和“单相类型”(Monomorphic Type)。典型的单相类型有,等,多相类型有等。此外,定义用于更改对象状态的方法的类型称为“可变类型”(Mutable type),并且必须将变量属性标记为(.g.动态数组:)。 +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 -一个子例程,它对外部变量(静态变量除外)具有 read 权限,但对外部变量没有读/写权限。即不会对外界产生副作用。Erg 函数(Function)的定义与 Python 的定义不同,因为它不允许产生副作用。 +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 -它对外部变量具有读取和权限,对静态变量具有读/写权限,并且允许使用所有子例程。会对外界产生副作用。 +It has read and `self` permissions for external variables, read/write permissions for static variables, and is allowed to use all subroutines. It can have external side effects. -## 方法 +## Method -将隐式作为第一个参数的子程序。它不同于简单的函数/过程。 +A subroutine that implicitly takes `self` as the first argument. It is a different type than a simple function/procedure. -## 实体 +## Entity -非子程序和类型的对象。单相实体(如和)也称为值对象,多相实体()也称为容器对象。 +Objects that are not subroutines and types. +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/zh_CN/syntax/26_pattern_matching.md b/doc/zh_CN/syntax/26_pattern_matching.md index 96b40b64..8539689e 100644 --- a/doc/zh_CN/syntax/26_pattern_matching.md +++ b/doc/zh_CN/syntax/26_pattern_matching.md @@ -1,19 +1,18 @@ -# 模式匹配,可辩驳性 +# pattern matching, refutable -## Erg 中可用的模式 +## Patterns available in Erg -### 变量模式 +### variable pattern - -```erg -# basic assignment +``` erg +# 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 @@ -27,12 +26,11 @@ a: [Int; 4] = [0, 1, 2, 3] a: Array Int, 4 = [0, 1, 2, 3] ``` -### 文字模式 +### Literal patterns - -```erg -# もし`i`がコンパイル時に1と判断できない場合は、TypeErrorが発生する。 -# `_: {1} = i`を省略したもの +``` erg +# Raise a TypeError if `i` cannot be determined to be 1 at compile time. +# omit `_: {1} = i` 1 = i # simple pattern matching @@ -42,16 +40,15 @@ match x: _ -> "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 - -```erg -cond = False +``` erg +cond=False match! cond: True => print! "cond is True" _ => print! "cond is False" @@ -65,11 +62,10 @@ name = match num: _ -> "unnamed" ``` -### 筛子模式 +### Sieve pattern - -```erg -# この2つは同じ +``` erg +# these two are the same Array(T, N: {N | N >= 3}) Array(T, N | N >= 3) @@ -77,55 +73,50 @@ f M, N | M >= 0, N >= 1 = ... f(1, 0) # TypeError: N (2nd parameter) must be 1 or more ``` -### 销毁(通配符)模式 +### discard (wildcard) pattern - -```erg +``` erg _ = 1 _: Int = 1 -zero _ = 0 +zero_ = 0 right(_, r) = r ``` -### 可变长度模式 +### Variable length patterns -与下面介绍的元组/数组/记录模式结合使用。 +It is used in combination with the tuple/array/record pattern described later. - -```erg -[i, ...j] = [1, 2, 3, 4] +``` erg +[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 - -```erg +``` erg (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) -# ネストしていないなら()を省略可能(1, 2は(1, 2)として扱われる) +# If not nested, () can be omitted (1, 2 are treated as (1, 2)) m, n = 1, 2 f(x, y) = ... ``` -### 数组模式 +### array pattern - -```erg +``` erg [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 - -```erg +``` erg record = {i = 1; j = 2; k = 3} {j; ...} = record # i, k will be freed @@ -140,10 +131,9 @@ age = match person: f {x: Int; y: Int} = ... ``` -### 数据类模式 +### Data class pattern - -```erg +``` erg Point = Inherit {x = Int; y = Int} p = Point::{x = 1; y = 2} Point::{x; y} = p @@ -162,23 +152,21 @@ List T. _ -> ... ``` -### 枚举模式 +### enumeration pattern -※实际上是单纯的列举型 +*Actually, it's just an enumeration type - -```erg +``` erg match x: i: {1, 2} -> "one or two: {i}" _ -> "other" ``` -### 范围模式 +### range pattern -※实际上是单纯的区间型 +*Actually, it is just an interval type. - -```erg +``` erg # 0 < i < 1 i: 0<..<1 = 0.5 # 1 < j <= 2 @@ -188,16 +176,18 @@ match i i: 1..5 -> ... ``` -### 不是模式的东西,不能被模式化的东西 +### 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. -条件指定不唯一。例如,如果确定数字是否为偶数,则是正统的,但也可以写为。不唯一的格式不能明确表示是否正常工作,也不能明确表示是否等同于其他条件。 +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 -没有布景图案。这是因为集合无法唯一地提取元素。可以用迭代器取出,但不保证顺序。 +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/zh_CN/syntax/27_comprehension.md b/doc/zh_CN/syntax/27_comprehension.md index 7195c95b..bd4ea15b 100644 --- a/doc/zh_CN/syntax/27_comprehension.md +++ b/doc/zh_CN/syntax/27_comprehension.md @@ -1,65 +1,65 @@ # Comprehension -你可以用创建数组,用创建集,用创建 Dict。 +Array with `[expr | (name <- iterable)+ (predicate)*]`, +set with `{expr | (name <- iterable)+ (predicate)*}`, +You can create a Dict with `{key: value | (name <- iterable)+ (predicate)*}`. -用分隔的节中,最初的部分称为布局节(配置节),第 2 部分称为绑定节(绑定节),第 3 部分称为保护节(条件节)。保护子句是可选的,但不能省略绑定子句,并且保护子句不能位于绑定子句之前。 +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. -内包表示法示例 +Comprehension example - -```erg -# 布局子句是 i -# 绑定子句是 i <- [0, 1, 2] +``` erg +# the layout clause is i +# bind clause is 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] +# layout clause is i / 2 +# bind clause is 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 +# 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 的内涵表述受到 Haskell 的影响,但略有差异。对于 Haskell 的列表内涵表示法,变量的顺序会导致结果的差异,而对于 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 +``` erg # 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)] ``` -## 筛子型 +## Sieve type -与内涵表记相似的还有筛子型。筛子类型是以的形式创建的类型(枚举类型)。对于筛子类型,名称只能是一个,不能指定布局(但可以处理多个值,例如元组类型),而 Predicate 只能是编译时计算的常量表达式。 +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 +``` erg Nat = {I: Int | I >= 0} -# 如果谓词表达式只有and,可以替换为: +# 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/zh_CN/syntax/28_spread_syntax.md b/doc/zh_CN/syntax/28_spread_syntax.md index b71ad142..aed87510 100644 --- a/doc/zh_CN/syntax/28_spread_syntax.md +++ b/doc/zh_CN/syntax/28_spread_syntax.md @@ -1,10 +1,9 @@ -# 展开分配 +# 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] +``` erg +[x,...y] = [1, 2, 3] assert x == 1 assert y == [2, 3] x, ...y = (1, 2, 3) @@ -12,34 +11,32 @@ assert x == 1 assert y == (2, 3) ``` -## 提取分配 +## Extract assignment -如果后没有写任何内容,则忽略其余元素并进行赋值。这种类型的展开赋值特别称为抽取赋值。提取赋值是一种有用的语法,用于将模块或记录中的特定属性本地化。 +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 +``` erg {sin; cos; tan; ..} = import "math" ``` -然后,可以在本地使用。 +After that, you can use `sin, cos, tan` locally. -记录也可以这样做。 +You can do the same with records. - -```erg +``` erg record = {x = 1; y = 2} {x; y; ...} = record ``` -如果要全部展开,请使用。这就是 OCaml 等所说的。 +If you want to expand all, use `{*} = record`. It is `open` in OCaml. - -```erg +``` erg 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/zh_CN/syntax/29_decorator.md b/doc/zh_CN/syntax/29_decorator.md index ed7207e8..a5ed389c 100644 --- a/doc/zh_CN/syntax/29_decorator.md +++ b/doc/zh_CN/syntax/29_decorator.md @@ -1,58 +1,56 @@ -# 装饰器(修饰符) +# decorator (modifier) -装饰器用于将特定的状态和行为添加到类型和函数中,或将其显式。装饰师的语法如下。 +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 +``` erg @deco -X = ... +X=... ``` -装饰器可以有多个,除非冲突。 +You can have multiple decorators as long as they don't conflict. -装饰器不是一个特殊的对象,它的实体只是一个参数函数。装饰器等效于以下伪代码。 +A decorator is not a special object, it's just a one-argument function. The decorator is equivalent to the following pseudocode. - -```erg -X = ... +``` erg +X=... X = deco(X) ``` -因为 Erg 不能重新赋值变量,所以上面的代码不能通过。对于简单的变量,这与相同,但对于即时块和子程序,这是不可能的,因此需要一个装饰器。 +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 +``` erg @deco f x = y = ... x + y -# コードが横長になるのを防ぐこともできる +# You can also prevent the code from becoming horizontal @LongNameDeco1 @LongNameDeco2 -C = Class ... +C = Class... ``` -下面介绍一些频出的嵌入式装饰器。 +Below are some frequently used built-in decorators. ## Inheritable -指示所定义的类型是可继承类。如果将参数指定为,则外部模块类可以继承这些参数。默认为,不能从外部继承。 +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 -使方法不可覆盖。将类附加到类后,它将成为不可继承类,但这没有意义,因为这是缺省类。 +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 -用于覆盖属性。缺省情况下,Erg 会在尝试定义与基类相同的属性时出错。 +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 that the argument trait is implemented. - -```erg +``` erg Add = Trait { .`_+_` = Self.(Self) -> Self } @@ -70,10 +68,10 @@ C. ## Attach -指定默认情况下随托盘一起提供的附件曲面片。这样,你就可以重现与 Rust 的trait相同的行为。 +Specifies the attachment patch that comes with the trait by default. +This allows you to reproduce the same behavior as Rust traits. - -```erg +``` erg # foo.er Add R = Trait { .AddO = Type @@ -88,37 +86,35 @@ AddForOdd = Patch(Odd, Impl := ClosedAdd) AddForOdd.AddO = Even ``` -这将在从其他模块导入托盘时自动应用附件修补程序。 +This will automatically apply the attachment patch when importing traits from other modules. - -```erg -# 本来IntIsBinAdd, OddIsBinAddも同時にインポートする必要があるが、アタッチメントパッチなら省略可 +``` erg +# 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 ``` -在内部,我们只是使用trait的方法将其连接起来。如果发生冲突,可以使用trait的方法将其移除。 +Internally it's just attached using the trait's `.attach` method. Conflicts can be removed with the trait's `.detach` method. - -```erg +``` erg @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 specification is obsolete and deprecated. ## Test -指示测试子程序。测试子例程使用命令执行。 +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/zh_CN/syntax/30_error_handling.md b/doc/zh_CN/syntax/30_error_handling.md index 4bb8e220..c67e363a 100644 --- a/doc/zh_CN/syntax/30_error_handling.md +++ b/doc/zh_CN/syntax/30_error_handling.md @@ -1,20 +1,22 @@ -# 错误处理系统 +# error handling system -主要使用 Result 类型。在 Erg 中,如果丢弃 Error 类型的对象(不在顶层),则会发生错误。 +Mainly use Result type. +In Erg, an error occurs if you throw away an Error type object (not supported at the top level). -## 异常,与 Python 的互操作 +## Exceptions, interop with Python -Erg 没有异常机制(Exception)。导入 Python 函数时 +Erg does not have an exception mechanism (Exception). When importing a Python function -* 返回类型 -* 类型(可能导致运行时错误) +* Set return value to `T or Error` type +* `T or Panic` type (may cause runtime error) -的两个选项,在中默认为后者。如果要作为前者导入,请在中指定)。 +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 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 @@ -26,10 +28,9 @@ except e: print(e) ``` -在上面的示例中,仅此代码并不知道异常是从哪个函数调度的。即使追溯到函数定义,也很难确定该函数是否会出现异常。 +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 +``` erg # Erg try!: do!: @@ -40,16 +41,16 @@ try!: print! e ``` -相反,在本示例中,和可以生成错误。确切地说,也可能是类型,但在使用中值时,你必须执行此操作。 +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. -使用类型的好处远不止这些。类型也是线程安全的。这意味着错误信息可以在并行执行期间(很容易)传递。 +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 -/类型不会产生副作用,因此它不具有与异常不同的诸如发送位置之类的信息(上下文),但可以使用方法将信息添加到对象。方法是使用对象本身来创建新的对象的方法。它是可链接的,可以有多个上下文。 +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 +``` erg f() = todo() \ .context "to be implemented in ver 1.2" \ @@ -61,14 +62,16 @@ f() # hint: and more hints ... ``` -注意,属性(如)不是次要属性,因此不是 context,不能覆盖最初生成的属性。 +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 -类型由于其方便性,在其他语言中也被广泛采用,但与异常机制相比,其缺点是错误的来源变得更难理解。因此,在 Erg 中,使对象具有属性,模拟地再现了异常机制那样的栈跟踪。是调用对象的数组。每当 Error 对象(包括所致)时,它的调用子例程将加载到中。如果在环境中,它将死机并显示回溯。 +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 +``` erg f x = ... y = foo.try_some(x)? @@ -80,27 +83,27 @@ g 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)? +# ... +# 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: ... ``` -## 恐慌 +## Panic -Erg 还存在一个名为的机制来处理不可恢复的错误。不可恢复的错误可能是由外部因素引起的错误,例如软/硬件故障,致命到无法继续执行代码的程度,或者是程序编写者不想要的错误。如果发生这种情况,由于程序员的努力无法使其恢复正常系统,因此当场终止程序。这叫做“恐慌”。 +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". -使用函数执行死机。 +Panic is done with the `panic` function. - -```erg +``` erg panic "something went wrong!" ```

Previous | Next -

+

\ No newline at end of file diff --git a/doc/zh_CN/syntax/31_pipeline.md b/doc/zh_CN/syntax/31_pipeline.md index be124273..652f756d 100644 --- a/doc/zh_CN/syntax/31_pipeline.md +++ b/doc/zh_CN/syntax/31_pipeline.md @@ -1,26 +1,26 @@ -# 流水线运算符 +# pipeline operator -按如下方式使用管线运算符。 +Pipeline operators are used like this: - -```erg +``` erg 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`. +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 +``` erg 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 -# パイプライン演算子を使わずに実装する場合、 +# When implemented without the pipeline operator, _evens = (1..100).iter().filter(i -> i % 2 == 0).collect(Array) -# または +# or __evens = 1..100 \ .iter() \ .filter i -> i % 2 == 0 \ @@ -29,4 +29,4 @@ __evens = 1..100 \

Previous | Next -

+

\ 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 index fcb7b207..1948466b 100644 --- a/doc/zh_CN/syntax/32_integration_with_Python.md +++ b/doc/zh_CN/syntax/32_integration_with_Python.md @@ -1,9 +1,9 @@ -# 与 Python 合作 +# Integration with Python -## 导出到 Python - -编译 Erg 脚本将生成一个.pyc 文件,你可以将其作为一个模块导入 Python。但是,在 Erg 端设置为私有的变量不能从 Python 访问。 +## Export to Python +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 # foo.er @@ -11,12 +11,10 @@ private = "this is a private variable" ``` - ```console erg --compile foo.er ``` - ```python import foo @@ -24,24 +22,23 @@ print(foo.public) print(foo.private) # AttributeError: ``` -## 从 Python 导入 +## Import from Python -默认情况下,从 Python 引入的所有对象都是类型。长此以往,我们也无法进行比较,所以我们需要进行类型的筛选。 +All objects imported from Python are by default of type `Object`. Since no comparisons can be made at this point, it is necessary to refine the type. -## 标准库类型 - -Python 标准库中的所有 API 都由 Erg 开发团队指定类型。 +## Type Specification in the Standard Library +All APIs in the Python standard library are type specified by the Erg development team. ```erg time = pyimport "time" time.sleep! 1 ``` -## 指定用户脚本类型 - -创建一个文件,为 Python 的模块创建类型。Python 端的 type hint 不是 100% 的保证,因此将被忽略。 +## Type Specification for User Scripts +Create a `foo.d.er` file that types the Python `foo` module. +Type hints on the Python side are ignored since they are not 100% guaranteed. ```python # foo.py @@ -50,9 +47,9 @@ def bar(x): ... def baz(): ... +... ``` - ```erg # foo.d.er foo = pyimport "foo" @@ -61,18 +58,16 @@ foo = pyimport "foo" .baz! = declare foo.'baz', () => Int ``` - ```erg 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 declare|S: Subroutine| sub!: S, T = - # 実は、=>はブロックの副作用がなければ関数にキャストできる + # Actually, => can be cast to a function without block side effects x => assert x in T.Input y = sub!(x) @@ -80,7 +75,7 @@ declare|S: Subroutine| sub!: S, T = y ``` -这是一个运行时开销,因此计划在 Erg 类型系统上对 Python 脚本进行静态类型分析。 +Since this is a runtime overhead, a project is planned to statically type analyze Python scripts with Erg's type system.

Previous | Next diff --git a/doc/zh_CN/syntax/33_package_system.md b/doc/zh_CN/syntax/33_package_system.md index e0a02a7e..dded29be 100644 --- a/doc/zh_CN/syntax/33_package_system.md +++ b/doc/zh_CN/syntax/33_package_system.md @@ -1,13 +1,15 @@ -# 包装系统 +# Package System -Erg 软件包大致可以分为 app 软件包(应用程序)和 lib 软件包(库)。app 包的入口点是。执行中定义的函数。lib 包的入口点是。导入包相当于导入。 +Erg packages can be roughly classified into the app package, which is the application, and the lib package, which is the library. +The entry point of the app package is `src/app.er`. The `main` function defined in `app.er` is executed. +The entry point for the lib package is `src/lib.er`. Importing a package is equivalent to importing `lib.er`. -软件包有一个称为模块的子结构。在 Erg 中,模块是 Erg 文件或由 Erg 文件组成的目录。外部 Erg 文件/目录可以作为模块对象进行操作。 +A package has a sub-structure called a module, which in Erg is an Erg file or directory composed of Erg files. External Erg files/directories are manipulatable objects as module objects. -要将目录识别为模块,必须在目录中放置文件。它类似于 Python 中的,但与不同,它位于目录之外。 - -例如,请考虑以下目录配置。 +In order for a directory to be recognized as a module, it is necessary to place a `(directory name).er` file in the directory. +This is similar to Python's `__init__.py`, but unlike `__init__.py`, it is placed outside the directory. +As an example, consider the following directory structure. ```console └─┬ ./src @@ -19,8 +21,9 @@ Erg 软件包大致可以分为 app 软件包(应用程序)和 lib 软件包 └─ qux.er ``` -允许你导入模块和模块。由于存在文件,目录可以识别为模块。模块是由文件组成的模块,模块是由目录组成的模块。模块还具有模块。该模块仅是模块的属性,可通过访问。 - +You can import `foo` and `bar` modules in `app.er`. The `bar` directory can be recognized as a module because of the `bar.er` file. +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 # app.er @@ -33,16 +36,16 @@ main args = ... ``` -请注意,用于访问子模块的分隔符为。这是因为文件名可能类似于。不建议使用这样的文件名。因为在 Erg 中,的前缀是有意义的。例如,测试模块。以结尾的文件是(白盒)测试模块,在执行测试时执行以装饰的子程序。 - +Note the `/` delimiter for accessing submodules. This is because there can be file names such as `bar.baz.er`. +Such filenames are discouraged, since the `.er` prefix is meaningful in Erg. +For example, a module for testing. A file ending with `.test.er` is a (white box) test module, which executes a subroutine decorated with `@Test` when the test is run. ```console └─┬ ./src ├─ app.er ├─ foo.er └─ foo.test.er -``` - +./src ```erg # app.er @@ -52,8 +55,7 @@ main args = ... ``` -此外,以结尾的文件是专用模块,只能从同一目录中的模块访问。 - +Also, files ending in ``.private.er`` are private modules and can only be accessed by modules in the same directory. ```console └─┬ @@ -64,7 +66,6 @@ main args = └─ qux.er ``` - ```erg # foo.er bar = import "bar" @@ -72,7 +73,6 @@ bar.qux bar.baz # AttributeError: module 'baz' is private ``` - ```erg # qux.er baz = import "baz" diff --git a/doc/zh_CN/syntax/34_generator.md b/doc/zh_CN/syntax/34_generator.md index 8564835c..1aef8649 100644 --- a/doc/zh_CN/syntax/34_generator.md +++ b/doc/zh_CN/syntax/34_generator.md @@ -1,7 +1,6 @@ -# 发电机 - -生成器是在块中使用过程的特殊过程。 +# Generator +Generators are special procedures that use the `yield!` procedure in a block. ```erg g!() = @@ -10,26 +9,25 @@ g!() = yield! 3 ``` -是在子例程块中定义的过程,它调用。它返回的返回值类似于,但它保存块在该时刻的执行状态,并在再次调用时继续执行。生成器既是过程又是迭代器。Python 生成器是生成迭代器的函数,而 Erg 直接迭代。过程本身通常不是可变对象(没有),但生成器是可变的,因为它可以在每次执行时更改其内容。 - +`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 -# Generator! < Proc +# Generator! g!: Generator!((), Int) assert g!() == 1 assert g!() == 2 assert g!() == 3 ``` -可以按如下方式定义 Python 样式生成器。 - +A Python-style generator can be defined as follows. ```erg make_g() = () => yield! 1 yield! 2 yield! 3 -make_g: () => Generator!((), Int) +make_g: () => Generator! ```

diff --git a/doc/zh_CN/syntax/container_ownership.md b/doc/zh_CN/syntax/container_ownership.md index 92bfcf5f..3067bb35 100644 --- a/doc/zh_CN/syntax/container_ownership.md +++ b/doc/zh_CN/syntax/container_ownership.md @@ -1,24 +1,25 @@ -# Subscript(下标访问) +# Subscript (index access) -不同于常规方法。 +`[]` is different from normal methods. - -```erg +``` erg a = [!1, !2] a[0].inc!() assert a == [2, 2] ``` -请记住,不能在子例程的返回值中指定引用。在这里,的类型显然应该是的类型取决于上下文)。因此,实际上是与相同的特殊语法的一部分。不像 Python,你不能过载。方法也不能再现行为。 +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. - -```erg +``` erg C = Class {i = Int!} -C.get(ref self) = +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 +#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) @@ -30,13 +31,12 @@ assert i == 2 own_do! C.new({i = 1}).steal(), i => i.inc!() ``` -此外,也可以剥夺所有权,但元素并不会因此而发生转移。 +Also, `[]` can be disowned, but the element is not shifted. - -```erg +``` erg 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/zh_CN/syntax/indexes.md b/doc/zh_CN/syntax/indexes.md index ba4811be..9a530a07 100644 --- a/doc/zh_CN/syntax/indexes.md +++ b/doc/zh_CN/syntax/indexes.md @@ -1,43 +1,43 @@ -# 指数 +# index -有关不在此索引中的 API,请参阅 [此处](../API/index.md)。 -有关术语,请参见 [此处](../dev_guide/terms.md)。 +See [here](../API/index.md) for APIs not in this index. +See [here](../dev_guide/terms.md) for terminology. -## 象征 +## symbol -* ! - * !-type → [可变类型](./type/mut.md) +* ! + * !-type → [mutable type](./type/mut.md) * [#](./00_basic.md/#comment) *$ -*% +* % * & * && -* ′(单引号) +* ′ (single quote) * () * * - * [*-less 乘法](./01_literal.md/#less-multiplication) -* + (前缀) - * +_ → + (前缀) -* + (中缀) + * [*-less multiplication](./01_literal.md/#less-multiplication) +* + (prefix) + * +_ → + (prefix) +* + (infix) * , -* −(前缀) - * −_ → − (前缀) -* −(中缀) - * 减号;> -* . → [可见性] +* − (prefix) + * −_ → − (prefix) +* − (infix) + * −> +* . → [Visibility] * / * : - * :: → [可见性] + * :: → [visibility] * ; -* < +* < * <: - * << - * <= + * << + * <= * = * == * => * > - *>> + * >> * >= * ? * @ @@ -46,407 +46,407 @@ * ^ * ^^ * _ - * _+_ → +(中缀) - * _-_ → −(中缀) + * _+_ → + (infix) + * _-_ → − (infix) *`` * {} - * {} 类型 + * {} type * {:} * {=} - * {=} 类型 + * {=} type * | * || * ~ -## 字母 +## alphabet -### 一个 +### A -* [代数类型] -* [和] -* [和] -* [断言] -* [属性] +* [algebraic type] +* [And] +* [and] +* [assert] +* [attribute] ###B -* [根据] -* [布尔] +* [Base] +* [Bool] -### C +### C -* [班级] +* [Class] ###D -*已弃用 -* [清楚的] +*Deprecated +* [distinct] ###E -* [枚举类型] -*[方程式] -*[erg] +* [enum type] +*[Eq] +*[Erg] -###F +###F -*[为了] +*[for] -###G +###G -###H +###H -### 我 +### I -*[如果] -* [进口] -* [在] -* [诠释] +* [if] +* [import] +* [in] +* [Int] ###J ###K -### 大号 +### L -* let-polymorphism → [rank 1 多态性] -* [日志] +* let-polymorphism → [rank 1 polymorphism] +* [log] ###M -* [匹配] +* [match] ###N -*[纳特] -* 绝不 -*没有任何 -*没有任何 -*[不是] -* [不是] +*[Nat] +* Never +*None +*None +*[Not] +* [not] ###O -* [选项] -* [或者] -* [或者] -*[订购] +* [Option] +* [Or] +* [or] +*[Ord] ###P -* 恐慌 -* [打印!](./../API/procs.md#print) -*[Python] +* panic +* [print!](./../API/procs.md#print) +* [Python] -### Q +###Q ### R -* 参考 -* 参考! -* [结果] -* [根对象] +* ref +*ref! +* [Result] +*[rootobj] -### S +###S -* 自己 -* [自我](./type/special.md) -* [副作用](./07_side_effect.md) -* [力量] +*self +* [Self](./type/special.md) +* [side-effect](./07_side_effect.md) +*[Str] -### T +###T -* 特质 -* [真的] -* [类型] -* [类型] +* Traits +* [True] +* [Type] +* [type] -### U +###U -### V +###V ### W -* [尽管!] +* [while!] -### X +###X -### Y +###Y -### Z +###Z -## 一行 +## A line -* [断言] -* 值对象 -* [附件补丁](./29_decorator.md#attach) -* Ad-hoc 多态性 → [无重载](./type/overloading.md) -* 属性 → [属性] -* 稀有度 -* [依赖类型](./type/dependent_type.md) -* 不可变 → [不可变] -* 参数 → [参数] -* 实例 -* [即时块](./00_basic.md#表达式分隔符) -* 指数 -* [缩进](./00_basic.md#indent) -* 别名 -* 错误 - * [错误处理] -* [运算符](./06_operator.md) - * [运算符绑定强度] -* 覆盖 -* [不重载](./type/overloading.md) -* 越位规则 → [缩进](./00_basic.md#indent) -* [目的] - * 面向对象 -* 操作数 → [操作数](./06_operator.md) -* 运算符 → [运算符](./06_operator.md) +* [Assertion] +* value object +* [Attachment patch](./29_decorator.md#attach) +* Ad-hoc polymorphism → [No overloading](./type/overloading.md) +* Attribute → [Attribute] +* arity +* [dependent type](./type/dependent_type.md) +* immutable → [immutable] +* Argument → [Argument] +* instance +* [instant block](./00_basic.md# expression separator) +* index +* [indent](./00_basic.md#indent) +* alias +* error + * [Error handling] +* [operator](./06_operator.md) + * [operator binding strength] +* Override +* [No overloading](./type/overloading.md) +* Offside rule → [indent](./00_basic.md#indent) +* [object] + * Object-orientation +* Operand → [operand](./06_operator.md) +* operator → [operator](./06_operator.md) -##嘉线 +## Ka line -* [种类](./type/advanced/kind.md) -* [可见性] -* [类型] - * [类型规格] - * [类型擦除](./type/advanced/erasure.md) - * [类型推断] - * [类型注释](./type/conv_type.md) - * [类型参数] - * [类型添加](./type/advanced/erasure.md) - * [类型变量](./type/type_variable.md) - * [类型约束] -* [警卫] -* 封装 -* [多变的] - * [可变对象] - * [多变的] - * [变量参考] - * [变量数组] - * [可变参数] -* [函数](./04_function.md) - * [函数式编程] (./23_scope.md#Avoiding mutable state 函数式编程) -* 基本类型 -* 签 - * [命名类型] → [类](./type/04_class.md) - * [报喜] - * [名义子类型](./type/05_nst_vs_sst.md) -*捕获→[关闭] -* [协变] -* [关键字参数] -* 空集 → [{}] -* 部分 - * [间隔类型](./type/11_interval.md) - * 区间运算符 -* 内置 - * [内置型] - * [内置函数](./05_builtin_funcs.md) - * [内置程序](./09_builtin_procs.md) -* [类](./type/04_class.md) -* [关闭] -* [全局变量] -* [克隆] -* [继承](./type/07_inheritance.md) -* 高楼层 - * [高级种类](./type/advanced/kind.md) - * 高阶类型 - * 高阶函数 -* [公共变量] -* [结构亚型] -* ~~反向引用~~ → [反向引用] -* [复制] -* 评论 -* [集合](./10_array.md) -* 冒号 → [:] -* [构造函数](./type/04_class.md) -* 容器 -* 编译器 -* [编译时计算](./04_function.md#compile-time函数) -* 逗号 → [,] +* [Kind](./type/advanced/kind.md) +* [Visibility] +* [type] + * [type specification] + * [type erasure](./type/advanced/erasure.md) + * [type inference] + * [type annotation](./type/conv_type.md) + * [type argument] + * [type addition](./type/advanced/erasure.md) + * [type variable](./type/type_variable.md) + * [type constraint] +* [Guard] +* Encapsulation +* [variable] + * [mutable object] + * [variable] + * [variable reference] + * [variable array] + * [variable arguments] +* [function](./04_function.md) + * [Functional programming] (./23_scope.md#Avoiding mutable state Functional programming) +* base type +* Signed + * [Named type] → [Class](./type/04_class.md) + * [Annunciation] + * [nominal subtype](./type/05_nst_vs_sst.md) +* Capture → [Closure] +* [covariant] +* [keyword argument] +* empty set → [{}] +* section + * [Interval type](./type/11_interval.md) + * interval operator +* built-in + * [Built-in type] + * [Built-in functions](./05_builtin_funcs.md) + * [Built-in procedures](./09_builtin_procs.md) +* [class](./type/04_class.md) +* [Closure] +* [global variables] +* [Clone] +* [Inheritance](./type/07_inheritance.md) +* high floor + * [Advanced kind](./type/advanced/kind.md) + * higher order type + * Higher-order functions +* [public variable] +* [structural subtype] +* ~~backreference~~ → [backreference] +* [copy] +* comment +* [Collection](./10_array.md) +* colon → [:] +* [constructor](./type/04_class.md) +* container +* Compiler +* [compile-time calculation](./04_function.md#compile-time function) +* Comma → [,] -## sa线 +## sa line -* 递归 - * 递归 - * [递归函数](./04_function.md#递归函数) -* 下标 → [索引] -* [子类型多态性](./type/overloading.md) -* 子程序 -* [参考] (./18_memory_management.md# 借用) - * 参考对象 - * [引用计数(RC)](./18_memory_management.md#内存管理) - * 引用相等 → [副作用](./07_side_effect.md) -* [标识符](./02_variable.md/# 赋值) -* 签名 - * 类型签名 -* [字典](./11_dict.md) -* [自然数] → [Nat] -* 泛型 → [通用类型] -* 发电机 -* [投影类型] -* 借用 → [参考](./18_memory_management.md#Borrow) -* [阴影] (./02_name.md# 变量) -* 物种 → [种类](./type/advanced/kind.md) -* [套装] → [套装] -* 谓词 - * [谓词函数] -* 条件分支 -* [所有权] -* 布尔 → [布尔] -* 单身人士 -* [符号] → [标识符](./02_name.md) - * [符号化] -* [脚本](./00_basic.md# 脚本) -* 范围 -* 扩展运算符 → [扩展赋值] -* [切片](./10_array.md#slice) -* 控制字符 -* [整数] → [整数] -* [设置](./12_set.md) -* 分号 → [;] -* [声明](./03_declaration.md) -* 全名 - * 通用类型 → [多态类型](./type/quantified.md) - * 封闭式通用 - * 打开通用 - * 通用函数 → 多相关函数 - * 通用量化 -* 前缀运算符 -* 相互递归 -* 下标 → [索引] -* [属性] - * [属性子类型] +* recursion + * recursive + * [Recursive function](./04_function.md#Recursive function) +* subscript → [index] +* [Subtyping Polymorphism](./type/overloading.md) +* Subroutine +* [reference] (./18_memory_management.md# borrowed) + * reference object + * [Reference counting (RC)] (./18_memory_management.md# memory management) + * Reference equality → [side effect](./07_side_effect.md) +* [identifier](./02_variable.md/# assignment) +* Signature + * type signature +* [dict](./11_dict.md) +* [Natural number] → [Nat] +* generics → [universal type] +* Generator +* [projective type] +* Borrow → [Reference](./18_memory_management.md#Borrow) +* [Shadowing] (./02_name.md# variables) +* Species → [Kind](./type/advanced/kind.md) +* [Set] → [Set] +* predicate + * [predicate function] +* Conditional branch +* [Ownership] +* Boolean → [Bool] +* Singleton +* [Symbol] → [Identifier](./02_name.md) + * [symbolization] +* [script](./00_basic.md# script) +* scope +* Spread operator → [expansion assignment] +* [slice](./10_array.md#slice) +* control character +* [Integer] → [Int] +* [set](./12_set.md) +* Semicolon → [;] +* [Declaration](./03_declaration.md) +* full name + * Universal type → [polymorphic type](./type/quantified.md) + * closed universal + * Open Universal + * universal function → polycorrelation function + * universal quantification +* prefix operator +* mutually recursive +* subscript → [index] +* [attribute] + * [attribute subtype] -## 塔线 +## Ta line -* [代数](./02_name.md) - * [代数类型](./type/13_algebraic.md) - * 代数数据类型 -* [赋值](./02_variable.md/#assignment) -* 多 - * [多重继承](./type/07_inheritance.md/#禁止多重继承) - * 多重赋值 - * 重载 → [不重载] -* 多相 - * [多态类型](./type/quantified.md) - * 多相关系数 -* 多态 → [多态] -*鸭子打字 -* [元组](./11_tuple.md) -* 单相 - * 单相 - * 单相型 - * 单相关系数 -* [延迟初始化] -* 提取任务 -* 抽象语法树 → [AST] -* 中缀运算符 -* [常数](./02_name.md/#constant) - * [常量类型](./type/advanced/const.md) - * [常量表达式](./type/advanced/const.md) -*[定义] -* 提供的属性 -* [申请] -* [装饰器](./29_decorator.md) -* 析构函数 -* 程序 → [程序](./08_procedure.md) -* [默认参数](./04_function.md/#default arguments default-parameters) -* 扩张 - * [扩展运算符] - * [扩展分配] -* [特殊格式](./../API/special.md) -* 匿名函数 → [匿名函数](./20_lambda.md) -* 点运算符 (`.`) → [属性参考] -* 顶部 - * 顶部类型 → [结构对象] - * 顶级 → [对象] -* [特质](./type/03_trait.md) +* [algebra](./02_name.md) + * [Algebraic type](./type/13_algebraic.md) + * algebraic data types +* [assignment](./02_variable.md/#assignment) +* Multiple + * [Multiple inheritance](./type/07_inheritance.md/#Prohibition of multiple inheritance) + * Multiple assignment + * Overloading → [No overloading] +* Polyphase + * [polymorphic type](./type/quantified.md) + * polycorrelation coefficient +* polymorphism → [polymorphism] +* duck typing +* [tuple](./11_tuple.md) +* Single-phase + * Single phase + * Single-phase type + * Single correlation coefficient +* [lazy initialization] +* extraction assignment +* Abstract syntax tree → [AST] +* infix operator +* [constant](./02_name.md/#constant) + * [constant type](./type/advanced/const.md) + * [constant expression](./type/advanced/const.md) +*[definition] +* provided attributes +* [Apply] +* [decorator](./29_decorator.md) +* Destructor +* procedure → [procedure](./08_procedure.md) +* [default arguments](./04_function.md/#default arguments default-parameters) +* expand + * [expansion operator] + * [expansion assignment] +* [special format](./../API/special.md) +* Anonymous function → [anonymous function](./20_lambda.md) +* Dot operator (`.`) → [attribute reference] +* Top + * Top type → [Structural Object] + * Top class → [Object] +* [trait](./type/03_trait.md) -## 没有一行 +## na line -* [理解](./27_comprehension.md) -* ~~中缀运算符~~ → [中缀运算符] -* [命名空间] +* [Comprehension](./27_comprehension.md) +* ~~Infix operator~~ → [Infix operator] +* [namespace] -## 是一行 +## is a line -* [数组](./10_array.md) -* [派生类型](./type/variances.md/#用户定义的类型变体) -* [模式(匹配)](./26_pattern_matching.md) -* [包](./33_package_s系统.md) -* Hashmap → [字典](./11_dict.md) -* [补丁](./type/07_patch.md) -* 公共变量 → [公共变量](./19_visibility.md) -* 参数 → [参数](./04_function.md) -* [参数多态](./type/overloading.md) -* [逆变](./type/advanced/variance.md) -* 相比 - * [比较运算符] - * [可比类型] -* [私有变量](./19_visibility.md) -* 标准 - * 标准输出 - * 标准输入 - * 标准库 -* [副作用](./07_side_effect.md) -* 复数 → [复数] -* [浮动] → [浮动] -* 私有变量 → [私有变量] -* 布尔代数 → [布尔] -* [程序](./08_procedure.md) -* [参数](./04_function.md) -* 部分输入 → [子输入] -* [不可变] - * [不可变对象] - * [不可变类型] - * [不可变引用] -* [筛子类型](./type/12_refinement.md) -* [堵塞] -* 解构赋值 -* [变量](./02_variable.md) -* 底部 - * 底部类型 → [{}] - * 底层 → [从不] -* [多态性] +* [Array](./10_array.md) +* [derived type](./type/variances.md/# user-defined type variations) +* [pattern (match)](./26_pattern_matching.md) +* [package](./33_package_ssystem.md) +* Hashmap → [dictionary](./11_dict.md) +* [patch](./type/07_patch.md) +* public variable → [public variable](./19_visibility.md) +* Parameter → [argument](./04_function.md) +* [Parametric Polymorphism](./type/overloading.md) +* [contravariant](./type/advanced/variance.md) +* Compare + * [comparison operator] + * [comparable type] +* [private variable](./19_visibility.md) +* standard + * standard output + * standard input + * standard library +* [side effect](./07_side_effect.md) +* Complex number → [Complex] +* [Float] → [Float] +* Private Variable → [Private Variable] +* Boolean algebra → [Bool] +* [procedure](./08_procedure.md) +* [argument](./04_function.md) +* Partial Typing → [Subtyping] +* [immutable] + * [immutable object] + * [immutable type] + * [immutable reference] +* [sieve type](./type/12_refinement.md) +* [block] +* deconstruction assignment +* [variable](./02_variable.md) +* Bottom + * bottom type → [{}] + * Bottom class → [Never] +* [Polymorphism] -## 马线 +## ma line -* ~~ 前缀运算符 ~~ → 前缀运算符 -* [标记类型](./type/advanced/marker_trait.md) -* [匿名函数](./21_lambda.md) -* 可变 → [可变] -* [移动] -* 方法 -* 元字符 -* [模块](./24_module.md) -* [字符串] → [字符串] - * [字符串插值](./01_literal.md/#str 字面量) -* 返回值 +* ~~ prefix operator ~~ → prefix operator +* [Marker type](./type/advanced/marker_trait.md) +* [anonymous function](./21_lambda.md) +* mutable → [mutable] +* [Move] +* methods +* Metacharacter +* [module](./24_module.md) +* [String] → [Str] + * [String interpolation](./01_literal.md/#str literal) +* Return value -## 或行 +## or line -* [幽灵类型](./type/advanced/phantom.md) -* 请求属性 -* [元素] -* [称呼] +* [Ghost type](./type/advanced/phantom.md) +* request attributes +* [element] +* [call] -## 拉线 +## Ra line -* [图书馆] -* Lambda 表达式 → [匿名函数](./20_lambda.md) -* 排名 - * [Rank 2 多态性](./type/advanced/rank2type.md) -* [文字](./01_literal.md) - * [文字标识符](./18_naming_rule.md/#literal identifier) -* [量化](./type/quantified.md) -* [布局](./type/mut.md) -* [枚举](./type/10_enum.md) -* [记录](./12_record.md) - * [记录类型] - * 记录多态 → [列多态] -* [列多态] -* [局部变量](./19_visibility.md) +* [Library] +* Lambda expression → [anonymous function](./20_lambda.md) +* rank + * [Rank 2 Polymorphism](./type/advanced/rank2type.md) +* [literal](./01_literal.md) + * [literal identifier](./18_naming_rule.md/#literal identifier) +* [quantified](./type/quantified.md) +* [Layout](./type/mut.md) +* [enum](./type/10_enum.md) +* [record](./12_record.md) + * [record type] + * Record Polymorphism → [Column Polymorphism] +* [column polymorphic] +* [local variable](./19_visibility.md) -## 线 +## line -* 通配符 \ No newline at end of file +* Wildcard \ No newline at end of file diff --git a/doc/zh_CN/syntax/quick_tour.md b/doc/zh_CN/syntax/quick_tour.md index a2a75af5..0c5e6cf7 100644 --- a/doc/zh_CN/syntax/quick_tour.md +++ b/doc/zh_CN/syntax/quick_tour.md @@ -1,155 +1,145 @@ # Quick Tour -下面的文档旨在让初学者也能理解。对于已经掌握 Python,Rust,Haskell 等语言的人来说,这可能有点多余。 +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. -因此,下面将概述性地介绍 Erg 的语法。没有特别提到的部分可以认为和 Python 一样。 +So, here's an overview of the Erg grammar. +Please think that the parts not mentioned are the same as Python. -## 变量,常量 +## variables, constants -变量定义为。与 Haskell 一样,一旦定义变量,就无法重写。但是,你可以在另一个范围内进行阴影。 +Variables are defined with `=`. As with Haskell, variables once defined cannot be changed. However, it can be shadowed in another scope. - -```erg +``` erg 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. - -```erg +``` erg PI = 3.141592653589793 match random.random!(0..10): - PI: + PIs: log "You get PI, it's a miracle!" ``` -## 声明 +## declaration -与 Python 不同,你只能先声明变量类型。当然,声明类型必须与实际赋值的对象类型兼容。 +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. - -```erg +``` erg i: Int i = 10 ``` -## 函数 +## Functions -你可以像 Haskell 一样定义它。 +You can define it just like in Haskell. - -```erg -fib 0 = 0 -fib 1 = 1 -fib n = fib(n - 1) + fib(n - 2) +``` erg +fib0 = 0 +fib1 = 1 +fibn = fib(n - 1) + fib(n - 2) ``` -可以按如下方式定义未命名函数。 +An anonymous function can be defined like this: - -```erg +``` erg i -> i + 1 assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4] ``` -## 运算符 +## operator -Erg 自己的运算符如下所示。 +The Erg-specific operators are: -### 变量运算符(!) +### mutating operator (!) -就像 Ocaml 的。 +It's like `ref` in Ocaml. - -```erg +``` erg i = !0 i.update! x -> x + 1 assert i == 1 ``` -## 过程 +## procedures -有副作用的子程序称为过程,并带有。 +Subroutines with side effects are called procedures and are marked with `!`. - -```erg +``` erg print! 1 # 1 ``` -## 类属函数(多相关数) +## generic function (polycorrelation) - -```erg +``` erg id|T|(x: T): T = x id(1): Int id("a"): Str ``` -## 记录 +## Records -你可以使用 ML 语言中的记录(或 JS 中的对象文字)。 +You can use the equivalent of records in ML-like languages ​​(or object literals in JS). - -```erg +``` erg p = {x = 1; y = 2} ``` -## 所有权 +## Ownership -Erg 拥有可变对象(使用运算符可变的对象)的所有权,不能从多个位置重写。 +Ergs are owned by mutable objects (objects mutated with the `!` operator) and cannot be rewritten from multiple places. - -```erg +``` erg i = !0 j = i assert j == 0 -i # MoveError +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. - -```erg +``` erg # foo.er .x = 1 y = 1 ``` - -```erg +``` erg foo = import "foo" assert foo.x == 1 foo.y # VisibilityError ``` -## 模式匹配 +## pattern matching -### 变量模式 +### variable pattern - -```erg -# basic assignment +``` erg +# basic assignments i = 1 # with type i: Int = 1 -# function +# functions fn x = x + 1 fn: Int -> Int = x -> x + 1 ``` -### 文字模式 +### Literal patterns - -```erg +``` erg # if `i` cannot be determined to be 1 at compile time, TypeError occurs. -# short hand of `_: {1} = i` +# shorthand of `_: {1} = i` 1 = i # simple pattern matching match x: @@ -157,15 +147,14 @@ match x: 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 - -```erg +``` erg PI = 3.141592653589793 E = 2.718281828459045 num = PI @@ -175,49 +164,44 @@ name = match num: _ -> "unnamed" ``` -### 销毁(通配符)模式 +### discard (wildcard) pattern - -```erg +``` erg _ = 1 _: Int = 1 right(_, r) = r ``` -### 可变长度模式 +### Variable length patterns -与后述的元组/数组/记录模式组合使用。 +Used in combination with the tuple/array/record pattern described later. - -```erg -[i, ...j] = [1, 2, 3, 4] +``` erg +[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 - -```erg +``` erg (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) -# ネストしていないなら()を省略可能(1, 2は(1, 2)として扱われる) +# If not nested, () can be omitted (1, 2 are treated as (1, 2)) m, n = 1, 2 ``` -### 数组模式 +### array pattern - -```erg -length [] = 0 -length [_, ...rest] = 1 + length rest +``` erg +length[] = 0 +length[_, ...rest] = 1 + lengthrest ``` -#### 记录模式 +#### record pattern - -```erg +``` erg {sin; cos; tan; ...} = import "math" {*} = import "math" # import all @@ -227,32 +211,30 @@ age = match person: {_; age} -> age ``` -### 数据类模式 +### Data class pattern - -```erg +``` erg Point = Inherit {x = Int; y = Int} p = Point::{x = 1; y = 2} Point::{x; y} = p ``` -## 内涵记载 +## Comprehensions - -```erg +``` erg odds = [i | i <- 1..100; i % 2 == 0] ``` -## 类 +## class -Erg 不支持多级和多级继承。 +Erg does not support multiple/multilevel inheritance. -## trait +## Traits -与 Rust 的trait类似,但更接近原意,可以合成和分离,属性和方法是对等的。也不涉及实施。 +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. - -```erg +``` erg XY = Trait {x = Int; y = Int} Z = Trait {z = Int} XYZ = XY and Z @@ -264,24 +246,22 @@ Point. ... ``` -## 补丁 +## patch -你可以为类和trait提供实现。 +You can give implementations to classes and traits. -## 筛子型 +## Sieve type -可以在谓词表达式中限制类型。 +A predicate expression can be type-restricted. - -```erg +``` erg Nat = {I: Int | I >= 0} ``` -## 包含值的参数化(从属) +## parametric type with value (dependent type) - -```erg +``` erg 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 index ddae11a1..d45ede30 100644 --- a/doc/zh_CN/syntax/type/01_type_system.md +++ b/doc/zh_CN/syntax/type/01_type_system.md @@ -1,11 +1,10 @@ -# Erg 类类型系统 +# Erg's Type System -下面是 Erg 类型系统的简要说明。其他部分将介绍更多信息。 +The following is a brief description of Erg's type system. Details are explained in other sections. -## 定义方法 - -Erg 的独特之处在于,(常规)变量、函数(子程序)和类型(卡印度)的定义没有太大的语法差异。所有这些都是根据常规变量和函数定义的语法定义的。 +## How to define +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 f i: Int = i + 1 @@ -19,48 +18,53 @@ T(1) # Type T(1) T.method self = ... D = Class {private = Int; .public = Int} D # -o1 = {private = 1; .public = 2} # o1はどのクラスにも属さないオブジェクト -o2 = D.new {private = 1; .public = 2} # o2はDのインスタンス +o1 = {private = 1; .public = 2} # o1 is an object that does not belong to any class +o2 = D.new {private = 1; .public = 2} # o2 is an instance of D o2 = D.new {.public = 2} # InitializationError: class 'D' requires attribute 'private'(: Int) but not defined ``` -## 分类 +## Classification -Erg 中的所有对象都已输入。最高类型是,它实现了等(它们不是请求方法,也不能覆盖这些属性)。Erg 类型系统采用结构子类型(Structural subtyping,SST)。系统输入的类型称为“结构类型”(Structural type)。有三种结构类型:Attributive(属性类型)/Refinement(筛子类型)/Algebraic(代数类型)。 +All objects in Erg are strongly typed. +The top-level type is `{=}`, which implements `__repr__`, `__hash__`, `clone`, etc. (not required methods, and these attributes cannot be overridden). +Erg's type system incorporates structural subtyping (SST). The types typed by this system are called Structural types. +There are three major types of structural types: Attributive (attribute type), Refinement (refinement type), and Algebraic (algebraic type). | | Record | Enum | Interval | Union | Intersection | Diff | | --------- | ----------- | ---------- | -------------- | ----------- | ------------ | ------------ | | kind | Attributive | Refinement | Refinement | Algebraic | Algebraic | Algebraic | | generator | record | set | range operator | or operator | and operator | not operator | -也可以使用 Nominal subtyping(Nominal subtyping,NST),将 SST 类型转换为 NST 类型称为“类型记名”(Nominalization)。这种类型称为“记名类型”(Nominal type)。在 Erg 中,记名类型为类和trait。如果只是一个类/任务,则通常指的是记录类/记录任务。 +Nominal subtyping (NST) can also be used, and the conversion of an SST type to an NST type is called nominalization of the type. The resulting type is called a nominal type. +In Erg, the nominal types are classes and traits. When we simply say class/trait, we often mean record class/trait. | | Type | Abstraction | Subtyping procedure | | --- | -------------- | ---------------- | ------------------- | | NST | NominalType | Trait | Inheritance | | SST | StructuralType | Structural Trait | (Implicit) | -表示整个记名类型的类型()和整个结构类型的类型()是整个类型的类型()的子类型。 +The type for the entire nominal type (`NominalType`) and the type for the entire structural type (`StructuralType`) are subtypes of the type for the entire type (`Type`). -Erg 可以将参数(类型参数)传递给类型定义。具有类型参数的,等称为多项卡印。它们本身不是类型,但通过应用参数成为类型。此外,没有参数的类型称为简单类型(标量类型)。 +Erg can pass arguments (type arguments) to the type definition. An `Option`, `Array`, etc. with type arguments are called a polynomial kind. These are not themselves types, but they become types by applying arguments. Types such as `Int`, `Str`, etc., which have no arguments, are called simple types (scalar types). -类型可以被视为一个集合,也存在包含关系。例如,包含等,包含。所有类的上级类为,所有类型的下级类为。我们将在后面讨论这一点。 +A type can be regarded as a set, and there is an inclusion relation. For example, `Num` contains `Add`, `Sub`, etc., and `Int` contains `Nat`. +The upper class of all classes is `Object == Class {:}` and the lower class of all types is `Never == Class {}`. This is described below. -## 型 +## Types -像这样的类型以为参数,返回类型,即类型的函数(理论上也称为类型)。像这样的类型被特别称为多相类型,而本身被称为 1 项卡印度。 +A type like `Array T` can be regarded as a function of type `Type -> Type` that takes type `T` as an argument and returns type `Array T` (also called Kind in type theory). Types like `Array T` are specifically called polymorphic types, and `Array` itself is called unary Kind. -参数和返回类型已知的函数类型将显示为。如果要指定类型相同的 2 自变量函数整体,可以指定;如果要指定 N 自变量函数整体,可以指定。但是,由于类型没有关于参数数量或类型的信息,因此调用时所有返回值都是类型。 +The type of a function whose argument and return types are known is denoted as `(T, U) -> V`. If you want to specify an entire two-argument function of the same type, you can use `|T| (T, T) -> T`, and if you want to specify an entire N-argument function, you can use `Func N`. However, the `Func N` type has no information about the number of arguments or their types, so all return values are of type `Obj` when called. -类型应表示为,依此类推。此外,类型实例的名称必须以结尾。 +The `Proc` type is denoted as `() => Int` and so on. Also, the name of the `Proc` type instance must end with `!` at the end. -类型是一个函数/过程,它将其所属的对象指定为第一个参数(作为引用)。对于依赖关系,你还可以在应用方法后指定自己的类型。这意味着你可以指定类型的方法,例如。 +A `Method` type is a function/procedure whose first argument is the object `self` to which it belongs (by reference). For dependent types, you can also specify the type of yourself after the method is applied. This is `T!(!N)` type and `T!(N ~> N-1). () => Int` and so on. -Erg 数组(Array)就是 Python 的列表。是包含三个类型对象的数组类。 +Erg's array (Array) is what Python calls a list. `[Int; 3]` is an array class that contains three objects of type `Int`. -> :既是类型又是值,因此可以这样使用。 +> __Note__: `(Type; N)` is both a type and a value, so it can be used like this. > -> `` `erg +> ```erg. > Types = (Int, Str, Bool) > > for! Types, T => @@ -69,7 +73,6 @@ Erg 数组(Array)就是 Python 的列表。是包含三个类 > a: Types = (1, "aaa", True) > ``` - ```erg pop|T, N|(l: [T; N]): ([T; N-1], T) = [...l, last] = l @@ -80,8 +83,8 @@ lpop|T, N|(l: [T; N]): (T, [T; N-1]) = (first, l) ``` -带有的类型允许对象的内部结构重写。例如,类是一个动态数组。要从类型对象生成类型对象,请使用一元运算符。 - +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 i: Int! = !1 @@ -90,35 +93,36 @@ assert i == 2 arr = [1, 2, 3] arr.push! 4 # ImplError: mut_arr = [1, 2, 3].into [Int; !3] -mut_arr.push! 4 -assert mut_arr == [1, 2, 3, 4] +mut_arr.push4 +assert mut_arr == [1, 2, 3, 4]. ``` -## 类型定义 - -类型定义如下。 +## Type Definitions +Types are defined as follows. ```erg Point2D = {.x = Int; .y = Int} ``` -如果省略,例如,则它将成为类型中使用的私有变量。但这也是请求属性。类型本身也有属性,因为类型也是对象。这些属性称为类型属性。类也称为类属性。 +Note that if `.` is omitted from a variable, it becomes a private variable used within the type. However, this is also a required attribute. +Since types are also objects, there are attributes on the types themselves. Such attributes are called type attributes. In the case of a class, they are also called class attributes. -## 类型类、数据类型(等效) +## Data type -如前所述,Erg 中的“类型”大致是指一组对象。以下是要求(中置运算符)的类型的定义。是一个所谓的类型参数,它包含实现的类型(类),如。在其他语言中,类型参数具有特殊的符号(通用、模板等),但在 Erg 中,类型参数的定义方式与常规参数的定义方式相同。类型参数也可以不是类型对象。例如,序列类型是的语法糖。如果类型实现被覆盖,则用户必须显式选择。 +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 Add R = Trait { .AddO = Type - .`_+_` = Self.(R) -> Self.AddO + . `_+_` = Self.(R) -> Self.AddO } ``` -.是 Add.的缩写。前缀运算符.是类型为的方法。 - +.`_+_` is an abbreviation for Add.`_+_`. The prefix operator .`+_` is a method of type `Num`. ```erg Num = Add and Sub and Mul and Eq @@ -128,8 +132,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 1 + 1 @@ -138,53 +141,53 @@ Nat.`_+_` 1, 1 Int.`_+_` 1, 1 ``` -最上面的四行返回相同的结果(确切地说,最下面的行返回),但通常使用最上面的行。 - -```Ratio.`_+_`(1, 1)```とすると、エラーにはならず`2.0`が返ります。 -これは、`Int <: Ratio`であるために`1`が`Ratio`にダウンキャストされるからです。 -しかしこれはキャストされません。 +The top four lines return the same result (to be exact, the bottom one returns `Int`), but it is common to use the top one. +```Ratio.`_+_`(1, 1)``` will return `2.0` without error. +This is because `Int <: Ratio`, so `1` is downcast to `Ratio`. +But this is not cast. ```erg i = 1 -if i: # TypeError: i: Int cannot cast to Bool, use Int.is_zero() instead. +if i: # TypeError: i: Int cannot be cast to Bool, use Int.is_zero() instead. log "a" log "b" ``` -这是因为()。转换到子类型通常需要验证。 +This is because `Bool <: Int` (`True == 1`, `False == 0`). Casts to subtypes generally require validation. -## 类型推理系统 - -Erg 采用静态烤鸭打字,几乎不需要明确指定类型。 +## Type Inference System +Erg uses static duck typing, so there is little need to explicitly specify the type. ```erg f x, y = x + y ``` -对于上面的代码,将自动推断具有的类型,即。Erg 首先推论最小的类型。如果,则推论为;如果,则推论为。最小化后,类型将不断增大,直到找到实现。对于,由于是具有实现的最小类型,因此将单相化为不匹配,因此将单相化为。如果不是子类型或上类型关系,则从浓度(实例数)较低(如果是多相类型,则参数更少)开始尝试。是作为等部分类型的枚举类型。枚举类型等可以命名为请求/实现方法。在可以访问该类型的命名空间中,满足请求的对象可以使用实现方法。 - +In the case of the code above, the type with `+`, i.e., `Add` is automatically inferred; Erg first infers the smallest type. If `f 0, 1`, it will infer `f x: {0}, y: {1}`, if `n: Nat; f n, 1`, it will infer `f x: Nat, y: {1}`. After minimization, the type is increased until an implementation is found. In the case of `{0}, {1}`, `Nat` is monomorphic to `Nat` since `Nat` is the smallest type with a `+` implementation. +If `{0}, {-1}`, it is monomorphic to `Int` since it does not match `Nat`. If there is no relationship between subtypes and supertypes, the one with the lowest concentration (number of instances) (or even fewer arguments in the case of polymorphic types) is tried first. +`{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 Binary = Patch {0, 1} Binary. - # selfにはインスタンスが格納される。この例では0か1のどちらか。 - # selfを書き換えたい場合、型名、メソッド名に!を付けなければならない。 + # self contains an instance. In this example, either 0 or 1. + # If you want to rewrite self, you must append ! must be added to the type name and method name. is_zero(self) = match self: 0 -> True - 1 -> False # _ -> Falseとしてもよい + 1 -> False # You can also use _ -> False is_one(self) = not self.is_zero() to_bool(self) = match self: 0 -> False 1 -> True ``` -以下代码可能是(尽管是内置定义的)。如代码中所示,下面是一个类型的示例,该类型实际上可以重写。 - +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 Binary! = Patch {0, 1}! -Binary!. +Binary! switch! ref! self = match! self: 0 => self = 1 1 => self = 0 @@ -194,27 +197,27 @@ b.switch!() print! b # => 0 ``` -## 结构(未命名) - +## Structure type (anonymous type) ```erg Binary = {0, 1} ``` -在上面的代码中,是元素的类型,其中是元素的类型。也可以说是既有又有类型的子类型。像这样的对象本身就是一个类型,可以像上面那样代入变量使用,也可以不代入变量使用。这种类型称为结构类型。与类(记名型)对比,强调作为后者使用时,也称为无名型。像这样的结构类型称为枚举类型,其他类型包括区间类型和记录类型。 +`Binary` in the above code is a type whose elements are `0` and `1`. It is also a subtype of the `Int` type, which has both `0` and `1`. +An object like `{}` is itself a type and can be used with or without assignment to a variable as above. +Such types are called structural types. When we want to emphasize its use as the latter in contrast to a class (named type), it is also called an unnamed type. A structural type such as `{0, 1}` is called an enumerated type, and there are also interval types, record types, and so on. -### 类型同一性 - -不能像下面这样指定。被解释为指的是不同的东西。例如,都是,但不能相加。 +### Type Identity +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 add l: Add, r: Add = - l + r # TypeError: there is no implementation of `_+_`: |T, U <: Add| (T, U) -> + 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 ... |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 index 1ac552b4..3a270717 100644 --- a/doc/zh_CN/syntax/type/02_basic.md +++ b/doc/zh_CN/syntax/type/02_basic.md @@ -1,85 +1,78 @@ -# 类型的基本语法 +# Basic syntax for types -## 类型指定 - -Erg 在之后指定变量类型,如下所示。也可以在赋值的同时进行。 +## Type specification +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 -i: Int # 声明从现在开始使用的变量 i 为 Int 类型 +i: Int # Declare the variable i to be of type Int i: Int = 1 j = 1 # type specification can be omitted ``` -也可以为常规表达式指定类型。 - +You can also specify a type for ordinary expressions. ```erg i = 1: Int 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 -# 参数类型说明 +# Type specification for parameters f x, y: Array Int = ... T X, Y: Array Int = ... ``` -注意,在上述情况下,都是。 - +Note that in the above case, `x, y` are both `Array Int`. ```erg -# 大写变量值必须是常量表达式 +# 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 g v: [T; _] = ... ``` -但是,请注意,如果在指定类型的位置指定,则意味着。 - +Note, however, `_` at a type specification implies `Object`. ```erg f x: _, y: Int = x + y # TypeError: + is not implemented between Object and Int ``` -## 子类型指定 +## Subtype specification -除了使用(类型声明运算符)指定类型与表达式之间的关系外,Erg 还使用(子类型声明运算符)指定类型之间的关系。的左边只能是类。使用等比较结构类型。 - -它通常用于子程序或类型定义,而不是简单的变量。 +In addition to the `:` (type declaration operator), Erg also allows you to specify the relationship between types by using `<:` (partial type declaration operator). +The left side of `<:` can only specify a class. Use `Subtypeof` or similar operators to compare structural types. +This is also often used when defining subroutines or types, rather than simply specifying variables. ```erg -# 部分输入参数 +# Subtype specification of an argument f X <: T = ... -# 请求属性子类型(要求 .Iterator 属性是 Iterator 类型的子类型) +# Subtype specification of the required attribute (.Iterator attribute is required to be a subtype of type Iterator) Iterable T = Trait { - .Iterator = {Iterator} # == {I | I <: Iterator} + .Iterator = {Iterator} # {Iterator} == {I: Type | I <: Iterator} .iter = Self.() -> Self.Iterator T ... } ``` -还可以在定义类时指定子类型,以静态方式检查类是否为指定类型的子类型。 - +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 -# C 类是 Show 的子类型 -C = Class Object, Impl=Show -C.show self = ... # Show请求属性 +# Class C is a subtype of Show +C = Class Object, Impl := Show +C.show self = ... # Show's required attributes. ``` -也可以仅在特定情况下指定子类型。 - +You can also specify a subtype only in specific cases. ```erg K T: Eq @@ -91,18 +84,17 @@ K(Int). show self = ... ``` -建议在实现结构类型时使用子类型。由于结构部分类型的特性,在实现请求属性时,即使存在错误的拼贴或类型指定,也不会出现错误。 - +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 C = Class Object -C.shoe self = ... # Show 由于 Typo 没有实现(它只是被认为是一种独特的方法) +C.shoe self = ... # Show is not implemented due to Typo (it is considered just a unique method). ``` -## 属性定义 - -只能在模块中为托盘和类定义属性。 +## Attribute definitions +Attributes can be defined for traits and classes only in modules. ```erg C = Class() @@ -113,8 +105,7 @@ c = C.new() assert c.pub_attr == "this is public" ``` -在或后换行并缩进的语法称为批量定义(batch definition)。 - +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 C = Class() @@ -126,16 +117,15 @@ C::priv2 = ... C = Class() C. pub1 = ... - pub2 = ... + C. pub2 = ... C:: priv1 = ... priv2 = ... ``` -## 锯齿 - -可以为类型指定别名(别名)。这使你可以将长类型(如记录类型)表示为短类型。 +## Aliasing +Types can be aliased. This allows long types, such as record types, to be shortened. ```erg Id = Int @@ -144,10 +134,11 @@ IorS = Int or Str Vector = Array Int ``` -此外,在错误显示过程中,编译器应尽可能使用复杂类型(在上面的示例中,不是第一种类型的右边类型)的别名。 - -但是,每个模块最多只能有一个别名,如果有多个别名,则会出现 warning。这意味着具有不同目的的类型应重新定义为不同的类型。它还可以防止将别名附加到已有别名的类型。 +Also, when displaying errors, the compiler will use aliases for composite types (in the above example, right-hand-side types other than the first) if they are defined. +However, only one alias of the same type is allowed per module, and multiple aliases will result in a warning. +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 Id = Int @@ -161,7 +152,7 @@ IorSorB = IorS or Bool IorSorB_ = Int or Str or Bool # TypeWarning: duplicate aliases: IorSorB and IorSorB_ Point2D = {x = Int; y = Int} -Point3D = {...Point2D; z = Int} +Point3D = {.... Point2D; z = Int} Point = {x = Int; y = Int; z = Int} # TypeWarning: duplicate aliases: Point3D and Point ``` diff --git a/doc/zh_CN/syntax/type/03_trait.md b/doc/zh_CN/syntax/type/03_trait.md index eda6c0b7..9fcf79b0 100644 --- a/doc/zh_CN/syntax/type/03_trait.md +++ b/doc/zh_CN/syntax/type/03_trait.md @@ -1,16 +1,16 @@ -# TRAIT - -TRAIT 是一种记名类型,它将类型属性请求添加到记录类型中。它类似于 Python 中的抽象基类(Abstract Base Class,ABC),但具有代数运算能力。 +# Trait +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 Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int} ``` -TRAIT不区分属性和方法。 - -请注意,TRAIT只能进行声明,而不能进行实现(实现是通过以下称为修补程序的功能实现的)。你可以检查 TRAIT 是否在类中以子类型实现。 +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 Point2D <: Norm @@ -18,16 +18,14 @@ Point2D = Class {.x = Int; .y = Int} Point2D.norm self = self.x**2 + self.y**2 ``` -未实现请求属性将导致错误。 - +Error if the required attributes are not implemented. ```erg Point2D <: Norm # TypeError: Point2D is not a subtype of Norm Point2D = Class {.x = Int; .y = Int} ``` -与结构类型一样,Trait 可以应用合并,替换和排除操作(e.g.)。这种方式形成的TRAIT称为即时TRAIT。 - +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 T = Trait {.x = Int} @@ -36,47 +34,46 @@ 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) assert Structural(W) == Structural(T.replace {.x = Ratio}) ``` -TRAIT 也是一种类型,因此也可以用于常规类型指定。 - +Trait is also a type, so it can be used for normal type specification. ```erg points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)] -assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25] +assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25]. ``` -## TRAIT包容 - -扩展运算符允许你定义一个包含高级类型的 TRAIT 的 TRAIT。这称为TRAIT的。在下面的示例中,包含。这对应于类中的继承(Inheritance),但不同于继承,可以通过组合来指定多个基本类型。根据排除一部分的TRAIT也OK。 +## Trait inclusion +The expansion operator `...` allows you to define a trait that contains a certain trait as a supertype. This is called the __subsumption__ of a trait. +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 Add R = Trait { .AddO = Type - .`_+_` = Self.(R) -> Self.AddO + . `_+_` = Self.(R) -> Self.AddO } -ClosedAdd = Subsume Add(Self) + Sub R = Trait { .SubO = Type - .`_-_` = Self.(R) -> O + . `_-_` = Self.(R) -> Self.SubO } -ClosedSub = Subsume Sub(Self) -ClosedAddSub = Subsume ClosedAdd and ClosedSub + +BinAddSub = Subsume Add(Self) and Sub(Self) ``` -## 结构TRAIT - -TRAIT可以结构化。 +## Structural Traits +Traits can be structured. ```erg SAdd = Structural Trait { - .`_+_` = Self.(Self) -> Self + . `_+_` = Self.(Self) -> Self } -# |A <: SAdd|は省略できない +# |A <: SAdd| cannot be omitted add|A <: SAdd| x, y: A = x.`_+_` y C = Class {i = Int} @@ -87,14 +84,14 @@ C. 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 Add = Trait { .`_+_` = Self.(Self) -> Self } -# |A <: Add|は省略できる +# |A <: Add| can be omitted add|A <: Add| x, y: A = x.`_+_` y C = Class {i = Int} @@ -102,72 +99,69 @@ C. new i = Self.__new__ {i;} `_+_` self, other: Self = Self.new {i = self::i + other::i} -add C.new(1), C.new(2) # TypeError: C is not subclass of Add +add C.new(1), C.new(2) # TypeError: C is not a subclass of Add # hint: inherit or patch 'Add' ``` -结构TRAIT可以没有这种实现的声明,但替代推理不起作用。使用时必须指定类型。 +Structural traits do not need to be declared for this implementation, but instead type inference does not work. Type specification is required for use. -## 依赖项 - -TRAIT可以采取自变量。这与依赖关系相同。 +## Polymorphic Traits +Traits can take parameters. This is the same as for polymorphic types. ```erg Mapper T: Type = Trait { - .MapIter = {Iterator} - .map = Self(T).(T -> U) -> Self.MapIter U + .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"] +assert [1, 2, 3].iter().map(x -> "{x}").collect(Array) == ["1", "2", "3"]. ``` -## TRAIT中的覆盖 - -派生的 TRAIT 可以覆盖基础 TRAIT 的类型定义。在这种情况下,要覆盖的方法类型必须是基础方法类型的子类型。 +## Override in Trait +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 -# `Self.(R) -> O`は`Self.(R) -> O or Panic`の部分型 +# `Self.(R) -> O` is a subtype of ``Self.(R) -> O or Panic Div R, O: Type = Trait { - .`/` = Self.(R) -> O or Panic + . `/` = Self.(R) -> O or Panic } SafeDiv R, O = Subsume Div, { @Override - .`/` = Self.(R) -> O + . `/` = Self.(R) -> O } ``` -## 实现和解决 API 重复任务 - -实际的,的定义是这样的。 +## Implementing and resolving duplicate traits in the API +The actual definitions of `Add`, `Sub`, and `Mul` look like this. ```erg Add R = Trait { .Output = Type - .`_+_` = Self.(R) -> .Output + . `_+_` = Self.(R) -> .Output } Sub R = Trait { .Output = Type - .`_-_` = Self.(R) -> .Output + . `_-_` = Self.(R) -> .Output } Mul R = Trait { .Output = Type - .`*` = Self.(R) -> .Output + . `*` = Self.(R) -> .Output } ``` -名为的变量具有重复的名称。如果要同时实现多个托盘,请指定。 - +`.Output` is duplicated. If you want to implement these multiple traits at the same time, specify the following. ```erg P = Class {.x = Int; .y = Int} -# P|Self <: Add(P)|はP|<: Add(P)|に省略可能 +# P|Self <: Add(P)| can be abbreviated to P|<: Add(P)| P|Self <: Add(P)|. Output = P `_+_` self, other = P.new {.x = self.x + other.x; .y = self.y + other.y} @@ -176,17 +170,17 @@ P|Self <: Mul(Int)|. `*` self, other = P.new {.x = self.x * other; .y = self.y * other} ``` -以这种方式实现的重复 API 在使用时通常是类型推理的,但也可以通过使用显式类型来解决。 - +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 -print! P.Output # TypeError: ambiguous type resolution +print! P.Output # TypeError: ambiguous type print! P|<: Mul(Int)|.Output # ``` -## Appendix:Rust 与TRAIT的区别 +## Appendix: Differences from Rust traits -Erg 的TRAIT忠于提出的TRAIT。为了能够进行代数运算,TRAIT没有实现,设计了必要时打补丁的设计。 +Erg's trait is faithful to the one proposed by [Schärli et al.](https://www.ptidej.net/courses/ift6251/fall06/presentations/061122/061122.doc.pdf). +In order to allow algebraic operations, traits are designed to be unable to have method implementations directory, but can be patched if necessary.

Previous | Next diff --git a/doc/zh_CN/syntax/type/04_class.md b/doc/zh_CN/syntax/type/04_class.md index 8b118e19..f582937a 100644 --- a/doc/zh_CN/syntax/type/04_class.md +++ b/doc/zh_CN/syntax/type/04_class.md @@ -1,11 +1,11 @@ # Class -Erg 中的类通常可以生成其自身的元素(实例)。下面是一个简单类的示例。 - +A class in Erg is roughly a type that can create its own elements (instances). +Here is an example of a simple class. ```erg Person = Class {.name = Str; .age = Nat} -# .newが定義されなかった場合、自動で`Person.new = Person::__new__`となります +# If `.new` is not defined, then Erg will create `Person.new = Person::__new__` Person. new name, age = Self::__new__ {.name = name; .age = age} @@ -14,21 +14,23 @@ print! john # print! classof(john) # Person ``` -给出的类型(通常为记录)称为要求类型(在本例中为)。可以在中生成实例。只是一条记录,但它通过转换为实例。生成此类实例的子例程称为构造函数。上面的类定义了方法,以便可以省略字段名等。 - -请注意,如下所示不换行定义会导致语法错误。 +The type given to `Class` (normally a record type) is called the requirement type (in this case `{.name = Str; .age = Nat}`). +Instances can be created with `::__new__ { = ; ...}` can be created with. +`{.name = "John Smith"; .age = 25}` is just a record, but it is converted to a `Person` instance by passing `Person.new`. +The subroutine that creates such an instance is called a constructor. +In the class above, the `.new` method is defined so that field names, etc. can be omitted. +Note that the following definition without line breaks will result in a syntax error. ```erg Person.new name, age = ... # SyntaxError: cannot define attributes directly on an object ``` -> :这是最近添加的规范,在以后的文档中可能不受保护。如果发现就报告。 +> __Warning__: This is a recently added specification and may not be followed in subsequent documents. If you find it, please report it. -## 实例属性、类属性 - -在 Python 和其他语言中,很多情况下都是在块端定义实例属性,如下所示,这种写法在 Erg 中是另外一个意思,需要注意。 +## Instance and class attributes +In Python and other languages, instance attributes are often defined on the block side as follows, but note that such writing has a different meaning in Erg. ```python # Python @@ -37,28 +39,27 @@ class Person: age: int ``` - ```erg -# Ergでこの書き方はクラス属性の宣言を意味する(インスタンス属性ではない) +# In Erg, this notation implies the declaration of a class attribute (not an instance attribute) Person = Class() Person. name: Str age: Int ``` - ```erg -# 上のPythonコードに対応するErgコード +# Erg code for the Python code above Person = Class { .name = Str .age = Nat } ``` -元素属性(在记录中定义的属性)和类型属性(在类中特别称为实例属性/类属性)是完全不同的。类型属性是类型本身所具有的属性。类型的要素在自身中没有目标属性时参照类型属性。要素属性是要素直接具有的固有属性。为什么要做这样的划分?如果全部都是要素属性,则在生成对象时需要复制、初始化所有属性,这是因为效率低下。另外,这样分开的话,“这个属性是共用的”“这个属性是分开拥有的”等作用就会明确。 - -用下面的例子来说明。由于这一属性在所有实例中都是共通的,所以作为类属性更为自然。但是,由于这一属性应该是各个实例各自持有的,所以应该是实例属性。 +Element attributes (attributes defined in a record) and type attributes (also called instance/class attributes, especially in the case of classes) are completely different things. Type attributes are attributes of the type itself. An element of a type refers to a type attribute when it does not have the desired attribute in itself. An element attribute is a unique attribute directly possessed by the element. +Why is this distinction made? If all attributes were element attributes, it would be inefficient to duplicate and initialize all attributes when the object is created. +In addition, dividing the attributes in this way clarifies roles such as "this attribute is shared" and "this attribute is held separately". +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 Person = Class {name = Str} @@ -82,35 +83,39 @@ alice.describe() # species: human 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 C = Class {.i = Int} -C. - i = 1 # AttributeError: `.i` is already defined in instance fields +C.i = 1 # AttributeError: `.i` is already defined in instance fields ``` ## Class, Type -请注意,类类型与不同。只有一个类可以从中生成。可以使用获取对象所属的类。与此相对,有无数个类型。例如,。但是,最小的类型可以是一个,在这种情况下是。可以通过获取对象的类型。这是一个编译时函数,顾名思义,它是在编译时计算的。除了类方法外,对象还可以使用修补程序方法。Erg 不能添加类方法,但可以使用进行扩展。 - -也可以继承现有的类(对于类)。表示继承。左边的类型称为派生类,右边的参数类型称为基类。 +Note that the class and type of `1` are different. +There is only one class `Int` that is the generator of `1`. You can get the class to which an object belongs by `classof(obj)` or `obj.__class__`. +In contrast, there are countless types of `1`. For example, `{1}, {0, 1}, 0..12, Nat, Int, Num`. +However, the smallest type can be defined as a single type, in this case `{1}`. The type to which an object belongs can be obtained with `Typeof(obj)`. This is a compile-time function. +Objects can use patch methods as well as class methods. +Erg does not allow you to add class methods, but you can use [patch](./07_patch.md) to extend a class. +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 MyStr = Inherit Str -# other: StrとしておけばMyStrでもOK +# other: You can use MyStr if you set ``other: Str''. MyStr. `-` self, other: Str = self.replace other, "" abc = MyStr.new("abc") -# ここの比較はアップキャストが入る +# Comparison here gets an upcast assert abc - "b" == "ac" ``` -与 Python 不同,定义的 Erg 类缺省为(不可继承)。要使其可继承,必须为类指定装饰器。是可继承类之一。 - +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 MyStr = Inherit Str # OK @@ -121,10 +126,10 @@ InheritableMyStr = Inherit Str MyStr3 = Inherit InheritableMyStr # OK ``` -和在实际应用中大致等效。一般使用后者。 - -类的等价机制不同于类型。类型根据结构确定等价性。 +`Inherit Object` and `Class()` are almost equivalent in practice. The latter is generally used. +Classes have a different equivalence checking mechanism than types. +Types are equivalence tested based on their structure. ```erg Person = {.name = Str; .age = Nat} @@ -133,8 +138,7 @@ Human = {.name = Str; .age = Nat} assert Person == Human ``` -类没有定义等价关系。 - +class has no equivalence relation defined. ```erg Person = Class {.name = Str; .age = Nat} @@ -143,10 +147,9 @@ Human = Class {.name = Str; .age = Nat} Person == Human # TypeError: cannot compare classes ``` -## 与结构类型的区别 - -类是一种可以生成自己元素的类型,但这并不是一个严格的描述。因为实际上,记录类型 + 修补程序也可以做到这一点。 +## Difference from structural types +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 Person = {.name = Str; .age = Nat} @@ -157,18 +160,19 @@ PersonImpl. john = Person.new("John Smith", 25) ``` -使用类有四个好处。一是检查构造函数的合法性,二是性能高,三是可以使用记名部分类型 (NST),四是可以继承和覆盖。 +There are four advantages to using classes. +The first is that the constructor is validity checked, the second is that it is more performant, the third is that you can use notational subtypes (NSTs), and the fourth is that you can inherit and override. -我们已经看到记录类型 + 修补程序也可以定义构造函数(类似),但这当然不是合法的构造函数。因为你可以返回一个自称但完全不相关的对象。对于类,将静态检查是否生成满足要求的对象。 +We saw earlier that record type + patch can also define a constructor (of sorts), but this is of course not a legitimate constructor. This is of course not a legitimate constructor, because it can return a completely unrelated object even if it calls itself `.new`. In the case of a class, `.new` is statically checked to see if it produces an object that satisfies the requirements. ~ -类类型检查只需查看对象的属性即可完成。因此,检查对象是否属于该类型的速度较快。 +Type checking for classes is simply a matter of checking the object's `. __class__` attribute of the object. So it is fast to check if an object belongs to a type. ~ -Erg 在类中提供了 NST。NST 的优点包括强健性。在编写大型程序时,对象的结构仍然会偶然匹配。 - +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 Dog = {.name = Str; .age = Nat} @@ -185,49 +189,49 @@ john = {.name = "John Smith"; .age = 20} 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 Dog = Class {.name = Str; .age = Nat} -Dog. - bark = log "Yelp!" +Dog.bark = log "Yelp!" ... Person = Class {.name = Str; .age = Nat} -Person. - greet self = log "Hello, my name is {self.name}." +Person.greet self = log "Hello, my name is {self.name}." john = Person.new {.name = "John Smith"; .age = 20} -john.bark() # TypeError: `Person` object has no method `.bark` +john.bark() # TypeError: `Person` object has no method `.bark`. ``` -另一个特征是,通过修补程序添加的类型属性是虚拟的,而不是作为实体保存在要实现的类中。也就是说,和是与兼容的类型可以访问(在编译时绑定)的对象,而不是在中定义的对象。相反,类属性由类自己维护。因此,结构相同但不具有继承关系的类无法访问。 - +Another feature is that the type attributes added by the patch are virtual and are not held as entities by the implementing class. +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 C = Class {i = Int} C. foo self = ... -print! dir(C) # ["foo", ...] +print! dir(C) # ["foo", ...]. T = Patch {i = Int} T. x = 1 bar self = ... -print! dir(T) # ["bar", "x", ...] +print! dir(T) # ["bar", "x", ...]. assert T.x == 1 assert {i = 1}.x == 1 print! T.bar # -{i = Int}.bar # TypeError: Record({i = Int}) has no method `.bar` -C.bar # TypeError: C has no method `.bar` +{i = Int}.bar # TypeError: Record({i = Int}) has no method `.bar`. +C.bar # TypeError: C has no method `.bar` print! print! {i = 1}.bar # -print! C.new({i = 1}).bar # +C.new({i = 1}).bar # ``` -## 与数据类的区别 - -类可以是通过请求记录的常规类,也可以是继承记录()的数据类。数据类继承了记录的功能,可以分解赋值,缺省情况下实现。相反,如果你想定义自己的等价关系和格式显示,则可以使用常规类。 +## Difference from data class +There are two types of classes: regular classes, which are record classes through `Class`, and data classes, which inherit (`Inherit`) from record classes. +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 C = Class {i = Int} @@ -237,16 +241,15 @@ print! c # c == d # TypeError: `==` is not implemented for `C` D = Inherit {i = Int} -e = D::{i = 1} # e = D.new {i = 1}と同じ -f = D::{i = 2} -print! e # D(i = 1) -assert e != f +e = D.new {i = 1} +f = D.new {i = 2} +print! e # D{i = 1} +assert e ! = f ``` ## Enum Class -提供以帮助定义 Or 类型的类。 - +To facilitate defining classes of type `Or`, an `Enum` is provided. ```erg X = Class() @@ -254,8 +257,8 @@ Y = Class() 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 x1 = XorY.new X.new() @@ -263,14 +266,13 @@ x2 = XorY.cons(X)() assert x1 == x2 ``` -## 包含关系 - -类是需求类型的子类型。你可以使用要求类型的方法(包括修补程序方法)。 +## Class Relationships +A class is a subtype of a requirement type. methods (including patch methods) of the requirement type can be used in the class. ```erg T = Trait {.foo = Foo} -C = Class(..., Impl: T) +C = Class(... , impl: T) C. foo = foo bar x = ... @@ -282,4 +284,4 @@ assert T.foo == Foo

Previous | Next -

\ No newline at end of file +

diff --git a/doc/zh_CN/syntax/type/05_inheritance.md b/doc/zh_CN/syntax/type/05_inheritance.md index 3c78393d..bb8c78f1 100644 --- a/doc/zh_CN/syntax/type/05_inheritance.md +++ b/doc/zh_CN/syntax/type/05_inheritance.md @@ -1,7 +1,7 @@ -# 继承(Inheritance) - -通过继承,你可以定义一个新类,该新类将添加或特定于现有类。继承类似于trait中的包容。继承的类将成为原始类的子类型。 +# Inheritance +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 NewInt = Inherit Int @@ -12,10 +12,9 @@ assert NewInt.new(1).plus1() == 2 assert NewInt.new(1) + NewInt.new(1) == 2 ``` -如果你希望新定义的类是可继承类,则必须指定装饰器。 - -可选参数允许你具有其他实例属性。但是,不能为值类添加实例属性。 +If you want the newly defined class to be inheritable, you must give it the `Inheritable` decorator. +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 @Inheritable @@ -28,28 +27,26 @@ alice = Student.new {name = "Alice", id = 123} MailAddress = Inherit Str, additional: {owner = Str} # TypeError: instance variables cannot be added to a value class ``` -Erg 中例外的是不能继承型的设计。因为是绝对不能生成实例的特殊类。 +Erg is exceptionally designed not to allow inheritance of type ``Never``. Erg is exceptionally designed not to allow inheritance of `Never` type, because `Never` is a unique class that can never be instantiated. -## 枚举类继承 - -也可以继承以为类的枚举类。在这种情况下,你可以通过指定选项参数来删除任何选项(使用可以选择多个选项)。仍不能添加。添加选择的类不是原始类的子类型。 +## Inheritance of Enumerated Classes +[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 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 +Number.abs(self): Float = + match self: + i: Int -> i.abs().into Float + f: Float -> f.abs() + c: Complex -> c.abs().into Float -# matchの選択肢でc: Complexは現れ得ない +# c: Complex cannot appear in match choices RealNumber = Inherit Number, Excluding: Complex ``` -同样,也可以指定。 - +Similarly, [refinement type](./12_refinement.md) can also be specified. ```erg Months = Class 0..12 @@ -59,53 +56,56 @@ StrMoreThan3 = Class StrWithLen N | N >= 3 StrMoreThan4 = Inherit StrMoreThan3, Excluding: StrWithLen N | N == 3 ``` -## 覆盖 +## Overriding -与修补程序相同,你可以在原始类型中添加新方法,但可以进一步“覆盖”类。覆盖称为覆盖。覆盖必须满足三个条件。首先,默认情况下,覆盖是错误的,因此必须添加装饰器。此外,覆盖不能更改方法类型。必须是原始类型的子类型。如果要覆盖其他方法引用的方法,则必须覆盖所有引用的方法。 +The class is the same as the patch in that new methods can be added to the original type, but the class can be further "overridden". +This overriding is called override. To override, three conditions must be met. +First, the override must have an `Override` decorator because by default it will result in an error. +In addition, the override cannot change the type of the method. It must be a subtype of the original type. +And if you override a method that is referenced by another method, you must also override all referenced methods. -为什么要有这样的条件呢?这是因为覆盖不仅可以改变一个方法的行为,还可以影响另一个方法的行为。 +Why is this condition necessary? It is because overriding does not merely change the behavior of one method, but may affect the behavior of another method. -首先,从第一个条件开始解说。这是为了防止“意外覆盖”。这意味着必须在装饰器中显示,以防止派生类中新定义的方法的名称碰巧与基类冲突。 +Let's start with the first condition. This condition is to prevent "accidental overrides. +In other words, the `Override` decorator must be used to prevent the name of a newly defined method in a derived class from conflicting with the name of the base class. -接下来,我们考虑第二个条件。这是为了保持类型的完整性。派生类是基类的子类型,因此其行为也必须与基类兼容。 - -最后,考虑第三个条件。这个条件是 Erg 特有的,在其他面向对象的语言中并不常见,但这也是为了安全起见。看看没有这个的时候会发生什么不好的事情。 +Next, consider the second condition. This is for type consistency. Since the derived class is a subtype of the base class, its behavior must also be compatible with that of the base class. +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 # Bad example @Inheritable Base! = Class {x = Int!} -Base!. +Base! f! ref! self = print! self::x self.g!() g! ref! self = self::x.update! x -> x + 1 Inherited! = Inherit Base! -Inherited!. +Inherited! @Override g! ref! self = self.f!() # InfiniteRecursionWarning: This code falls into an infinite loop # OverrideError: method `.g` is referenced by `.f` but not overridden ``` -继承类覆盖方法并将处理转发到。但是,基类的方法将其处理转发到,从而导致无限循环。类中是一个没有问题的方法,但由于被覆盖而被意外地使用,并被破坏。 - -因此,通常需要重写所有可能受覆盖影响的方法。Erg 将这一规则纳入规范。 +In the inherited class `Inherited!`, the `.g!` method is overridden to transfer processing to `.f!`. However, the `.f!` method in the base class transfers its processing to `.g!`, resulting in an infinite loop. `.f` was a problem-free method in the `Base!` class, but it was used in an unexpected way by the override, and it was broken. +Erg has built this rule into the specification. ```erg -# OK +# OK. @Inheritable Base! = Class {x = Int!} -Base!. +Base! f! ref! self = print! self::x self.g!() g! ref! self = self::x.update! x -> x + 1 Inherited! = Inherit Base! -Inherited!. +Inherited! @Override f! ref! self = print! self::x @@ -114,97 +114,100 @@ Inherited!. g! ref! self = self.f!() ``` -但这一规范并不能完全解决覆盖问题。编译器无法检测覆盖是否修复了问题。创建派生类的程序员有责任修改替代的影响。应尽可能定义别名方法。 +However, this specification does not completely solve the override problem. However, this specification does not completely solve the override problem, since the compiler cannot detect if the override fixes the problem. +It is the responsibility of the programmer creating the derived class to correct the effects of the override. Whenever possible, try to define an alias method. -### 替换trait(类似于) +### Replacing Traits (or what looks like it) -你不能在继承过程中替换 TRAIT,但有一个示例似乎是这样做的。 - -例如,(实现)的子类型似乎正在重新实现。 +Although it is not possible to replace traits at inheritance time, there are examples that appear to do so. +For example, `Int`, a subtype of `Real` (which implements `Add()`), appears to reimplement `Add()`. ```erg -Int = Class ..., Impl := Add() and ... +Int = Class ... , Impl := Add() and ... ``` -但实际上,中的的缩写,只是用覆盖。两者是不同的trait(,因此)。 +But in fact `Add()` in `Real` stands for `Add(Real, Real)`, and in `Int` it is just overwritten by `Add(Int, Int)`. +They are two different traits (`Add` is a [covariate](./advanced/variance.md), so `Add(Real, Real) :> Add(Int, Int)`). -## 禁止多重继承 - -Erg 不允许常规类之间的 Intersection、Diff 或 Complement。 +## Multiple Inheritance +Erg does not allow intersection, diff, and complement between normal classes. ```erg Int and Str # TypeError: cannot unite classes ``` -此规则不允许继承多个类,即多重继承。 - +This rule prevents inheritance from multiple classes, i.e., multiple inheritance. ```erg IntAndStr = Inherit Int and Str # SyntaxError: multiple inheritance of classes is not allowed ``` -但是,可以使用 Python 多重继承类。 +However, multiple inherited Python classes can be used. -## 禁止多层继承 +## Multi-layer (multi-level) Inheritance -Erg 继承也禁止多层继承。也就是说,你不能定义继承的类,也不能定义继承的类。但是,继承的(Inheritable)类除外。 +Erg inheritance also prohibits multi-layer inheritance. That is, you cannot define a class that inherits from another class. +Inheritable classes that inherit from an `Object` may exceptionally inherit. -此外,Python 多层继承类仍然可用。 +Also in this case, Python's multi-layered inherited classes can be used. -## 禁止改写源属性 +## Rewriting Inherited Attributes -Erg 无法重写源属性。这有两个意思。首先,对继承的类属性执行更新操作。不仅不能重新赋值,也不能通过方法进行更新。 +Erg does not allow rewriting the attributes inherited from the base class. This has two implications. -覆盖与重写不同,因为它是一种使用更特定的方法进行覆盖的操作。替代也必须使用兼容类型进行替换。 +The first is an update operation on the inherited source class attribute. It cannot be reassigned, nor can it be updated by the `.update!` method, for example. +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 @Inheritable Base! = Class {.pub = !Int; pri = !Int} -Base!. +Base! var = !1 inc_pub! ref! self = self.pub.update! p -> p + 1 -Inherited! = Inherit Base!: -Inherited!. +Inherited! = Inherit Base! +Inherited! var.update! v -> v + 1 # TypeError: can't update base class variables @Override inc_pub! ref! self = self.pub + 1 - # OverrideError: `.inc_pub!` must be subtype of `Self!.() => ()` + # OverrideError: `.inc_pub!` must be subtype of `Self! () => ()` ``` -第二种是对从其继承的(可变)实例属性执行更新操作。这也是禁止的。只能从基类提供的方法更新基类的实例属性。无论属性的可视性如何,都不能直接更新。但是可以读取。 - +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 @Inheritable Base! = Class {.pub = !Int; pri = !Int} -Base!. +Base! inc_pub! ref! self = self.pub.update! p -> p + 1 inc_pri! ref! self = self::pri.update! p -> p + 1 -Inherited! = Inherit Base!: -Inherited!. +self = self.pub.update! +Inherited! # OK add2_pub! ref! self = self.inc_pub!() self.inc_pub!() - # NG, `Child` cannot touch `self.pub` and `self::pri` + # NG, `Child` cannot touch `self.pub` and `self::pri`. add2_pub! ref! self = self.pub.update! p -> p + 2 ``` -最后,Erg 只能继承添加新属性和覆盖基类方法。 +After all, Erg inheritance can only add new attributes and override base class methods. -## 继承用法 +## Usage of Inheritance -如果正确使用,继承是一个强大的功能,但另一方面,它也有一个缺点,即类之间的依赖关系容易变得复杂,特别是在使用多重继承和多层继承时,这种趋势更为明显。依赖项的复杂性可能会降低代码的可维护性。Erg 禁止多重继承和多层继承是为了降低这种风险,而引入类修补功能是为了在继承“添加功能”的同时减少依赖关系的复杂性。 - -那么反过来应该用继承的地方在哪里呢?一个指标是如果“想要基类的语义亚型”。Erg 由类型系统自动确定子类型的一部分(如果 Int 大于或等于 e.g.0,则为 Nat)。但是,例如,仅依靠 Erg 类型系统来创建“表示有效电子邮件地址的字符串类型”是很困难的。应该对普通字符串进行验证。然后,我们希望为验证通过的字符串对象添加一个“保证书”。这相当于向下转换到继承类。将下铸为与验证字符串是否为正确的电子邮件地址格式一一对应。 +While inheritance is a powerful feature when used correctly, it also has the drawback that it tends to complicate class dependencies, especially when multiple or multi-layer inheritance is used. Complicated dependencies can reduce code maintainability. +The reason Erg prohibits multiple and multi-layer inheritance is to reduce this risk, and the class patch feature was introduced to reduce the complexity of dependencies while retaining the "add functionality" aspect of inheritance. +So, conversely, where should inheritance be used? One indicator is when "semantic subtypes of the base class are desired. +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 ValidMailAddressStr = Inherit Str @@ -220,8 +223,11 @@ valid = ValidMailAddressStr.init s2 valid: ValidMailAddressStr # assurance that it is in the correct email address format ``` -另一个指标是“记名的多相 = 想实现多态”的情况。例如,下面定义的过程接受任何类型为的对象。但显然,应用类型对象是错误的。因此,我们将参数类型设置为类。在这种情况下,只有对象和继承它的类对象作为参数。这样更保守,不用承担不必要的更多责任。 - +Another indicator is when you want to achieve a nominal polymorphism. +For example, the `greet!` procedure defined below will accept any object of type `Named`. +But obviously it is wrong to apply a `Dog` type object. So we will use the `Person` class for the argument type. +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 Named = {name = Str; ...} diff --git a/doc/zh_CN/syntax/type/06_nst_vs_sst.md b/doc/zh_CN/syntax/type/06_nst_vs_sst.md index 950009c4..8cc422cc 100644 --- a/doc/zh_CN/syntax/type/06_nst_vs_sst.md +++ b/doc/zh_CN/syntax/type/06_nst_vs_sst.md @@ -1,5 +1,4 @@ -# 记名的部分型 vs.构造的部分型 - +# Nominal Subtyping vs. Structural Subtyping ```erg Months = 0..12 @@ -9,9 +8,9 @@ MonthsClass = Class Months MonthsClass. name self = match self: - 1 -> "January" - 2 -> "February" - 3 -> "March" + 1 -> "january" + 2 -> "february" + 3 -> "march" ... # SST @@ -28,15 +27,16 @@ assert 12 in Months assert 2.name() == "February" assert not 12 in MonthsClass assert MonthsClass.new(12) in MonthsClass -# クラスでラップしても構造型は使える +# It can use structural types, even though wrapped in a class. assert MonthsClass.new(12) in Months -# 両方ある場合クラスメソッドが優先 +# If both exist, class methods take priority. assert MonthsClass.new(2).name() == "february" ``` -## 到底用 NST 还是 SST 好呢? +## In The End, Which Should I Use, NST or SST? -如果无法确定该选项,建议使用 NST。SST 要求具备编写不破坏任何用例的代码的抽象能力。最好的抽象可以提高工作效率,但错误的抽象(__ 外观通用性 __)会适得其反。NST 可以降低这种风险,而不是抽象性。如果你不是库的实现者,你可以只在 NST 中编码。 +If you cannot decide which one to use, our recommendation is NST. +SST requires abstraction skills to write code that does not break down in any use case. Good abstraction can lead to high productivity, but wrong abstraction (commonality by appearances) can lead to counterproductive results. (NSTs can reduce this risk by deliberately keeping abstraction to a minimum. If you are not a library implementor, it is not a bad idea to code only with NSTs.

Previous | Next diff --git a/doc/zh_CN/syntax/type/07_patch.md b/doc/zh_CN/syntax/type/07_patch.md index 395adf29..79795524 100644 --- a/doc/zh_CN/syntax/type/07_patch.md +++ b/doc/zh_CN/syntax/type/07_patch.md @@ -1,7 +1,8 @@ # Patch -Erg 不允许修改现有类型类。不能在类中定义额外的方法,而是专门化(specialization,将声明为多相的类型单相化并定义专用方法的功能。C++ 等也不能使用。但是,在许多情况下,你希望将功能添加到现有类型类中,而修补程序就是实现这一目标的方法。 - +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 StrReverse = Patch Str @@ -11,33 +12,34 @@ StrReverse. assert "abc".reverse() == "cba" ``` -修补程序的名称最好是要添加的主要功能的直接描述。这样,要修补的类型()的对象就可以使用修补方法()。实际上,不是方法,而是添加到中的方法。 - -但是,修补程序方法的优先级低于记名(类)方法,因此不能覆盖(覆盖)现有类的方法。 +The name of the patch should be a straightforward description of the primary functionality to be added. +This way, objects of the type being patched (`Str`) can use the methods of the patch (`StrReverse`). +In fact, built-in method `.reverse` is not a method of `Str`, but a method added to `StrRReverse`. +However, patch methods have lower precedence than methods of the nominal type (class/trait) and cannot override methods of existing types. ```erg StrangeInt = Patch Int StrangeInt. - `_+_` = Int.`_-_` # AssignError: .`_+_` is already defined in Int + `_+_` = Int.`_-_` # AssignError: . `_+_` is already defined in Int ``` -如果要覆盖,必须继承类。但是,建议你定义一个具有不同名称的方法,而不是覆盖它。因为覆盖有一些安全限制,不是那么容易做到的。 - +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 StrangeInt = Inherit Int StrangeInt. - # オーバーライドするメソッドにはOverrideデコレータを付与する必要がある - # さらに、Int.`_+_`に依存するIntのメソッドすべてをオーバーライドする必要がある + # Overriding methods must be given Override decorators. + # In addition, you need to override all Int methods that depend on Int.`_+_`. @Override - `_+_` = Super.`_-_` # OverrideError: Int.`_+_` is referenced by ..., so these method must also be overridden + `_+_` = Super.`_-_` # OverrideError: Int.`_+_` is referenced by ... ````` , so these methods must also be overridden ``` -## 选择修补程序 - -可以为一种类型定义多个曲面片,也可以将它们组合在一起。 +## Selecting Patches +Patches can be defined for a single type, and can be grouped together. ```erg # foo.er @@ -55,10 +57,10 @@ StrToKebabCase = Patch(Str) StrToKebabCase. to_kebab_case self = ... +StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase ``` - ```erg {StrBoosterPack; ...} = import "foo" @@ -68,8 +70,7 @@ assert "to camel case".to_camel_case() == "toCamelCase" assert "to kebab case".to_kebab_case() == "to-kebab-case" ``` -如果可以定义多个修补程序,某些修补程序可能会导致重复的实现。 - +If multiple patches are defined, some of them may result in duplicate implementations. ```erg # foo.er @@ -85,26 +86,25 @@ StrReverseMk2. "hello".reverse() # PatchSelectionError: multiple choices of `.reverse`: StrReverse, StrReverseMk2 ``` -在这种情况下,可以使用相关函数格式而不是方法格式来实现唯一性。 - +In such a case, you can make it unique by using the __related function__ form instead of the method form. ```erg assert StrReverseMk2.reverse("hello") == "olleh" ``` -也可以通过选择性导入来实现唯一性。 - +You can also make it unique by selectively importing. ```erg {StrReverseMk2; ...} = import "foo" -assert StrReverseMk2.reverse("hello") == "olleh" +assert "hello".reverse() == "olleh" ``` -## 粘合面片(Glue Patch) - -修补程序还可以关联类型。将关联起来。这些面片称为“粘合面片”(Glue Patch)。由于是一个内置类型,因此用户需要一个粘合贴片来改装托盘。 +## Glue Patch +Patches can also relate types to each other. The `StrReverse` patch relates `Str` and `Reverse`. +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 Reverse = Trait { @@ -117,8 +117,9 @@ StrReverse. self.iter().rev().collect(Str) ``` -只能为一对类型和托盘定义一个粘合曲面片。这是因为,如果多个粘合贴片同时“可见”,则无法唯一确定选择哪个实现。但是,你可以在切换到其他范围(模块)时替换修补程序。 - +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 NumericStr = Inherit Str @@ -132,10 +133,9 @@ NumStrRev. # hint: `Str` (superclass of `NumericStr`) is associated with `Reverse` by `StrReverse` ``` -## Appendix:Rust 与trait的关系 - -Erg 修补程序相当于 Rust 的 impl 块(后置)。 +## Appendix: Relationship to Rust's Trait +Erg patches are the equivalent of Rust's (retrofitted) `impl` blocks. ```rust // Rust @@ -150,8 +150,7 @@ impl Reverse for String { } ``` -可以说,Rust Traitt 是 Erg Traitt 和补丁的功能的结合。这样说来,Rust 的trait听起来更方便,其实也不尽然。 - +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 # Erg @@ -165,8 +164,8 @@ StrReverse. self.iter().rev().collect(Str) ``` -Erg 将 impl 块对象化为修补程序,以便在从其他模块导入时进行选择性导入。此外,还允许在外部结构中实现外部托盘。此外,由于结构类型的不同,也不需要 dyn trait 和 impl trait 语法。 - +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 # Erg @@ -175,7 +174,6 @@ 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")]; @@ -185,10 +183,11 @@ fn iter(i: I) -> impl Iterator where I: IntoIterator { } ``` -## 全称补丁 - -你可以为特定类型定义修补程序,也可以为“常规函数类型”等定义修补程序。在这种情况下,将想要给出自由度的项作为参数(在下面的情况下为)。以这种方式定义的曲面片称为全称曲面片。正如你所看到的,全称修补程序是一个返回修补程序的函数,但它本身也可以被视为修补程序。 +## For-All Patch +A patch can be defined not only for one specific type, but also for "function types in general" and so on. +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 FnType T: Type = Patch(T -> T) @@ -198,15 +197,15 @@ FnType(T). assert (Int -> Int).type == Int ``` -## 结构补丁 +## Structural Patch -此外,还可以为满足某一结构的所有类型定义修补程序。但是,它的优先级低于记名修补程序和类方法。 - -在定义结构修补程序时,请仔细设计,因为扩展可能会导致不成立,如下所示。 +In addition, patches can be defined for any type that satisfies a certain structure. +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 -# これはStructuralにするべきではない +# This should not be `Structural` Norm = Structural Patch {x = Int; y = Int} Norm. norm self = self::x**2 + self::y**2 diff --git a/doc/zh_CN/syntax/type/08_value.md b/doc/zh_CN/syntax/type/08_value.md index bd2b4724..21db678b 100644 --- a/doc/zh_CN/syntax/type/08_value.md +++ b/doc/zh_CN/syntax/type/08_value.md @@ -1,9 +1,8 @@ -# 值类型(Value types) +# Value Type -值类型是 Erg 内置类型中可以进行编译时评估的类型,具体如下所示。 +Value types are Erg built-in types that can be evaluated at compile time, specifically: - -```erg +``` erg Value = ( Int or Nat @@ -22,17 +21,17 @@ Value = ( ) ``` -值类型的对象常量和编译时子例程称为常量表达式。 +Value-type objects, constants, and compile-time subroutines applied to them are called __constant expressions__. - -```erg +``` erg 1, 1.0, 1+2im, True, None, "aaa", [1, 2, 3], Fib(12) ``` -需要注意子程序。子程序可能是值类型,也可能不是。虽然每个子例程的实体都是一个指针,并且都是一个值,但在编译时,在常量上下文中使用非子例程并没有什么意义,因此它不是一个值类型。 +Be careful with subroutines. Subroutines may or may not be value types. +Since the substance of a subroutine is just a pointer, it can be treated as a value [1](#1), but when compiling something that is not a subroutine cannot be used in a constant context. is not a value type because it doesn't make much sense. -以后可能会添加一些类型,这些类型被归类为值类型。 +Types classified as value types may be added in the future. --- -1Erg 中的值类型一词与其他语言中的定义不同。在纯 Erg 语义学中,内存的概念不存在,因为它被放置在堆栈中,所以它是一种值类型,或者因为它是一个指针,所以它不是一种值类型,这些说法是不正确的。从根本上说,值类型是类型或其子类型。 +1 The term "value type" in Erg differs from the definition in other languages. There is no concept of memory within pure Erg semantics, and it is incorrect to state that it is a value type because it is placed on the stack, or that it is not a value type because it is actually a pointer. A value type only means that it is a `Value` type or its subtypes. [↩](#f1) diff --git a/doc/zh_CN/syntax/type/09_attributive.md b/doc/zh_CN/syntax/type/09_attributive.md index 1215574d..3098d671 100644 --- a/doc/zh_CN/syntax/type/09_attributive.md +++ b/doc/zh_CN/syntax/type/09_attributive.md @@ -1,7 +1,9 @@ -# 属性类型(Attributive Type) +# Attributive Type -属性类型是包含记录和数据类、修补程序、模块等的类型。属于属性类型的类型不是值类型。 +Attribute types are types that contain Record and Dataclass, Patch, Module, etc. +Types belonging to attribute types are not value types. -## 记录类型合并 +## Record Type Composite -合并的记录类型可以展平。例如,等于。 +It is possible to flatten Record types composited. +For example, `{... {.name = Str; .age = Nat}; ... {.name = Str; .id = Nat}}` becomes `{.name = Str; .age = Nat; .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 index 01d27148..4c71ed4f 100644 --- a/doc/zh_CN/syntax/type/10_interval.md +++ b/doc/zh_CN/syntax/type/10_interval.md @@ -1,26 +1,24 @@ # Interval Type -对象最基本的用法是用作迭代器。 - +The most basic use of `Range` objects is as iterator. ```erg for! 0..9, i => print! i ``` -请注意,与 Python 不同,最后一个数字是包含的。 - -但是,这并不是对象的唯一用途。也可以作为模具使用。这些类型称为“区间类型”(Interval type)。 +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 i: 0..10 = 2 ``` -类型与等效,类型与等效。也可以写成表示类型的任何实例。 - -也可以用作迭代器,因此可以按相反的顺序指定,如,但不能反转的方向。 +The `Nat` type is equivalent to `0..,所以在元素有限的情况下,枚举类型和区间类型本质上是等价的。 - +Since `1..7` can be rewritten as `{1, 2, 3, 4, 5, 6, 7}`, so when element is finite, the Enum types essentially equivalent the Range types. ```erg Binary! = Class {0, 1}!. @@ -24,29 +25,26 @@ b = Binary!.new !0 b.invert!() ``` -顺便一提,Erg 的枚举类型是一个包含其他语言中常见的枚举类型的概念。 - +Incidentally, Erg's Enum types are a concept that encompasses enumerative types common in other languages. ```rust // Rust enum Status { Ok, Error } ``` - ```erg # Erg Status = {"Ok", "Error"} ``` -它与 Rust 的区别在于它采用了结构子类型 (SST)。 - +The difference with Rust is that it uses a structural subtype(SST). ```rust -// StatusとExtraStatusの間にはなんの関係もない +// There is no relationship between Status and ExtraStatus. enum Status { Ok, Error } enum ExtraStatus { Ok, Error, Unknown } -// メソッドを実装可能 +// Methods can be implemented impl Status { // ... } @@ -55,26 +53,27 @@ impl ExtraStatus { } ``` - ```erg -# Status > ExtraStatusであり、Statusの要素はExtraStatusのメソッドを使える +# Status > ExtraStatus, and elements of Status can use methods of ExtraStatus. Status = Trait {"Ok", "Error"} # ... ExtraStatus = Trait {"Ok", "Error", "Unknown"} # ... ``` -还可以使用 patching 添加方法。 - -如果要显式显示包含关系,或者要向现有 Enum 类型添加选项,请使用运算符。 +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 ExtraStatus = Status or {"Unknown"} ``` -元素所属的所有类都相同的枚举类型称为“等质”(homogenous)枚举类型。缺省情况下,要求类型相同的枚举类型的类可以被视为元素所属类的子类。如果你不想这样做,则最好是包装类。 +An enumerated type in which all classes to which an element belongs are identical is called a homogenous enumerated type. +By default, a class whose requirement type is an homogeneous enumerated type can be treated as a subclass of the class to which the element belongs. + +If you do not wish to do so, you can make it a wrapper class. ```erg Abc = Class {"A", "B", "C"} diff --git a/doc/zh_CN/syntax/type/12_refinement.md b/doc/zh_CN/syntax/type/12_refinement.md index 281eab5a..2aac3db8 100644 --- a/doc/zh_CN/syntax/type/12_refinement.md +++ b/doc/zh_CN/syntax/type/12_refinement.md @@ -1,12 +1,12 @@ -# 筛子类型(Refinement Type) +# Refinement Type -Refinement type 是受谓词表达式约束的类型。枚举型和区间型是筛子型的一种。 - -筛型的标准形式是。这意味着它是以满足为元素的类型。只有可用于筛型。 +Refinement type is a type constrained by a predicate expression. Enumeration types and interval types are syntax sugar of refinement types. +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 -Nat = 0.._ +Nat = 0.. _ Odd = {N: Int | N % 2 == 1} Char = StrWithLen 1 # StrWithLen 1 == {_: StrWithLen N | N == 1} @@ -14,35 +14,36 @@ Char = StrWithLen 1 Array3OrMore == {A: Array _, N | N >= 3} ``` -如果有多个 Pred,请用或分隔。是相同的意思。 +When there are multiple preds, they can be separated by `;` or `and` or `or`. `;` and `and` mean the same thing. -的元素是。因为它是一种将现有类型的一部分作为要素的类型,就像在筛子上一样,所以被称为筛子类型。 - -称为(左侧)谓词表达式。它不返回与赋值表达式相同的有意义的值,并且只能在左边放置模式。也就是说,等式不能用作筛子谓词表达式。这一点不同于右边表达式的谓词表达式。 +The elements of `Odd` are `1, 3, 5, 7, 9, ...`. +It is called a refinement type because it is a type whose elements are part of an existing type as if it were a refinement. +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 {X: Int | X**2 - 5X + 6 == 0} # SyntaxError: the predicate form is invalid. Only names can be on the left-hand side ``` -如果你知道二次方程的解法,你应该可以预测,上面的筛子类型将等同于。然而,Erg 编译器几乎没有代数学知识,因此无法解决右边的谓词表达式。 +If you know how to solve quadratic equations, you would expect the above refinement form to be equivalent to `{2, 3}`. +However, the Erg compiler has very little knowledge of algebra, so it cannot solve the predicate on the right. ## Smart Cast -定义是很好的,但如果这样,除了文字以外,似乎很难使用它。要将常规对象中的奇数提升到,即将下铸到,必须通过构造函数。对于筛子类型,常规构造函数可能会死机,有些辅助构造函数返回类型。 - +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 i = Odd.new (0..10).sample!() i: Odd # or Panic ``` -也可以在中用作类型说明。 - +It can also be used as a type specification in `match`. ```erg # i: 0..10 -i = (0..10).sample!() +i = (0..10).sample! match i: o: Odd -> log "i: Odd" @@ -50,26 +51,25 @@ match i: log "i: Nat" ``` -然而,由于 Erg 当前不是,因此不能进行诸如之类的次要判断。 +However, Erg cannot currently make sub-decisions such as `Even` because it was not `Odd`, etc. -## 列举型、区间型和筛型 - -之前介绍的枚举型和区间型,是筛子型的糖衣句法。将脱糖为,将脱糖为。 +## Enumerated, Interval and Sift Types +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 {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} +1... <10 == {I: Int | I >= 1 and I < 10} ``` -## 筛子模式 - -可以被重写为(常数模式),可以被重写为。 +## Refinement pattern +Just as `_: {X}` can be rewritten as `X` (constant pattern), `_: {X: T | Pred}` can be rewritten as `X: T | Pred`. ```erg -# メソッド.mは長さ3以上の配列に定義される +# method `.m` is defined for arrays of length 3 or greater 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 index 92d63f96..f910147a 100644 --- a/doc/zh_CN/syntax/type/13_algebraic.md +++ b/doc/zh_CN/syntax/type/13_algebraic.md @@ -1,35 +1,37 @@ -# Algebraic type(代数类型) +# Algebraic type -代数运算类型是指将类型视为代数并进行运算而产生的类型。代数类型处理的操作包括 Union、Intersection、Diff 和 Complement。常规类只能是 Union,其他操作都是类型错误。 +Algebraic types are types that are generated by operating types by treating them like algebra. +Operations handled by them include Union, Intersection, Diff, Complement, and so on. +Normal classes can only perform Union, and other operations will result in a type error. ## Union -在 Union 型中,关于型可以给出多个可能性。顾名思义,它由运算符生成。典型的 Union 是类型。类型是的 patch type,主要表示可能失败的值。 +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 IntOrStr = Int or Str assert dict.get("some key") in (Int or NoneType) -# 暗黙に`T != NoneType`となる +# Implicitly become `T != NoneType` Option T = T or NoneType ``` ## Intersection -Intersection 类型是通过操作组合类型而得到的。 - +Intersection types are got by combining types with the `and` operation. ```erg Num = Add and Sub and Mul and Eq ``` -如上所述,无法通过操作将常规类组合在一起。实例属于唯一的类。 +As mentioned above, normal classes cannot be combined with the `and` operation. This is because instances belong to only one class. ## Diff -Diff 类型是通过运算得到的。作为接近英文的表记,比较好,但由于并列比较好,所以建议只使用。 - +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 CompleteNum = Add and Sub and Mul and Div and Eq and Ord @@ -41,8 +43,9 @@ OneTwoThree = {1, 2, 3, 4, 5, 6} - {4, 5, 6, 7, 8, 9, 10} ## Complement -Complement 是通过运算得到的,但它是一元运算。类型是的缩写符号。类型的 Intersection 等效于 Diff,类型的 Diff 等效于 Intersection。但不建议这样的写法。 - +Complement types is got by the `not` operation, which is a unary operation. The `not T` type is a shorthand for `{=} not T`. +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 # the simplest definition of the non-zero number type @@ -52,10 +55,11 @@ NonZero = Not {0} Bool == {True} not not {False} # 2 == 1 - -1 ``` -## 真实代数类型 - -代数运算类型包括可简化的表观代数运算类型和不能进一步简化的“真代数运算类型”。其他“表观代数类型”包括 Enum 和 Interval 类型,以及和记录类型。因为它们可以简化,所以它们不是真正的代数运算类型,如果用来指定类型,就会出现 Warning。要消除警告,必须简化或定义类型。 +## True Algebraic type +There are two algebraic types: apparent algebraic types that can be simplified and true algebraic types that cannot be further simplified. +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 assert {1, 2, 3} or {2, 3} == {1, 2, 3} @@ -71,12 +75,11 @@ Point2D = Point1D and {y = Int; ...} # == {x = Int; y = Int; ...} 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 assert Int or Str == Or(Int, Str) assert Int and Marker == And(Int, Marker) ``` -Diff 和 Complement 类型不是真正的代数运算类型,因为它们总是可以简化。 +Diff, Complement types are not true algebraic types because they can always be simplified. diff --git a/doc/zh_CN/syntax/type/14_dependent.md b/doc/zh_CN/syntax/type/14_dependent.md index 8efd14ae..c7ec3eb6 100644 --- a/doc/zh_CN/syntax/type/14_dependent.md +++ b/doc/zh_CN/syntax/type/14_dependent.md @@ -1,11 +1,12 @@ -# 依赖关系 +# dependent type -依赖性可以说是 Erg 最大的特点。依赖关系是一种以值为参数的类型。通常的多相型只能将型作为自变量,但放松了其限制,就可以说是依存型。 +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 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 +``` erg a1 = [1, 2, 3] assert a1 in [Nat; 3] a2 = [4, 5, 6, 7] @@ -13,26 +14,24 @@ assert a1 in [Nat; 4] assert a1 + a2 in [Nat; 7] ``` -如果在函数参数中传递的类型对象与返回类型相关联,请使用。 +If the type object passed in the function argument is related to the return type, write: - -```erg +``` erg 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. -依赖关系本身也存在于现有语言中,但 Erg 允许你定义依赖关系的过程方法。 +Dependent types themselves exist in existing languages, but Erg has the feature of defining procedural methods on dependent types. - -```erg -x = 1 +``` erg +x=1 f x = print! f::x, module::x -# Phantom型は型引数と同じ値になるPhantomという属性を持っている +# 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 @@ -40,21 +39,21 @@ T(X). T(1).x() # 1 ``` -可以通过应用方法来转换可变依赖类型参数。转换规范在中进行。 +Type arguments of mutable dependent types can be transitioned by method application. +Transition specification is done with `~>`. - -```erg -# `Id`は不変型なので遷移させることはできないことに注意 +``` erg +# 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::set_phantom!("running") -# 型引数ごとに切り出すこともできる(定義されたモジュール内でのみ) +# 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 = +VM!("running" ~> "running").stop!ref!self = self.close_something!() self::set_phantom!("stopped") @@ -65,12 +64,11 @@ vm.stop!() # TypeError: VM!(!"stopped", 1) doesn't have .stop!() # hint: VM!(!"running", 1) has .stop!() ``` -也可以通过合并或继承现有类型来创建依赖类型。 +You can also embed or inherit existing types to create dependent types. +``` erg +MyArray(T, N) = Inherit[T; N] -```erg -MyArray(T, N) = Inherit [T; N] - -# .arrayと連動してself: Self(T, N)の型が変わる +# 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/zh_CN/syntax/type/15_quantified.md b/doc/zh_CN/syntax/type/15_quantified.md index b1bde16c..368aaaf5 100644 --- a/doc/zh_CN/syntax/type/15_quantified.md +++ b/doc/zh_CN/syntax/type/15_quantified.md @@ -1,14 +1,14 @@ -# 类型变量,量化 - -类型变量是用于指定子例程参数类型的变量,并指示其类型是可选的(非单相)。首先,作为引入类型变量的动机,让我们考虑返回输入的函数。 +# Type Variable, quantified type +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 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 id x: Object = x @@ -18,16 +18,16 @@ s = id "foo" 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 print! id 1 # -id(1) + 1 # TypeError: cannot add `Object` and `Int` +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 id|T: Type| x: T = x @@ -36,13 +36,12 @@ assert id("foo") == "foo" assert id(True) == True ``` -我们在函数中称为。虽然有细微差别,但它们相当于其他语言中称为通用的功能。然后,全称量化函数称为。定义多相关数就像为所有类型定义相同形式的函数一样(由于 Erg 禁止重载,所以下面的代码实际上是不可能写的)。 - +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 id|T: Type| x: T = x # pseudo code -# == id x: Int = x id x: Str = x id x: Bool = x @@ -51,22 +50,23 @@ id x: NoneType = x ... ``` -此外,类型变量用于指定类型,因此可以推断为类型。因此,可以简单地省略为。此外,如果你可以推理非类型对象,如),则可以省略它。 - -另外,如果任何类型太大,也可以给出限制。约束也有好处,例如,子类型规范允许你使用特定的方法。 +Also, the type variable `T` can be inferred to be of type `Type` since it is used in the type specification. So `|T: Type|` can simply be abbreviated to `|T|`. +You can also omit `|T, N| foo: [T; N]` if it can be inferred to be other than a type object (`T: Type, N: Nat`). +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 # T <: Add -# => TはAddのサブクラス -# => 加算ができる +# => T is a subclass of Add +# => can do addition add|T <: Add| l: T, r: T = l + r ``` -在此示例中,必须是类型的子类,并且实际赋值的必须与类型相同。在这种情况下,是指。因为没有定义的相加,所以弹。 - -也可以这样打字。 +In this example, `T` is required to be a subclass of type `Add`, and the actual types of `l` and `r` to be assigned must be the same. +In this case, `T` is satisfied by `Int`, `Ratio`, etc. So, the addition of `Int` and `Str`, for example, is not defined and is therefore rejected. +You can also type it like this. ```erg f| @@ -74,36 +74,35 @@ f| X <: Add Y, O1 O1 <: Add Z, O2 O2 <: Add X, _ -| x: X, y: Y, z: Z = +| x: X, y: Y, z: Z = x + y + z + x ``` -如果注释列表变长,最好预先声明。 - +If the annotation list is long, you may want to pre-declare it. ```erg 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 = +f|X, Y, Z| x: X, y: Y, z: Z = x + y + z + x ``` -与许多具有通用语言的语言不同,所有声明的类型变量必须在伪参数列表(部分)或其他类型变量的参数中使用。这是 Erg 语言设计提出的要求,即所有类型变量都可以从实际参数中推理。因此,不能推理的信息(如返回类型)是从实际参数传递的。Erg 可以从实际参数中传递类型。 - +Unlike many languages with generics, all declared type variables must be used either in the temporary argument list (the `x: X, y: Y, z: Z` part) or in the arguments of other type variables. +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 Iterator T = Trait { - # 戻り値の型を引数から渡している - # .collect: |K: Type -> Type| Self(T).({K}) -> K(T) + # Passing return types from arguments. + # .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] +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 f|X|(x: X): () = @@ -116,35 +115,32 @@ f 1 # ``` -使用时也可以显式单相化,如下所示。 - +You can also explicitly monophasize at the time of use as follows ```erg 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 assert id(1) == 1 assert id|Int|(1) in Int assert id|Ratio|(1) in Ratio -# キーワード引数も使える +# You can also use keyword arguments assert id|T: Int|(1) == 1 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 -# {id|Int| x | x <- 1..10}だと{id | ...}だと解釈される +# {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 I: Type @@ -152,10 +148,9 @@ I: Type f|I: Type| ... = ... ``` -## 方法定义中的类型参数 - -缺省情况下,左侧的类型参数被视为绑定变量。 +## Type arguments in method definitions +Type arguments on the left-hand side are treated as bound variables by default. ```erg K(T: Type, N: Nat) = ... @@ -163,8 +158,7 @@ K(T, N). foo(x) = ... ``` -如果使用不同的类型变量名称,则会发出警告。 - +Using another type variable name will result in a warning. ```erg K(T: Type, N: Nat) = ... @@ -172,72 +166,68 @@ K(U, M). # Warning: K's type variable names are 'T' and 'N' foo(x) = ... ``` -常量在定义后的所有命名空间中都是相同的,因此也不能用于类型变量名称。 - +Constants are the same in all namespaces since their definition, so of course they cannot be used for type variable names. ```erg N = 1 K(N: Nat) = ... # NameError: N is already defined L(M: Nat) = ... -# M == N == 1のときのみ定義される +# Defined only if M == N == 1 L(N). foo(self, x) = ... -# 任意のM: Natに対して定義される +# defined for any M: Nat L(M). .bar(self, x) = ... ``` -虽然不能为每个类型参数定义多个参数,但可以定义同名的方法,因为没有指定类型参数的从属类型(非原始卡印)和已指定类型参数的从属类型(原始卡印)没有关系。 - +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 K(I: Int) = ... K. - # Kは真の型(原子カインド)ではないので、メソッドを定義できない - # これはメソッドではない(スタティックメソッドに近い) + # K is not a true type (atomic Kind), so we cannot define a method + # This is not a method (more like a static method) foo(x) = ... K(0). foo(self, x): Nat = ... ``` -## 全称型 - -在上一章中定义的函数可以是任何类型。那么,“函数本身的类型”是什么呢? +## All symmetric types +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 print! classof(id) # |T: Type| T -> T ``` -得到了的类型。这被称为,相当于 ML 中以形式提供的类型,Haskell 中以形式提供的类型。为什么要加上“闭合”这个形容词,后面会讲到。 +We get a type `|T: Type| T -> T`. This is called a __closed universal quantified type/universal type__, which is `['a. ...]'` in ML, and `forall t. ...` in Haskell. Why the adjective "closed" is used is discussed below. -封闭的全称类型是有限制的,只能将子程序类型全称化,即只能将其置于左侧子句中。但这已经足够了。在 Erg 中,子程序是最基本的控制结构,因此当“想要处理任意 X”时,即“想要能够处理任意 X 的子程序”。所以,全称型和多相关数型是一个意思。以后基本上把这种类型称为多相关数类型。 - -与无名函数一样,多相关数类型具有类型变量名称的任意性,但它们都是等值的。 +There is a restriction on the closed universal quantified type: only subroutine types can be made universal quantified, i.e., only subroutine types can be placed in the left clause. But this is sufficient, since subroutines are the most basic control structure in Erg, so when we say "I want to handle arbitrary X," i.e., I want a subroutine that can handle arbitrary X. So, the quantified type has the same meaning as the polymorphic function type. From now on, this type is basically called polymorphic function type. +Like anonymous functions, polymorphic types have arbitrary type variable names, but they all have the same value. ```erg assert (|T: Type| T -> T) == (|U: Type| U -> U) ``` -在 Lambda 计算中,当α等值时,等号成立。由于类型运算存在一些限制,因此始终可以确定等价性(除非考虑终止性)。 +The equality is satisfied when there is an alpha equivalence, as in the lambda calculus. Since there are some restrictions on operations on types, equivalence determination is always possible (if we don't consider the stoppage property). -## 多相关数类型的部分类型 +## Subtyping of Polymorphic Function Types -多相关数类型可以是任何函数类型。这意味着它与任何函数类型具有子类型关系。让我们来详细了解一下这种关系。 +A polymorphic function type can be any function type. This means that there is a subtype relationship with any function type. Let's look at this relationship in detail. -这样的“类型变量在左边定义并在右边使用的类型”称为。与此相对,等“类型变量在右边定义和使用的类型”称为。 - -打开了的全称型,成为同形的全部的“真的型”的超级型。相反,封闭的全称类型是所有相同类型的“真实类型”的子类型。 +A type in which the type variable is defined on the left-hand side and used on the right-hand side, such as `OpenFn T: Type = T -> T`, is called an __open universal type__. +In contrast, a type in which type variables are defined and used on the right-hand side, such as `ClosedFn = |T: Type| T -> T`, is called a __closed universal type__. +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 (|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 # id: |T: Type| T -> T @@ -246,32 +236,34 @@ id|T|(x: T): T = x # iid: Int -> Int iid(x: Int): Int = x -# 任意の関数をそのまま返す +# return arbitrary function as is 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) # TypeError -# Int型関数をそのまま返す +# Return Int type function as is id_int_fn(f3: Int -> Int): (Int -> Int) = f # id_int_fn(id) == id|Int| # id_int_fn(iid) == iid ``` -类型的可以赋给类型的参数,因此可以认为是。相反,类型的不能赋给类型的参数,但它是,因为它可以赋给类型的参数。因此,确实是。 +Since `id`, which is of type `|T: Type| T -> T`, can be assigned to a parameter `f3` of type `Int -> Int`, we may consider `(|T| T -> T) < (Int -> Int)`. +Conversely, `iid`, which is of type `Int -> Int`, cannot be assigned to parameter `f2` of type `(|T| T -> T)`, but it can be assigned to parameter `f1` of type `T -> T`, so `(Int -> Int) < (T -> T)`. +Therefore, it is indeed `(|T| T -> T) < (Int -> Int) < (T -> T)`. -## 全称和依赖关系 +## Quantified Types and Dependent Types -依存型和全称型(多相关数型)有什么关系,有什么不同呢?依赖类型是一种采用参数的类型,而全称类型是一种为参数提供任意性的类型(在要全称的子程序中)。 +What is the relationship between dependent types and quantified types (polymorphic function types) and what is the difference between them? +We can say that a dependent type is a type that takes arguments, and an quantified type is a type that gives arbitrariness to the arguments. -重要的是,封闭的全称类型本身没有类型参数。例如,多相关数类型是取多相关数的类型,其定义是封闭的。不能使用该类型参数定义方法等。 - -在 Erg 中,类型本身也是一个值,因此采用参数的类型(例如函数类型)也必须是一个依赖类型。也就是说,多相关数类型既是全称类型,也是依存类型。 +The important point is that there are no type arguments in the closed, polymorphic type itself. For example, the polymorphic function type `|T| T -> T` is a type that takes a polymorphic function __only__, and its definition is closed. You cannot define methods, etc. using its type argument `T`. +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 PolyFn = Patch(|T| T -> T) diff --git a/doc/zh_CN/syntax/type/16_subtyping.md b/doc/zh_CN/syntax/type/16_subtyping.md index f3f4bc04..e5ed7cf9 100644 --- a/doc/zh_CN/syntax/type/16_subtyping.md +++ b/doc/zh_CN/syntax/type/16_subtyping.md @@ -1,19 +1,17 @@ -# 部分定型 - -在 Erg 中,可以使用比较运算符和来确定类之间的包含关系。 +# Subtyping +In Erg, class inclusion can be determined with the comparison operators `<`, `>`. ```erg Nat < Int Int < Object -1.._ < Nat +1... _ < Nat {1, 2} > {1} {=} > {x = Int} {I: Int | I >= 1} < {I: Int | I >= 0} ``` -请注意,它与运算符的含义不同。它声明左侧类是右侧类型的子类型,并且仅在编译时有意义。 - +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 C <: T # T: StructuralType @@ -22,12 +20,11 @@ f|D <: E| ... assert F < G ``` -对于多相类型的子类型规范,例如,也可以指定。 +You can also specify `Self <: Add` for a polymorphic subtype specification, for example ``Self(R, O) <: Add(R, O)``. -## 结构类型,类类型关系 - -结构类型是用于实现结构定型的类型,如果结构相同,则将其视为相同的对象。 +## Structural types and class type relationships +Structural types are types for structural typing and are considered to be the same object if they have the same structure. ```erg T = Structural {i = Int} @@ -39,8 +36,7 @@ assert t in T assert t in U ``` -相反,类是用于实现记名类型的类型,不能在结构上比较类型和实例。 - +In contrast, classes are types for notational typing and cannot be compared structurally to types and instances. ```erg C = Class {i = Int} @@ -52,10 +48,11 @@ assert c in C assert not c in D ``` -## 子程序的局部类型 - -子程序的参数和返回值只采用单个类。也就是说,不能将结构型和trait作为函数的类型直接指定。必须使用子类型指定将其指定为“作为该类型子类型的单个类”。 +## Subtyping of subroutines +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 # OK @@ -63,14 +60,13 @@ f1 x, y: Int = x + y # NG f2 x, y: Add = x + y # OK -# Aは何らかの具体的なクラス +# A is some concrete class f3 x, y: A = x + y ``` -子程序的类型推论也遵循这个规则。当子程序中的变量中有未明示类型时,编译器首先检查该变量是否为某个类的实例,如果不是,则从作用域中的trait中寻找适合的变量。即使这样也找不到的话,就成为编译错误。这个错误可以通过使用结构型来消除,但是推论无名型有可能是程序员不想要的结果,所以设计成程序员明确地用来指定。 - -## 上传类 +Type inference in subroutines also follows this rule. When a variable in a subroutine has an unspecified type, the compiler first checks to see if it is an instance of one of the classes, and if not, looks for a match in the scope of the trait. If it still cannot find one, a compile error occurs. This error can be resolved by using a structural type, but since inferring an anonymous type may have unintended consequences for the programmer, it is designed to be explicitly specified by the programmer with `Structural`. +## Class upcasting ```erg i: Int diff --git a/doc/zh_CN/syntax/type/17_type_casting.md b/doc/zh_CN/syntax/type/17_type_casting.md index 4fd887a9..65ef9207 100644 --- a/doc/zh_CN/syntax/type/17_type_casting.md +++ b/doc/zh_CN/syntax/type/17_type_casting.md @@ -1,11 +1,12 @@ -# cast +# Cast -## 上投 +## Upcasting -Python 没有 cast 的概念,因为它采用烤鸭打字的语言。不需要上播,基本上也没有下播。但是,由于 Erg 是静态输入的,因此可能需要强制转换。一个简单的例子是。Erg 的语言规范没有定义(Int,Ratio),即 Int( <:Add(Ratio,Ratio))的运算。这是因为将 1 上传到 Ratio 的实例 1.0。 - -~~Erg 扩展字节码将类型信息添加到 BINARY_ADD 中,其中类型信息为 Ratio-Ratio。在这种情况下,BINARY_ADD 指令将转换 Int,因此不会插入指定转换的特殊指令。因此,例如,如果在子类中覆盖了某个方法,但将父项指定为类型,则会强制类型(type coercion)并在父项方法中执行(在编译时进行名称限定以引用父项方法)。编译器只执行强制类型验证和名称限定。运行时不会强制转换对象(当前)。可能会实现强制转换指令以进行执行优化。~~ +Because Python is a language that uses duck typing, there is no concept of casting. There is no need to upcast, and there is essentially no downcasting. +However, Erg is statically typed, so there are times when casting must be done. +A simple example is `1 + 2.0`: the `+`(Int, Ratio), or Int(<: Add(Ratio, Ratio)) operation is not defined in the Erg language specification. This is because `Int <: Ratio`, so 1 is upcast to 1.0, an instance of 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 @Inheritable @@ -15,7 +16,7 @@ Parent. Child = Inherit Parent Child. - # オーバーライドする際にはOverrideデコレータが必要 + # Override requires Override decorator @Override greet!() = print! "Hello from Child" @@ -24,12 +25,11 @@ greet! p: Parent = p.greet!() parent = Parent.new() child = Child.new() -greet! parent # "Hello from Parent" -greet! child # "Hello from Parent" +parent # "Hello from Parent" greet! +child # "Hello from Parent" ``` -此行为不会导致与 Python 的不兼容。Python 最初不为变量指定类型,因此所有变量都以类型变量输入。由于类型变量选择最小匹配类型,因此如果 Erg 不指定类型,则会实现与 Python 相同的行为。 - +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 @Inheritable @@ -39,19 +39,18 @@ Parent. Child = Inherit Parent Child. - greet!() = print! "Hello from Child" + greet!() = print! "Hello from Child" Child. greet! some = some.greet!() parent = Parent.new() child = Child.new() -greet! parent # "Hello from Parent" -greet! child # "Hello from Child" +parent # "Hello from Parent" greet! +child # "Hello from Child" ``` -对于具有继承关系的类型,和是自动实现的,你也可以使用它们。 - +You can also use `.from` and `.into`, which are automatically implemented for types that are inherited from each other. ```erg assert 1 == 1.0 @@ -59,10 +58,9 @@ assert Ratio.from(1) == 1.0 assert 1.into() == 1.0 ``` -## 下铸 - -降播通常是不安全的,转换方式也不是显而易见的,而是通过实现来实现。 +## Downcasting +Since downcasting is generally unsafe and the conversion method is non-trivial, we instead implement ``TryFrom.try_from``. ```erg IntTryFromFloat = Patch Int @@ -70,5 +68,5 @@ IntTryFromFloat. try_from r: Float = if r.ceil() == r: then: r.ceil() - else: Error "conversion failed" + else: Error "conversion failed". ``` diff --git a/doc/zh_CN/syntax/type/18_mut.md b/doc/zh_CN/syntax/type/18_mut.md index 9c41fe64..63ab9719 100644 --- a/doc/zh_CN/syntax/type/18_mut.md +++ b/doc/zh_CN/syntax/type/18_mut.md @@ -1,82 +1,79 @@ -# 可变类型(Mutable Type) +# Mutable Type -> :本节中的信息过时,并且包含一些错误。 +> __Warning__: The information in this section is old and contains some errors. -缺省情况下,Erg 将所有类型设置为不可变类型,即不能更新内部状态。但你当然可以定义可变类型。变量类型声明为。 +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 +``` erg 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 + inc_age!ref!self = self::name.update!old -> old + 1 ``` -确切地说,以可变类型或包含可变类型的复杂类型为基本类型的类型必须在类型名称后加上。没有的类型也可以存在于同一命名空间中,并被视为不同的类型。在上面的示例中,属性是可变的,而属性是不变的。如果有一个属性是可变的,则整个属性都是可变的。 +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. -变量类型可以定义用于重写实例的过程方法,但具有过程方法并不一定意味着它是变量类型。例如,数组类型实现了随机选择元素的方法,当然这不会对数组进行破坏性更改。 +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 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 +``` erg 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. - -```erg +``` erg i = !1 i.set! 2 assert i == 2 ``` -方法在不更改值的情况下执行操作。 +The `.freeze_map` method operates on values ​​unchanged. - -```erg +``` erg 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 a polymorphic immutable type the type argument `T` of the type is implicitly assumed to be immutable. - -```erg +``` erg # ImmutType < Type -K T: ImmutType = Class ... -K! T: Type = Class ... +KT: ImmutType = Class ... +K!T: Type = Class ... ``` -在标准库中,可变类型通常基于不变类型。但是,类型和类型在语言上没有特殊的关联,不需要这样配置。 +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 -# 配列型 -## 不変型(immutable types) -[T; N] # 可変操作は実行できない -## 可変型(mutable types) -[T!; N] # 中身を1つずつ変更できる -[T; !N] # 可変長、中身は変更不能だが要素の追加・削除で実質変更可能 -[!T; N] # 中身は不変オブジェクトだが、型を変えたものに差し替え可能(型を変えないという操作で実質差し替え可能) -[!T; !N] # 型、長さを変更可能 -[T!; !N] # 中身、長さを変更可能 -[!T!; N] # 中身、型を変更可能 -[!T!; !N] # ありとあらゆる可変操作を実行できる +``` erg +# 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 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, 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 syntactic sugar, the actual types are: - -```erg -# 実際は4種類の型 +``` erg +# actually 4 types [T; N] = Array(T, N) [T; !N] = Array!(T, !N) [!T; N] = ArrayWithMutType!(!T, N) @@ -86,83 +83,81 @@ K! T: Type = Class ... [!T!; !N] = ArrayWithMutTypeAndLength!(!T!, !N) ``` -另外,可以更改类型就是这样的意思。 +This is what it means to be able to change the type. - -```erg +``` erg a = [1, 2, 3].into [!Nat; 3] a.map!(_ -> "a") a: [!Str; 3] ``` -其他收藏类型也是如此。 +The same is true for other collection types. - -```erg -# タプル型 -## 不変型(immutable types) -(T, U) # 要素数不変、中身を変更できない -## 可変型(mutable types) -(T!, U) # 要素数不変、最初の要素は変更できる -(T, U)! # 要素数不変、中身を差し替えられる +``` erg +# tuple type +## immutable types +(T, U) # No change in number of elements, contents cannot be changed +## mutable types +(T!, U) # constant number of elements, first element can be changed +(T, U)! # No change in number of elements, content can be replaced ... ``` - -```erg -# セット型 -## 不変型(immutable types) -{T; N} # 不変要素数、中身を変更できない -## 可変型(mutable types) -{T!; N} # 不変要素数、中身を(1つずつ)変更できる -{T; N}! # 可変要素数、中身は変更不能だが、要素の追加削除で実質可能、中の型を変更可能 -{T!; N}! # 可変要素数、中身も変更できる +``` erg +# Set type +## immutable types +{T; N} # number of immutable elements, contents cannot be changed +## mutable types +{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 -# 辞書型 -## 不変型(immutable types) -{K: V} # 不変長、中身を変更できない -## 可変型(mutable types) -{K: V!} # 不変長、値を(1つずつ)変更できる -{K: V}! # 可変長、中身を変更できないが、要素の追加削除で実質可能、中の型も変更可能 +``` erg +# Dictionary type +## immutable types +{K: V} # immutable length, contents cannot be changed +## mutable types +{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 -# レコード型 -## 不変型(immutable types) -{x = Int; y = Str} # 中身を変更できない -## 可変型(mutable types) -{x = Int!; y = Str} # xの値を変更できる -{x = Int; y = Str}! # {x = Int; y = Str}のインスタンスならば何でも差し替えられる +``` erg +# Record type +## immutable types +{x = Int; y = Str} # content cannot be changed +## mutable types +{x = Int!; y = Str} # can change the value of x +{x = Int; y = Str}! # replace any instance of {x = Int; y = Str} ... ``` -当时,仅为的类型称为简单结构类型。简单结构类型(语义上)也可以称为没有内部结构的类型。数组,元组,集,字典和记录类型并非都是简单结构类型,而 Int 和筛选类型则是简单结构类型。 +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 -# 篩型 -## 列挙型 -{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}! # 上と全く同じ型、だが上の記法が推奨される +``` erg +# 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 above notation is preferred ``` -根据以上说明,可变类型不仅包括自身可变的类型,也包括内部具有的类型可变的类型。类型(如和)是内部变量类型,其内部对象是可变的,而实例本身并不是可变的。 +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. -对于具有内部结构的类型,可以改变整个对象。它还可以进行局部更改。但是,最好将更改权限限制在局部,因此如果只有可以更改,则最好将其设置为。如果类型没有内部结构,则该实例只是一个可互换的框。方法不能更改类型。 +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类型和类型在语言上没有特殊关系,这是有意设计。如果存在关联,则会出现一些不便,例如,如果名称空间中存在类型/,则无法从另一个模块引入类型/。此外,与不可变类型相比,可变类型并不是唯一的。当定义时,变量子类型可以是 +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/zh_CN/syntax/type/19_bound.md b/doc/zh_CN/syntax/type/19_bound.md index 0c7c00f0..90411ac4 100644 --- a/doc/zh_CN/syntax/type/19_bound.md +++ b/doc/zh_CN/syntax/type/19_bound.md @@ -1,16 +1,18 @@ -# 类型边界(Type Bound) +# Type Bound -型界是在型指定上添加条件的东西。实现这一功能的功能是保护(保护节)。除了函数签名、无名函数签名之外,筛子型也可以使用该功能。监控记述在返回值型之后。 +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) +## Predicate -可以使用返回的表达式(谓词表达式)指定变量满足的条件。只能使用和运算符。编译时函数有可能在今后的版本中被对应。 +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 +``` erg 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 index be845153..1fdeed74 100644 --- a/doc/zh_CN/syntax/type/advanced.md +++ b/doc/zh_CN/syntax/type/advanced.md @@ -1 +1 @@ -以后将进一步解说高级型系统。入门的朋友不看所有的条款也没问题。 +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/zh_CN/syntax/type/advanced/GADTs.md b/doc/zh_CN/syntax/type/advanced/GADTs.md index 06b874e1..ee5da587 100644 --- a/doc/zh_CN/syntax/type/advanced/GADTs.md +++ b/doc/zh_CN/syntax/type/advanced/GADTs.md @@ -1,9 +1,8 @@ -# Generalized Algebraic Data Types,GADTs +# Generalized Algebraic Data Types (GADTs) -Erg 可以通过对 Or 类型进行类化来创建广义代数数据类型(GADTs)。 +Erg can create Generalized Algebraic Data Types (GADTs) by classifying Or types. - -```erg +``` erg 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) @@ -11,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 @@ -19,18 +18,17 @@ print! cons(1, cons(2, nil())).head() # 1 print! nil.head() # RuntimeError: "empty list" ``` -将作为而不是是因为使用时不需要类型。 +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 +``` erg i = List.nil() _: List Int = cons 1, i ``` -这里定义的是 GADTs,但它是一个简单的实现,没有真正的 GADTs 价值。例如,如果内容为空,上面的方法将导致运行时错误,但可以在编译时执行此检查。 +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 +``` erg List: (Type, {"Empty", "Nonempty"}) -> Type List T, "Empty" = Class(Impl := Phantom T) List T, "Nonempty" = Class {head = T; rest = List(T, _)}, Impl := Unpack @@ -45,10 +43,10 @@ print! cons(1, cons(2, nil())).head() # 1 print! nil().head() # TypeError ``` -在街头巷尾经常被说明的 GADTs 的例子,是象以上那样根据类型能判定内容是否为空的列表。Erg 提供了更精确的定义长度列表的方法。 +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 +``` erg List: (Type, Nat) -> Type List T, 0 = Class(Impl := Phantom T) List T, N = Class {head = T; rest = List(T, N-1)}, Impl := Unpack @@ -64,5 +62,5 @@ List(_, N | N >= 2). 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 -``` +print! nil. head() # TypeError +``` \ 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 index 7f068403..11b4afcd 100644 --- a/doc/zh_CN/syntax/type/advanced/_rank2type.md +++ b/doc/zh_CN/syntax/type/advanced/_rank2type.md @@ -1,58 +1,58 @@ -# rank-2 多相 +# rank-2 polymorphism -> :此文档的信息较旧,通常包含错误。 +> __Warning__: This document is out of date and contains errors in general. -在 Erg 中,像等可以接受各种类型的函数,即可以定义多相关数。那么,能接受多相关数的函数能被定义吗?例如,这样的函数(请注意,此定义包含错误)。 +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): - -```erg -# tuple_map(i -> i * 2, (1, "a")) == (2, "aa")我要你成为 +``` erg +# 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. - -```erg +``` erg 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. - -```erg +``` erg # 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. - -```erg +``` erg 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. -对此,使用单纯的 1 自变量函数进行考虑。 +Think about this in terms of simple one-argument functions. - -```erg -f1: (T -> T) -> Int | T # 接受任何函数并返回 Int 的函数 -f2: (|T: Type| T -> T) -> Int # 接收多相关并返回 Int 的函数 -f3: Int -> (|T: Type| T -> T) # 一个函数,接受一个 Int 并返回一个封闭的通用函数 -f4: |T: Type|(Int -> (T -> T)) # 同上(首选) +``` erg +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. - -```erg +``` erg # id: |T: Type| T -> T id x = x # same type as `f1` @@ -65,12 +65,11 @@ take_i_and_return_univq_f(_: Int): (|T: Type| T -> T) = id take_i_and_return_arbit_f|T: Type|(_: Int): (T -> T) = id ``` -应用之后,就会发现其中的差异。 +After applying it, you will notice the difference. - -```erg +``` erg _ = 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: 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 @@ -84,59 +83,60 @@ 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. -关于等级的定义,首先,未量化的类型,即,等被认为是“等级 0”。 +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". - -```erg -# KはOptionなどの多項カインド +``` erg +# K is a polynomial kind such as Option R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0) ``` -其次,将等进行一阶全称量化的类型,或者将其包含在返回值类型中的类型作为“等级 1”。此外,将进行二阶全称量化的类型(以等等级 1 类型为自变量的类型),或将其包含在返回值类型中的类型设为“等级 2”。重复上述操作,定义“秩 N”型。另外,等级 N 型包含 N 以下等级的所有类型。因此,多个等级混合的类型的等级与其中最高的等级相同。 +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. - -```erg +``` erg 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. - -```erg +``` erg (|T: Type| T -> T) -> (|U: Type| U -> U) -=> R1 -> R1 -=> R1 -> R2 -=> R2 +=> R1 -> R1 +=> R1 -> R2 +=> R2 Option(|T: Type| T -> T) -=> Option(R1) -=> K(R1) -=> R1 +=> Option(R1) +=> K(R1) +=> R1 ``` -根据定义,是等级 2 型。 +By definition, `tuple_map` is a rank-2 type. - -```erg +``` erg tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) -=> (R1, R0) -> R0 -=> R1 -> R2 -=> R2 +=> (R1, R0) -> R0 +=> R1 -> R2 +=> R2 ``` -在 Erg 中,可以处理到等级 2 为止的类型(等级 N 型包含 N 以下等级的所有类型,因此正确地说 Erg 的类型都是等级 2 型)。如果试图配置更多类型的函数,则会出现错误。例如,将多相关数作为多相关数处理的函数都需要指定其他自变量的类型。另外,不能构成这样的函数。 +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. - -```erg +``` erg # 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)) ``` -等级 3 以上的类型在理论上不能决定类型推论的事实已知,类型指定破坏了可以省略的 Erg 的性质,因此被排除。尽管如此,实用需求 2 级基本可以覆盖。 +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/zh_CN/syntax/type/advanced/default_param.md b/doc/zh_CN/syntax/type/advanced/default_param.md index 3e3f5ace..d18a9e02 100644 --- a/doc/zh_CN/syntax/type/advanced/default_param.md +++ b/doc/zh_CN/syntax/type/advanced/default_param.md @@ -1,9 +1,8 @@ -# 具有默认参数的函数类型 +# Function type with default arguments -首先,看默认自变量的使用例。 +First, let's look at an example of using default arguments. - -```erg +``` erg f: (Int, Int, z := Int) -> Int f(x, y, z := 0) = x + y + z @@ -17,12 +16,13 @@ assert fold(f, [1, 2, 3]) == 6 assert fold(g, [1, 2, 3]) == 8 ``` -之后的自变量为默认自变量。部分定型规则如下。 +Arguments after `:=` are default arguments. +The subtyping rules are as follows. - -```erg +``` erg ((X, y := Y) -> Z) <: (X -> Z) ((X, y := Y, ...) -> Z) <: ((X, ...) -> Z) ``` -第 1 个意思是,有默认自变量的函数可以与没有默认自变量的函数同等看待。第 2 个是可以省略任意的默认自变量的意思。 +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/zh_CN/syntax/type/advanced/erasure.md b/doc/zh_CN/syntax/type/advanced/erasure.md index 5c24a9c7..94f9e01a 100644 --- a/doc/zh_CN/syntax/type/advanced/erasure.md +++ b/doc/zh_CN/syntax/type/advanced/erasure.md @@ -1,45 +1,43 @@ -# 类型擦除(Type erasure) +# Type erasure -类型擦除是指将指定为类型参数,并故意丢弃该信息。类型擦除是许多具有多相类型的语言的一个功能,但根据 Erg 语法,类型自变量擦除可能更准确。 - -最常见的类型清除类型的示例可能是。在编译数组时,你可能不知道数组的长度。例如,指向命令行参数的类型为。Erg 编译器不知道命令行参数的长度,因此必须放弃关于长度的信息。但是,由于已擦除的类型成为未擦除类型的超类型(e.g.),因此可以接收更多对象。类型的对象当然可以使用类型的方法,但使用后信息将被清除。因为长度可能已经改变了。如果长度不变,则必须用签名表示。 +Type erasure is the process of setting a type argument to `_` and deliberately discarding its information. Type erasure is a feature of many polymorphic languages, but in the context of Erg's syntax, it is more accurate to call it type argument erasure. +The most common example of a type that has been type-erased is `[T, _]`. Arrays are not always known their length at compile-time. For example, `sys.argv`, which refers to command line arguments, is of type `[Str, _]`. Since Erg's compiler has no way of knowing the length of command line arguments, information about their length must be given up. +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 -# 配列の長さが変わらないことが保証される関数(sortなど) -f: [T; N] -> [T; N] -# されない関数(filterなど) +# 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) g: [T; n] -> [T; _] ``` -如果类型本身使用,则该类型将上传至。对于非类型的类型参数(例如,Int 和 Bool 类型),是未定义的参数。 - +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 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 implicit = (1..5).iter().map(i -> i * 2).to_arr() explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat)) ``` -Rust 支持以下代码。 - +In Rust, this corresponds to the following code. ```rust let partial = (1..6).iter().map(|i| i * 2).collect::>(); ``` -Erg 不能部分省略类型,而是使用高阶卡印多相。 - +Erg does not allow partial omission of types, but uses higher-order kind polymorphism instead. ```erg -# collect 是一个接收 kind 的高阶 kind 方法 +# 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/zh_CN/syntax/type/advanced/existential.md b/doc/zh_CN/syntax/type/advanced/existential.md index c8a0f7ec..5cc1ef99 100644 --- a/doc/zh_CN/syntax/type/advanced/existential.md +++ b/doc/zh_CN/syntax/type/advanced/existential.md @@ -1,22 +1,23 @@ -# 存在类型 - -如果有对应于应有尽有的全称型,那么自然会有对应于应有尽有的存在型。存在型并不难。只是你没有这样的意识,就已经知道了你的存在型。 +# Existential type +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 T: Trait f x: T = ... ``` -上面的trait被用作存在类型。相反,下面的只是trait,是全称类型。 - +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 f|X <: T| x: X = ... ``` -事实上,存在类型被全称类型所取代。那么为什么会存在所谓的存在型呢?首先,正如上面所见,存在类型不涉及类型变量,因此可以简化类型指定。此外,由于可以移除类型变量,因此可以配置全称类型,使其超过等级 2。 - +In fact, the existential type is replaced by an for-all type. So why is there such a thing as an existential type? +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 show_map f: (|T| T -> T), arr: [Show; _] = @@ -26,14 +27,15 @@ show_map f: (|T| T -> T), arr: [Show; _] = y ``` -但是,一看就知道,存在型会忘却、扩大原来的型,所以不想扩大返回值的型等情况下,需要使用全称型。相反,只作为参数接收而与返回值无关的类型可以用存在类型来描述。 - +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 -# id(1): 我希望它是一个 Int +# id(1): I want it to be Int id|T|(x: T): T = x -# |S <: Show|(s: S) -> () 是多余的 +# |S <: Show|(s: S) -> () is redundant show(s: Show): () = log s ``` -顺便说一下,类不称为存在类型。因为预先决定了成为那个要素的对象。存在型是指满足某一trait的所有类型,实际上不知道要代入什么类型。 +By the way, a class is not called an existential type. A class is not called an existential type, because its elemental objects are predefined. +Existential type means any type that satisfies a certain trait, and it is not the place to know what type is actually assigned. diff --git a/doc/zh_CN/syntax/type/advanced/keyword_param.md b/doc/zh_CN/syntax/type/advanced/keyword_param.md index 537c9814..45db64bc 100644 --- a/doc/zh_CN/syntax/type/advanced/keyword_param.md +++ b/doc/zh_CN/syntax/type/advanced/keyword_param.md @@ -1,26 +1,26 @@ -# 关键字参数函数类型 +# Function type with keyword arguments - -```erg +``` erg 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 -((x: T, y: U) -> V) <: ((T, U) -> V) # x, y are arbitrary keyword parameters +``` erg +((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 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 +``` erg 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 index 43d32cf8..64cd1f35 100644 --- a/doc/zh_CN/syntax/type/advanced/kind.md +++ b/doc/zh_CN/syntax/type/advanced/kind.md @@ -1,131 +1,122 @@ -# kind(Kind) +# Kind -Erg 中全部都是定型的。套路本身也不例外。表示“类型的类型”的是。例如,属于属于是最简单的kind。在型理论性的记法中,相对应。 +Everything is typed in Erg. Types themselves are no exception. __kind__ represents the “type of type”. For example, `Int` belongs to `Type`, just as `1` belongs to `Int`. `Type` is the simplest kind, the __atomic kind__. In type-theoretic notation, `Type` corresponds to `*`. -在kind这个概念中,实用上重要的是一项以上的kind(多项kind)。1 项的kind度,例如等属于它。1 项kind度表示为等的是特别将类型作为自变量的多项关系。正如这一表记所示,实际上是接受这一类型并返回这一类型的函数。但是,由于该函数不是通常意义上的函数,因此通常被称为 1 项kind(unary kind)。 +In the concept of kind, what is practically important is one or more kinds (multinomial kind). One-term kind, for example `Option`, belongs to it. A unary kind is represented as `Type -> Type` [1](#1). A __container__ such as `Array` or `Option` is specifically a polynomial kind that takes a type as an argument. +As the notation `Type -> Type` indicates, `Option` is actually a function that receives a type `T` and returns a type `Option T`. However, since this function is not a function in the usual sense, it is usually called the unary kind. -另外,作为无名函数运算符的本身也可以看作是接收类型并返回类型时的关系。 +Note that `->` itself, which is an anonymous function operator, can also be seen as a kind when it receives a type and returns a type. -另外,请注意,非原子kind的kind不是套路。就像是数值但不是数值一样,是类型但不是类型。等有时也被称为类型构建子。 +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 +``` erg assert not Option in Type assert Option in Type -> Type ``` -因此,下面的代码会出现错误。在 Erg 中可以定义方法的只有原子kind度,方法的第一自变量以外的地方不能使用这个名字。 +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 -# K is an unary kind +``` erg +#K is an unary kind K: Type -> Type -K T = Class ... +K T = Class... K. - foo x = ... # OK,这就像是所谓的静态方法 + foo x = ... # OK, this is like a so-called static method bar self, x = ... # TypeError: cannot define a method to a non-type object K(T). baz self, x = ... # OK ``` -二进制或更高类型的示例是 `{T: U}`(: `(Type, Type) -> Type`), `(T, U, V)`(: `(Type, Type, Type) - > Type `), ... 等等。 +Examples of binary or higher kinds are `{T: U}`(: `(Type, Type) -> Type`), `(T, U, V)`(: `(Type, Type, Type) - > Type`), ... and so on. -还有一个零项类型`() -> Type`。 这有时等同于类型论中的原子类型,但在 Erg 中有所区别。 一个例子是“类”。 +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 +``` erg Nil = Class() ``` -## kind包含关系 +## Containment of kind -多项关系之间也有部分型关系,原来部分关系。 +There is also a partial type relation, or rather a partial kind relation, between multinomial kinds. - -```erg +``` erg 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. - -```erg +``` erg ∀T. L T <: K T <=> L <: K ``` -## 高阶kind +## higher kind -还有一种叫做高阶kind(higher-order kind)。这是与高阶函数相同概念的kind,是接受kind本身的kind。等是高阶kind度。尝试定义属于高阶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 +``` erg IntContainerOf K: Type -> Type = K Int assert IntContainerOf Option == Option Int assert IntContainerOf Result == Result Int assert IntContainerOf in (Type -> Type) -> Type ``` -多项kind度的约束变量通常表示为 K,L,...等(K 是 Kind 的 K)。 +The bound variables of a polynomial kind are usually denoted as K, L, ..., where K is K for Kind. -## 套管 +## set kind -在型理论中,有一个叫做记录的概念。这与 Erg 的记录基本相同。 +In type theory, there is the concept of a record. This is almost the same as the Erg record [2](#2). - -```erg +``` erg # 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 +``` erg assert {x = 1; y = 2} in {x = Int; y = Int} ``` -记录类型用于输入记录。善于体谅的人可能会认为,应该有“唱片kind”来定型唱片型。实际上,它是存在的。 +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 +``` erg log Typeof {x = Int; y = Int} # {{x = Int; y = Int}} ``` -像这样的类型就是唱片kind。这不是特别的记法。它是只以为要素的枚举型。 +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 +``` erg Point = {x = Int; y = Int} Pointy = {Point} ``` -记录kind的重要特性在于,当时,。这从列举型实际上是筛子型的糖衣句法就可以看出。 +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 -# 通常のオブジェクトでは{c} == {X: T | X == c}だが、 -# 型の場合等号が定義されない場合があるので|T| == {X | X <: T}となる +``` erg +# {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} ``` -型限制中的实际上是的糖衣句法。这种类型的组套即kind一般被称为组套kind。设定kind也出现在 Iterator 模式中。 +`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 +``` erg Iterable T = Trait { .Iterator = {Iterator} .iter = Self(T).() -> Self.Iterator T } ``` -## 多项关系型推理 +## Type inference for polynomial kinds - -```erg +``` erg Container K: Type -> Type, T: Type = Patch K(T, T) -Container(K). +Container (K). f self = ... Option T: Type = Patch T or NoneType Option(T). @@ -137,21 +128,22 @@ Fn2 T, U: Type = Patch T -> U Fn2(T, U). f self = ... -(Int -> Int).f() # どれが選択される? +(Int -> Int).f() # which one is selected? ``` -在上面的例子中,方法选择哪个补丁呢?简单地说,被认为是可以选择的,但也有可能,包含的原样,因此任意类型都适用,也是,即相匹配。因此,上面的 4 个补丁都可以作为选择。 +In the example above, which patch would the method `f` choose? +Naively, `Fn T` seems to be chosen, but `Fn2 T, U` is also possible, `Option T` includes `T` as it is, so any type is applicable, `Container K , T` also matches ``` `->`(Int, Int)```, i.e. ```Container(`->`, Int)``` as ```Int -> Int`. So all four patches above are possible options. -在这种情况下,根据以下优先标准选择补丁。 +In this case, patches are selected according to the following priority criteria. -* 任何(e.g.)比优先匹配。 -* 任何(e.g.)比优先匹配。 -* 同样的标准适用于 3 项以上的kind度。 -* 选择替换类型变量较少的变量。例如,优先匹配(替换类型变量:T),而不是(替换类型变量:K,T)或(替换类型变量:T,U)。 -* 如果替换数相同,则错误为“无法选择”。 +* Any `K(T)` (e.g. `T or NoneType`) preferentially matches `Type -> Type` over `Type`. +* Any `K(T, U)` (e.g. `T -> U`) matches `(Type, Type) -> Type` preferentially over `Type`. +*Similar criteria apply for kind of 3 or more. +* The one that requires fewer type variables to replace is chosen. For example, `Int -> Int` is `T -> T` rather than `K(T, T)` (replacement type variables: K, T) or `T -> U` (replacement type variables: T, U). `(replacement type variable: T) is matched preferentially. +* If the number of replacements is also the same, an error is given as being unselectable. --- -在1型理论的记法中 +1 In type theory notation, `*=>*` [↩](#f1) -2存在可视性等微妙的差异。 +2 There are subtle differences such as visibility. [↩](#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 index a873e4da..17b8326b 100644 --- a/doc/zh_CN/syntax/type/advanced/marker_trait.md +++ b/doc/zh_CN/syntax/type/advanced/marker_trait.md @@ -1,21 +1,20 @@ # Marker Trait -标记托盘是没有要求属性的托盘。也就是说,不安装方法就可以 Impl。如果没有要求属性的话,似乎就没有意义了,但是因为登录了属于该trait的信息,所以可以使用补丁方法,编译器进行特别处理。 +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 subsumed by the `Marker` trait. +`Light` provided as standard is a kind of marker trait. - -```erg +``` erg Light = Subsume Marker ``` - -```erg +``` erg Person = Class {.name = Str; .age = Nat} and Light ``` - -```erg +``` erg M = Subsume Marker MarkedInt = Inherit Int, Impl := M @@ -25,9 +24,8 @@ assert i + 1 == 2 assert i in M ``` -也可以用自变量来排除标记类。 +Marker classes can also be excluded with the `Excluding` argument. - -```erg +``` erg 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 index 6822b5f2..9fdd8479 100644 --- a/doc/zh_CN/syntax/type/advanced/mut_struct.md +++ b/doc/zh_CN/syntax/type/advanced/mut_struct.md @@ -1,34 +1,34 @@ -# 可变结构类型 - -型是可以插入任意的型对象进行替换的箱型。 +# Mutable Structure Type +The ``T!`` type is described as a box type that can be replaced by any ``T`` type object. ```erg -Particle! State: {"base", "excited"}! = Class(..., Impl := Phantom State) -Particle!. - # このメソッドはStateを"base"から"excited"に遷移させる +Particle!State: {"base", "excited"}! = Class(... Impl := Phantom State) +Particle! + # This method moves the State from "base" to "excited". apply_electric_field!(ref! self("base" ~> "excited"), field: Vector) = ... ``` -型虽然可以进行数据的替换,但不能改变其结构。如果用更接近现实的程序行为的说法,(堆上的)大小不能变更。这种类型称为不变结构(可变)类型。 +The ``T!`` type can replace data, but it cannot change its structure. +More like the behavior of a real program, it cannot change its size (on the heap). Such a type is called an immutable structure (mutable) type. -实际上,存在不变结构型无法表示的数据结构。例如,可变长度排列。型可以加入任意的对象,但不能替换为型对象等。 +In fact, there are data structures that cannot be represented by invariant structure types. +For example, a Mutable-length array. The `[T; N]!`type can contain objects of any `[T; N]`, but cannot be replaced by objects of type `[T; N+1]` and so on. -也就是说,长度不能改变。为了改变长度,必须改变型本身的结构。 - -实现那个的是可变结构(可变)型。 +In other words, the length cannot be changed. To change the length, the structure of the type itself must be changed. +This is achieved by Mutable structure (mutable) types. ```erg v = [Str; !0].new() v.push! "Hello" -v: [Str; !1] +v: [Str; !1]. ``` -在可变结构型中,在可变化的类型自变量上添加。在上述情况下,可以将型改为型等。也就是说,可以改变长度。顺便一提,型是型的糖衣句法。 - -可变结构型当然也可以用户定义。但是,需要注意的是,与不变结构型在构成法方面有几个不同。 +For mutable structure types, Mutable type arguments are marked with `!`. In the above case, the type `[Str; !0]` can be changed to `[Str; !1]` and so on. That is, the length can be changed. +Incidentally, the `[T; !N]` type is the sugar-coated syntax of the `ArrayWithLength!(T, !N)` type. +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 Nil T = Class(Impl := Phantom T) diff --git a/doc/zh_CN/syntax/type/advanced/newtype.md b/doc/zh_CN/syntax/type/advanced/newtype.md index 49819332..bf08c2a0 100644 --- a/doc/zh_CN/syntax/type/advanced/newtype.md +++ b/doc/zh_CN/syntax/type/advanced/newtype.md @@ -1,20 +1,18 @@ # Newtype pattern -下面是 Rust 常用的 newtype 模式的 Erg 版本。 - -Erg 可以按如下方式定义类型别名,但仅指同一类型。 +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 UserId = Int ``` -因此,例如,即使类型的数值是 8 位正数,因为它与类型相同,所以可以输入 10 或-1. 如果,-1 是可以弹的,但是 8 位数的性质仅用 Erg 的类型系统是不能表现的。 +So, for example, if you have a specification that a number of type `UserId` must be a positive 8-digit number, you can put in `10` or `-1`, because it is the same as type `Int`. If you set it to `Nat`, `-1` can be rejected, but the nature of an 8-digit number cannot be expressed by Erg's type system alone. -再比如设计某个数据库的系统时,有几类 ID。随着 ID 类型的增加,例如用户 ID,商品 ID,订单 ID 等,可能会出现错误,即向函数传递不同类型的 ID。用户 ID 和商品 ID 等即使在结构上等价,在语义上也是不同的。 - -newtype 模式是这种情况下的理想设计模式。 +Also, for example, when designing a database system, suppose there are several types of IDs: user IDs, product IDs, product IDs, and user IDs. If the number of ID types increases, such as user IDs, product IDs, order IDs, etc., a bug may occur in which different types of IDs are passed to different functions. Even if user IDs and product IDs are structurally equivalent, they are semantically different. +The newtype pattern is a good design pattern for such cases. ```erg UserId = Class {id = Nat} @@ -25,7 +23,9 @@ UserId. i = UserId.new(10000000) print! i # <__main__.UserId object> -i + UserId.new(10000001) # TypeError: + is not implemented between `UserId` and `UserId` +i + UserId.new(10000001) # TypeError: + is not implemented between `UserId` and `UserId ``` -构造函数保证了 8 位数的先决条件。由于丢失了的所有方法,因此必须重新定义每次所需的运算。如果重新定义的成本不相称,最好使用继承。相反,你可能希望使用没有方法的特性,因此请根据具体情况选择适当的方法。 +The constructor guarantees the pre-condition of an 8-digit number. +The `UserId` loses all the methods that `Nat` has, so you have to redefine the necessary operations each time. +If the cost of redefinition is not worth it, it is better to use inheritance. On the other hand, there are cases where the loss of methods is desirable, so choose the appropriate method depending on the situation. diff --git a/doc/zh_CN/syntax/type/advanced/overloading.md b/doc/zh_CN/syntax/type/advanced/overloading.md index 760dcc5b..6f621555 100644 --- a/doc/zh_CN/syntax/type/advanced/overloading.md +++ b/doc/zh_CN/syntax/type/advanced/overloading.md @@ -1,7 +1,7 @@ -# 过载 - -Erg 不支持。也就是说,不能对函数卡印进行多重定义(过载)。但是,通过组合trait类和补丁,可以再现过载的行为。可以使用trait而不是trait类,但在这种情况下,安装的所有类型都成为对象。 +# Overloading +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 Add1 = Trait { @@ -19,10 +19,10 @@ assert add1(1) == 2 assert add1(1.0) == 2.0 ``` -这种通过接受某一类型的所有亚型而产生的多相称为。Erg 中的亚分型多相也包括列多相。 - -如果各型的处理完全相同,也可以写如下。上面的写法用于不同类的行为(但返回类型相同)。使用类型参数的多相称为。参数多相与如下所示的部分型指定并用的情况较多,这种情况下是参数多相和子分型多相的组合技术。 +Such a polymorphism by accepting all subtypes of a type is called __subtyping polymorphism__. +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 add1|T <: Int or Str| x: T = x + 1 @@ -30,8 +30,7 @@ assert add1(1) == 2 assert add1(1.0) == 2.0 ``` -另外,自变量数不同类型的过载可以用默认自变量再现。 - +Also, overloading of types with different numbers of arguments can be reproduced with default arguments. ```erg C = Class {.x = Int; .y = Int} @@ -41,12 +40,12 @@ C. assert C.new(0, 0) == C.new(0) ``` -虽然无法定义根据自变量的数量类型不同等行为完全变化的函数,但 Erg 采取的立场是,如果行为本来就不同,就应该赋予其他名称。 +Erg takes the stance that you cannot define a function that behaves completely differently, such as having a different type depending on the number of arguments, but if the behavior is different to begin with, it should be named differently. -结论是,Erg 禁止过载而采用亚分 + 参数多相是出于以下原因。 - -首先,被超载的函数的定义是分散的。因此,发生错误时很难报告原因所在。另外,通过导入子程序,可能会改变已经定义的子程序的行为。 +In conclusion, Erg prohibits overloading and adopts subtyping plus parametric polymorphism for the following reasons. +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 {id; ...} = import "foo" @@ -56,11 +55,10 @@ id x: Int = x id x: Ratio = x ... id "str" # TypeError: id is not implemented for Str -# But... where did this error come from? +# But... But... where did this error come from? ``` -其次,与默认参数不匹配。当有默认参数的函数被重载时,存在哪个优先的问题。 - +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 f x: Int = ... @@ -69,8 +67,8 @@ f(x: Int, y := 0) = ... 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 f: Num -> Num @@ -78,8 +76,8 @@ f(x: Int): Ratio = ... f(x: Ratio): Int = ... ``` -而且,破坏语法的连贯性。虽然 Erg 禁止变量的再代入,但是过载的语法看起来像是再代入。也不能替换为无名函数。 - +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 # same as `f = x -> body` diff --git a/doc/zh_CN/syntax/type/advanced/phantom.md b/doc/zh_CN/syntax/type/advanced/phantom.md index f9221806..9abfeade 100644 --- a/doc/zh_CN/syntax/type/advanced/phantom.md +++ b/doc/zh_CN/syntax/type/advanced/phantom.md @@ -1,7 +1,7 @@ -# 幽灵类型(Phantom class) - -幽灵型是只为给编译器注释而存在的标记trait。作为幽灵型的使用方法,来看清单的构成。 +# Phantom class +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 Nil = Class() @@ -9,8 +9,7 @@ List T, 0 = Inherit Nil List T, N: Nat = Class {head = T; rest = List(T, N-1)} ``` -这个代码是错误的。 - +This code results in an error. ```erg 3 | List T, 0 = Inherit Nil @@ -19,8 +18,8 @@ TypeConstructionError: since Nil does not have a parameter T, it is not possible hint: use 'Phantom' trait to consume T ``` -这个错误也就是当时不能进行的类型推论。在 Erg 中,类型自变量不能保持未使用状态。在这种情况下,无论什么都可以,所以必须在右边消耗型。如果大小为 0 的类型,例如长度为 0 的元组,则运行时没有开销,非常方便。 - +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 Nil T = Class((T; 0)) @@ -28,10 +27,9 @@ List T, 0 = Inherit Nil T List T, N: Nat = Class {head = T; rest = List(T, N-1)} ``` -这个代码通过编译。但是有点棘手,意图很难理解,而且除了类型自变量是类型以外,不能使用。 - -这种时候正好是幽灵型。幽灵型是将大小为 0 的型一般化的型。 +This code passes compilation. But it's a little tricky to understand the intent, and it can't be used except when the type argument is a type. +In such a case, a phantom type is just what you need. A phantom type is a generalized type of size 0. ```erg Nil T = Class(Impl := Phantom T) @@ -42,17 +40,18 @@ nil = Nil(Int).new() assert nil.__size__ == 0 ``` -保留类型。但是实际上型的大小为 0,没有保存型的对象。 - -另外,除了类型以外还可以消耗任意类型自变量。在以下的例子中,保存了这一的子类型对象的类型自变量。这种情况下,也是不出现在对象实体中的哈利波特型变量。 +`Phantom` holds the type `T`. But in fact the size of the `Phantom T` type is 0 and does not hold an object of type `T`. +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 -VM! State: {"stopped", "running"}! = Class(..., Impl := Phantom! State) +VM! State: {"stopped", "running"}! = Class(... State) VM!("stopped"). start ref! self("stopped" ~> "running") = self.do_something!() - self::set_phantom!("running") + self::set_phantom!("running")) ``` -通过方法或方法进行更新。这是的可变版本)标准补丁提供的方法,其用法与可变类型的相同。 +The `state` is updated via the `update_phantom!` or `set_phantom!` methods. +This is the method provided by the standard patch for `Phantom!` (the variable version of `Phantom`), and its usage is the same as the variable `update!` and `set!`. diff --git a/doc/zh_CN/syntax/type/advanced/projection.md b/doc/zh_CN/syntax/type/advanced/projection.md index e3b79ac1..e9ce3ae4 100644 --- a/doc/zh_CN/syntax/type/advanced/projection.md +++ b/doc/zh_CN/syntax/type/advanced/projection.md @@ -1,11 +1,10 @@ -# 投影类型 - -投影类型表示以下代码中类似于的类型。 +# Projection Type +A projection type represents a type such as ``Self.AddO`` in the following code. ```erg Add R = Trait { - .`_+_` = Self, R -> Self.AddO + . `_+_` = Self, R -> Self.AddO .AddO = Type } @@ -14,8 +13,8 @@ AddForInt. AddO = Int ``` -类型定义了与某个对象的相加。由于方法应该是类型属性,因此的类型声明必须位于缩进下面。类型的 misso 是声明,其投影类型类型的实体具有属于的子类型的类型。例如,。 - +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 assert Int < Add diff --git a/doc/zh_CN/syntax/type/advanced/quantified_dependent.md b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md index 65d9df20..28afb5ed 100644 --- a/doc/zh_CN/syntax/type/advanced/quantified_dependent.md +++ b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md @@ -1,17 +1,15 @@ -# 量化依赖性 - -Erg 有量化类型和依赖类型。这样自然就可以把这两个组合在一起做成模具了。那就是量化依赖型。 +# Quantified Dependent Type +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 -NonNullStr = |N: Nat| StrWithLen N | N != 0 # same as {S | N: Nat; S: StrWithLen N; N != 0} +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} ``` -量化依赖性的标准形式是。其中是类型构建器,是类型参数,是条件表达式。 - -作为左边值的量化依赖类型只能在与原始类型相同的模块中定义方法。 +The standard form of quantified dependent types are `K(A, ... | Pred)`. ``K`` is a type constructor, `A, B` are type arguments, and `Pred` is a conditional expression. +Quantified dependent types as left-hand side values can only define methods in the same module as the original type. ```erg K A: Nat = Class ... @@ -21,10 +19,9 @@ K(A | A >= 1). method ref! self(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 -# Tは具体的な型 +# T is a concrete type 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 index 90990621..ccc907ae 100644 --- a/doc/zh_CN/syntax/type/advanced/shared.md +++ b/doc/zh_CN/syntax/type/advanced/shared.md @@ -1,7 +1,7 @@ -# 共享引用(Shared Reference) - -共享引用是一种必须小心处理的语言功能。例如,在 TypeScript 中,以下代码通过类型检查。 +# Shared Reference +Shared references are one of those language features that must be handled with care. +In TypeScript, for example, the following code will pass type checking. ```typescript class NormalMember {} @@ -14,10 +14,12 @@ normal_area.push(new NormalMember()) console.log(vip_area) # [NormalMember] ``` -普通会员闯入了贵宾区。这是一个明显的 bug,有什么不对呢?原因是共享引用的。是通过复制而创建的,但其类型已发生变化。但是,由于继承了,所以被认为是没有问题的。关系对于不变对象来说是没有问题的。但是,如果像上面那样进行破坏性操作,就会出现破绽。 - -在 Erg 中,由于所有权系统,这些代码被弹出。 +A NormalMember has entered the vip_area. It is an obvious bug, however what went wrong? +The cause is the shared reference [denatured](./variance.md). The `normal_area` is created by copying the `vip_area`, but in doing so the type has changed. +But `VIPMember` inherits from `NormalMember`, so `VIPMember[] <: NormalMember[]`, and this is not a problem. +The relation `VIPMember[] <: NormalMember[]` is fine for immutable objects. However, if you perform a destructive operation like the one above, there will be a breakdown. +In Erg, such code is played back due to the ownership system. ```erg NormalMember = Class() @@ -30,17 +32,17 @@ normal_area.push!(NormalMember.new()) log vip_area # OwnershipError: `vip_room` was moved to `normal_room` ``` -但是,在某些情况下,只有一个对象的所有权是不方便的。为此,Erg 的类型为,它表示共享状态。 - +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 $p1 = SharedCell!.new(!1) $p2 = $p1.mirror!() $p3 = SharedCell!.new(!1) -# $p1 == $p2 比较内容类型 Int! +# If $p1 == $p2, a comparison of the content type Int! assert $p1 == $p2 assert $p1 == $p3 -# 检查 `.addr!` 以查看 $p1 和 $p2 是否相同 +# Check if $p1 and $p2 point to the same thing with `.addr!`. assert $p1.addr!() == $p2.addr!() assert $p1.addr!() != $p3.addr!() $p1.add! 1 @@ -49,12 +51,11 @@ assert $p2 == 2 assert $p3 == 1 ``` -类型的对象必须以开头。此外,由于其性质,它不能是常数。 +Objects of type `SharedCell!` must be prefixed with `$`. Also, by their nature, they cannot be constants. -类型也是类型的子类型,可以调用类型的方法。类型特定的方法只有。 - -一个重要的事实是,是非变态的。即,不定义不同类型参数的包含关系。 +The `SharedCell! T!` type is also a subtype of `T!` and can call methods of type `T!`. The only methods specific to the `SharedCell!T!` type are `.addr!`, `.mirror!` and `.try_take`. +An important fact is that `SharedCell! T!` is non-variant, i.e., no inclusions are defined for different type arguments. ```erg $vip_area = SharedCell!.new([].into [VIPMember; !_]) @@ -62,8 +63,7 @@ $normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError: # hint: SharedCell!(T) is non-variant, which means it cannot have a supertype or a subtype. ``` -但是下面的代码没有问题。在最后一行中,类型转换为参数。 - +However, the following code have not problem. In the last line, it's the `VIPMember` argument that has been typed converted. ```erg $normal_area = SharedCell!.new([].into [NormalMember; !_]) diff --git a/doc/zh_CN/syntax/type/advanced/special.md b/doc/zh_CN/syntax/type/advanced/special.md index d9d0eede..8fa6825b 100644 --- a/doc/zh_CN/syntax/type/advanced/special.md +++ b/doc/zh_CN/syntax/type/advanced/special.md @@ -1,24 +1,22 @@ -# 特殊类型(Self,Super) +# Special types (Self, Super) -表示你的类型。你可以简单地将其用作别名,但请注意,它在派生类型中的含义是不同的(指你自己的类型)。 +`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 +``` erg @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 the type of the base class. The method itself refers to the base class, but the instance uses its own type. - -```erg +``` erg @Inheritable C = Class() @@ -27,16 +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 variables -和可用作结构化任务中的类型变量。这是属于该类型子类型的类。也就是说,在类型中,表示。 +`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 +``` erg Add R = Trait { .AddO = Type .`_+_`: Self, R -> Self.AddO @@ -51,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/zh_CN/syntax/type/advanced/typeof.md b/doc/zh_CN/syntax/type/advanced/typeof.md index 45df6258..ab16bb84 100644 --- a/doc/zh_CN/syntax/type/advanced/typeof.md +++ b/doc/zh_CN/syntax/type/advanced/typeof.md @@ -1,15 +1,14 @@ # Typeof, classof -是可以窥视 Erg 的类型推理系统的函数,其举动很复杂。 +`Typeof` is a function that can peek into Erg's type inference system, and its behavior is complex. - -```erg +``` erg 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} +I = C. new {i = 1} assert Typeof(I) == {X: C | X == I} J: C = ... assert Typeof(J) == {i = Int} @@ -17,24 +16,29 @@ 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. - -```erg +``` erg i: Int = ... assert Typeof(i) == {__valueclass_tag__ = Phantom Int} s: Str = ... assert Typeof(s) == {__valueclass_tag__ = Phantom Str} ``` -用输出的只是结构型。说明了结构型有属性型、筛子型和(真的)代数演算型。这些是独立的类型(存在推理的优先顺序),不发生推理的重解。属性型、代数运算型可能跨越多个类,而筛型是单一类的亚型。Erg 尽可能地将对象的类型作为筛子类型进行推论,当不能进行推论时,将筛子类型的基类扩大到结构化(后述)的类型。 +`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`. - -```erg +``` erg C = Class {i = Int} assert Structure(C) == {i = Int} D = Inherit C @@ -43,13 +47,13 @@ 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 structurized -# 你实际上不能用 __valueclass_tag__ 定义一条记录,但在概念上 +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))} -# 标记类也是带有 __valueclass_tag__ 的记录类型 +# Marker classes are also record types with __valueclass_tag__ M = Inherit Marker assert Structure(M) == {__valueclass_tag__ = Phantom M} D = Inherit(C and M) @@ -58,4 +62,4 @@ 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 index 7696edfd..6a7bec59 100644 --- a/doc/zh_CN/syntax/type/advanced/variance.md +++ b/doc/zh_CN/syntax/type/advanced/variance.md @@ -1,128 +1,143 @@ -# 退化(variance) +# variation -Erg 可以进行多相型的分型,但是有一部分必须注意的地方。 +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) => NoneTypeArray.pop!: Self(T).() => T +Array.push!: Self(T).(T) => NoneType +Array.pop!: Self(T).() => T -我们可以直观地了解到, +As can be intuitively understood, -* 当时OK(将上传至即可) -* 当时为 NG -* 是 NG -* 好的 +* `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 -前者可能看起来很奇怪。虽然是,但将其作为自变量的函数的包含关系却发生了逆转。在类型理论中,这种关系(的类型关系)称为反变(contravariant),相反,的类型关系称为共变(covariant)。也就是说,可以说函数型是关于自变量的类型的反变,关于返回值的类型的共变。听起来很复杂,但正如刚才看到的那样,如果套用实例来考虑的话,这是一个合理的规则。即便如此,如果还不明白的话,可以考虑如下。 +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. -Erg 的设计方针中有“输入的类型大,输出的类型小”。这可以从函数的变性说起。从上面的规则来看,输入型是大的一方整体来说是小的类型。因为通用函数明显比专用函数稀少。而且输出型越小整体越小。 +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 还有一种变性。它是非变性的。这是编入型中等具有的变性。这意味着,关于的 2 个类型,即使存在包含关系,也不能在之间进行转换。这是因为是共享参照。有关详细信息,请参见。 +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. - -```erg +``` erg |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. - -```erg -# U < A < T -{... | A <: T; A :> U} +``` erg +# U U} ``` -下面是使用变性规范的代码示例。 +Here is an example of code that uses a variable specification. - -```erg +``` erg show|S <: Show| s: S = log s -Nil T = Class(Impl=Phantom T) +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} + 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. - -```erg +``` erg ... 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} + 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 ``` -即使在这种情况下,Erg 编译器也可以很好地推论的上限和下限类型。但是,请注意,Erg 编译器并不理解方法的含义。编译器只是根据变量和类型变量的使用方式机械地推理和推导类型关系。 +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. -如注释所示,的类型的子类(如果,则等)。即推论为。此约束禁止更改参数类型的上传(e.g.)。但是,请注意,约束并没有改变函数类型的包含关系。这一事实保持不变,只是不能在方法中执行这样的上播。同样,从的转换在的约束条件下是可能的,因此可以这样推论退化规范。此约束禁止更改的返回类型的上传(e.g.)。 +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. - -```erg +``` erg ... List T = Class {head = T; rest = Cons T} List(T). - push|U :> T|(self, x: U): List T = Self.new {head = x; rest = self} + 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`. Or you may have the wrong variance specification. -# TypeWarning: `U` in the `.upcast` cannot take anything other than `U == T`. Replace `U` with `T`. Or you may have the wrong variance specification. +# 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:用户定义的变体 +## 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`. - -```erg +``` erg K T = Class(...) assert not K(Str) <= K(Object) assert not K(Str) >= K(Object) InputStream T = Class ..., Impl := Inputs(T) -# Objectを受け入れるストリームは、Strを受け入れるともみなせる +# A stream that accepts Objects can also be considered to accept Strs assert InputStream(Str) > InputStream(Object) OutputStream T = Class ..., Impl := Outputs(T) -# Strを出力するストリームは、Objectを出力するともみなせる +# 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/zh_CN/syntax/type/advanced/widening.md b/doc/zh_CN/syntax/type/advanced/widening.md index c8ba5eca..7d0a9b47 100644 --- a/doc/zh_CN/syntax/type/advanced/widening.md +++ b/doc/zh_CN/syntax/type/advanced/widening.md @@ -1,34 +1,32 @@ -# 类型扩展(Type Widening) +# Type Widening -例如定义如下的多相关数。 +For example, define the polycorrelation coefficient as follows. - -```erg +``` erg 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. - -```erg +``` erg assert ids(1, 2) == (1, 2) assert ids(1, 2.0) == (1.0, 2.0) -ids(1, "a") # TypeError +ids(1, "a") #TypeError ``` -那么,拥有其他结构型的型的情况又会怎样呢? +Now, what about types that have different derived types? - -```erg +``` erg i: Int or Str j: Int or NoneType ids(i, j) # ? ``` -在解释这一点之前,我们必须注意一个事实,即 Erg 类型系统实际上没有看到类(在运行时)。 +Before explaining this, we have to focus on the fact that Erg's type system doesn't actually look at (runtime) classes. - -```erg +``` erg 1: {__valueclass_tag__ = Phantom Int} 2: {__valueclass_tag__ = Phantom Int} 2.0: {__valueclass_tag__ = Phantom Ratio} @@ -38,12 +36,14 @@ ids(1, 2.0): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phanto ids(1, "a"): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Str} == Never # TypeError ``` -之所以没有看到类,是因为有时不能正确看到,这是因为在 Erg 中对象的类属于运行时信息。例如,型对象的类是或者,这是哪一个只有执行后才能知道。当然,型的对象的类是由确定的,这时从类型系统中也能看到的结构型。 +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`. -现在,让我们回到另一个结构类型的例子。从结论上来说,上面的代码如果没有类型,就会成为 TypeError。但是,如果用类型注释进行类型扩大,编译就可以通过。 +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. - -```erg +``` erg i: Int or Str j: Int or NoneType ids(i, j) # TypeError: types of i and j not matched @@ -51,43 +51,42 @@ ids(i, j) # TypeError: types of i and j not matched 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 中,返回值类型不一致时默认为错误。 +Erg defaults to an error if return types do not match. - -```erg +``` erg parse_to_int s: Str = if not s.is_numeric(): do parse_to_int::return error("not numeric") ... # return Int object -# TypeError: mismatch types of return values -# 3 | do parse_to_int::return error("not numeric") -# └─ Error -# 4 | ... -# └ Int +# TypeError: mismatched types of return values +# 3 | do parse_to_int::return error("not numeric") +# └─ Error +# 4 | ... +# └ Int ``` -为了解决这一问题,必须将返回类型显式指定为 Or 类型。 +In order to solve this, it is necessary to explicitly specify the return type as Or type. - -```erg +``` erg 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/zh_CN/tips.md b/doc/zh_CN/tips.md index 94df3d72..b90de192 100644 --- a/doc/zh_CN/tips.md +++ b/doc/zh_CN/tips.md @@ -1,11 +1,11 @@ # Tips -## 我想改变错误的显示语言 +## Want to change the language in which errors are displayed -请下载语言版本的 erg。但是,标准库之外可能不提供多语言支持。 - -## 只想改变记录的特定属性 +Please download Erg for your language. +However, external libraries may not support multiple languages. +## Want to change only certain attributes of a record ```erg record: {.name = Str; .age = Nat; .height = CentiMeter} @@ -13,23 +13,21 @@ record: {.name = Str; .age = Nat; .height = CentiMeter} mut_record = {.height = !height; ...rest} ``` -## 我要阴影变量 +## Want to shadow variables -Erg 不能在同一范围内进行阴影。但是,如果作用域变了,就可以重新定义,所以最好使用即时块。 +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 -# T!型オブジェクトを取得し、最終的にT型として変数へ代入 +````erg +## Get a T!-type object and finally assign it to a variable as type T x: T = x: T! = foo() x.bar!() x.freeze() -``` +```` -## 想办法重用 final class(不可继承类) - -我们来做个说唱班。这就是所谓的合成模式。 +## Want to reuse a final class (non-inheritable class) somehow +You can create a wrapper class. This is a so-called composition pattern. ```erg FinalWrapper = Class {inner = FinalClass} @@ -39,10 +37,11 @@ FinalWrapper. ... ``` -## 要使用非字符串枚举类型 - -你可以定义其他语言中常见的传统枚举类型(代数数据类型),如下所示。当实现时,类和实例是等同的。此外,如果使用,则可选择的类型将自动定义为重定向属性。 +## Want to use an enumerated type that is not a string +You can define a traditional enumerated type (algebraic data type) commonly found in other languages as follows +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 Ok = Class Impl := Singleton @@ -53,10 +52,9 @@ stat: Status = Status.cons(ErrWithInfo) {info = "error caused by ..."} match! stat: Status.Ok -> ... Status.Err -> ... - Status.ErrWithInfo::{info;} -> ... + Status.ErrWithInfo::{info} -> ... ``` - ```erg Status = Enum Ok, Err, ErrWithInfo # is equivalent to @@ -67,11 +65,10 @@ Status. ErrWithInfo = ErrWithInfo ``` -## 一开始想要 enumerate +## I want to enumerate at the beginning of 1 method 1: - ```erg arr = [...] for! arr.iter().enumerate(start: 1), i => @@ -80,24 +77,22 @@ for! arr.iter().enumerate(start: 1), i => method 2: - ```erg arr = [...] -for! arr.iter().zip(1..), i => +for! arr.iter().zip(1...) , i => ... ``` -## 我想测试我的私有 API(白盒) - -名为的模块可以专门访问的专用 API。模块不能导入,因此保持了隐藏性。 +## Want to test a (white box) non-public API +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 # foo.er private x = ... ``` - ```erg # foo.test.er foo = import "foo" @@ -109,10 +104,9 @@ foo = import "foo" ... ``` -## 要定义外部只读(可变)属性 - -最好将属性设为私有,然后定义 getta。 +## Want to define a (variable) attribute that is read-only from the outside +You can make the attribute private and define a getter. ```erg C = Class {v = Int!} @@ -124,10 +118,9 @@ C. ... ``` -## 要在类型系统上标识参数名称 - -将参数作为记录接收比较好。 +## Want the argument names to be identified on the type system +You can receive arguments by record. ```erg Point = {x = Int; y = Int} @@ -137,6 +130,6 @@ norm({x: Int; y: Int}): Int = x**2 + y**2 assert norm({x = 1; y = 2}) == norm({y = 2; x = 1}) ``` -## 我不想发出警告 +## Want to stop warnings -没有用于阻止 Erg 警告的选项(这是故意的设计)。重写代码。 +There is no option in Erg to stop warnings (this is by design). Please rewrite your code. diff --git a/doc/zh_CN/tools/build.md b/doc/zh_CN/tools/build.md index ac3e8dc5..e8df33b7 100644 --- a/doc/zh_CN/tools/build.md +++ b/doc/zh_CN/tools/build.md @@ -1,13 +1,14 @@ -# build 子命令 +# build subcommand -build 子命令用于构建软件包。缺省构建过程如下所示。 +The build subcommand builds the package. +The steps performed in the default build are as follows: -1. 检查注释/文档(doc 以下的 md 文件)中的代码。 -2. 编译包所需的代码。 -3. 对于应用程序包,生成与命令对应的批处理文件或 shell 脚本。 -4. 运行测试。 +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. -* 调试构建时:build/debug -* 版本构建时:build/release +* During debug build: build/debug +* For release build: build/release \ No newline at end of file diff --git a/doc/zh_CN/tools/env.md b/doc/zh_CN/tools/env.md index f6c50ac6..19673686 100644 --- a/doc/zh_CN/tools/env.md +++ b/doc/zh_CN/tools/env.md @@ -1,3 +1,7 @@ -# env 子命令 +# env subcommand -env 子命令指定 erg 执行环境。在中创建新的运行时环境。当交互工具打开并指定 erg 版本时,将安装该版本的 erg(如果已安装,则将其用作新环境)。你可以在中切换环境。创建的环境可以在中进行编辑,可以预安装软件包或指定其他语言的依赖关系。该命令的最大特征是可以将在中再现环境的信息作为文件输出。据此,可以在与他人相同的环境下马上开始开发。并且,在中,可以像软件包那样公开环境。 +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/zh_CN/tools/fmt.md b/doc/zh_CN/tools/fmt.md index 8b6cfdf3..49f22b63 100644 --- a/doc/zh_CN/tools/fmt.md +++ b/doc/zh_CN/tools/fmt.md @@ -1,5 +1,6 @@ # fmt -fmt 子命令允许在中设置代码格式。以下是常用的旗帜。 +Code formatting can be done with the fmt subcommand. +Commonly used flags are: -* explicit-type:自动完成省略类型的位置。 +* explicit-type: Automatically completes where the type specification is omitted. \ No newline at end of file diff --git a/doc/zh_CN/tools/install.md b/doc/zh_CN/tools/install.md index e108a7af..0343a0ca 100644 --- a/doc/zh_CN/tools/install.md +++ b/doc/zh_CN/tools/install.md @@ -1,9 +1,10 @@ -# install 子命令 +# install subcommand -install 可以安装在注册表站点注册的软件包。基本用法与包管理器(如 cargo)相同。 +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 -* 如果有名字相似的软件包名称,并且下载量比那个多 10 倍以上,就会出现错误输入的提示。由此,可以防止 typo squatting。 -* 如果软件包大小很大(50 MB 或更大),请查看大小以确定是否安装。 -* 如果软件包为 duplicated,则提示替换软件包。 +* 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/zh_CN/tools/pack.md b/doc/zh_CN/tools/pack.md index b734adee..ae02aa88 100644 --- a/doc/zh_CN/tools/pack.md +++ b/doc/zh_CN/tools/pack.md @@ -1,41 +1,43 @@ -# 包管理器 +# package manager -Erg 标配包管理器,可通过子命令调用。以下是典型的选项。 +Erg comes standard with a package manager, which you can invoke with the `pack` subcommand. +The following are typical options. -* :将当前目录初始化为软件包。生成文件和目录。指定是可执行文件的软件包,指定是库的软件包,指定是两个软件包。如果指定,它将自动放置许可证文件。 -* :构建包。执行测试并进行优化。工件配置在或。 -* :安装软件包。对于库,被放置在以下,应用程序被放置在作为 shell 脚本。添加时进行最优化。 -* :构建软件包并运行应用程序(仅限 app 软件包)。 -* 删除:build 目录中的内容。 -* :测试软件包。有关详细信息,请参见。 -* :发布/发布软件包。我需要 GitHub 帐户和公钥。 +* `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. -另外,本文档说明了管理自己的软件包时的方法。要安装或搜索外部软件包,请参阅。此外,有关 Erg 的封装系统,请参见。 - -## 整个软件包的标准目录配置(适用于应用程序软件包) +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 # パッケージのルートディレクトリ - /build # ビルド結果を格納するディレクトリ - /debug # デバッグビルド時の成果物 - /release # リリースビルド時の成果物 - /doc # ドキュメント(さらに`en`, `ja`などのサブディレクトリに分けることで各国語対応可能) - /src # ソースコード - /main.er # main関数を定義するファイル - /tests # (ブラックボックス)テストファイルを格納するディレクトリ - /package.er # パッケージの設定を定義するファイル +/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 +##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`. - -```erg +``` erg name = "example" # package name author = "John Smith" # package author name -version = "0.1.0" +version="0.1.0" description = "An awesome package" categories = ["cli"] # package categories type = "app" # "app" or "lib" @@ -45,38 +47,54 @@ 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 + 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") + baz = pack("baz", "1.1.0") } -deprecated = False +deprecated=False successors = [] # alternative packages (when a package is deprecated) ``` -## 语义 +## Semantic versioning -Erg 软件包根据指定版本。语义版本化通常以格式指定,其中 x,y 和 z 是大于或等于 0 的整数。每个数字的含义如下。 +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:主要版本(增加一个,以进行破坏兼容性的更新) -* y:次要版本(兼容更新(如 API 添加或过时)时增加 1;补丁版本升级(如错误修复) -* z:修补程序版本(错误修复和兼容性较小的更改增加 1;严重的不兼容修复将在主要版本升级中提供) +* 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) -但是,在默认情况下,对版本的更改始终不兼容。如果你想在版本升级时保持兼容性,请在后面指定(Erg 自己的规则)。例如,如果你想添加,同时兼容,即升级到,请指定。如果已修复错误,请指定。这将确保该版本与上一版本兼容。如果你想将升级为,也可以使用此选项。也就是说,与上一个版本兼容。 +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 软件包管理器严格执行以上规则,任何与规则相冲突的软件包更新都将被拒绝。Erg 包管理器与版本控制系统(如 git)配合使用,在 publish 包时检测代码差异,以验证版本化的有效性。具体地说,包管理器看 API 的类型。如果类型是旧版本的子类型,则将更改视为兼容(请注意,这不是完全验证。可能存在类型上兼容但语义上不兼容的更改。这是开发人员的工作。 +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:语义版本化问题及其对策 +### Appendix: Semantic Versioning Issues and Countermeasures -语义版本化中存在(至少)两个已知问题。首先,语义版本化可能会施加过大的限制。在语义版本化中,只有一个不兼容的 API 更改会提升整个包的主要版本。这会导致“我想尝试一个新的 API,但因为我必须处理另一个不兼容的 API 更改而推迟升级”。还有一点,语义版本可能承诺过高。如上一节所述,API 的“兼容更改”在理论上无法证明。如果你指定要版本的软件包,则从语义版本的角度来看,可以使用大于或等于小于的所有软件包(不能使用)。但是,实际上,软件包开发人员无意中使用 API 可能会导致构建不成功。 +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 采取了一种方法,允许你同时使用不同版本的软件包(通过重命名)。这允许你在引入部分版本 2 的 API 的同时继续使用版本 1 的 API。此外,虽然不是很理想,但如果只有某些次要版本的 API 可以在没有错误的情况下使用,则可以将其保留到下一个版本。 +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 -可以使用子命令发布软件包。我需要一个 GitHub 账户来发表。缺省情况下,软件包注册为。如果满足一定的条件(下载数量,维护频率等),则可以申请注册省略所有者名称的别名。软件包名称不区分大小写和分隔符,如。 +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/zh_CN/tools/repl.md b/doc/zh_CN/tools/repl.md index 4781f7e0..b22166c8 100644 --- a/doc/zh_CN/tools/repl.md +++ b/doc/zh_CN/tools/repl.md @@ -1,9 +1,9 @@ -# REPL +#REPL -如果命令没有参数,则会调用 REPL。你也可以使用子命令启动它。还可以指定以下标志。 - -* typed:显示对象及其类型。 +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 @@ -12,4 +12,4 @@ Erg interpreter ... (tags/?:, ...) on ... 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 index bc84403e..6e449ac8 100644 --- a/doc/zh_CN/tools/test.md +++ b/doc/zh_CN/tools/test.md @@ -1,13 +1,13 @@ -# test 子命令 +# test subcommand -erg 指令中有 test 这个子指令,进行测试安装以及执行的支援。 +The erg command has a subcommand called test, which supports test implementation and execution. -## 测试装饰器(@Test) +## Test decorator (@Test) -Erg 使用命令测试软件包中的目录或文件中的子程序。子例程负责黑盒测试(不测试私有函数),子例程负责白盒测试(也测试私有函数)。 +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). - -```erg +``` erg # tests/test1.er {add; ...} = import "foo" @@ -16,28 +16,30 @@ test_1_plus_n(n: Nat) = assert add(1, n) == n + 1 ``` -运行结果显示为摘要,并且可以以各种文件格式(.md,.csv,etc.)输出。 +The execution result is displayed as a summary and can be output in various file formats (.md, .csv, etc.). ## Doc Test -在 Erg 中,,以后成为注释行,但在中成为 doc comment,可以通过 VSCode 等编辑器标记注释。并且,如果 doc comment 中的源代码被指定为 erg,则通过 erg 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. - -```erg -VM = ... +``` erg +VMs =... ... #[[ execute commands. - ```erg + ``` erg # 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 = + ]]# + .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/zh_TW/API/consts.md b/doc/zh_TW/API/consts.md deleted file mode 100644 index b42e2f5b..00000000 --- a/doc/zh_TW/API/consts.md +++ /dev/null @@ -1,13 +0,0 @@ -# 内置常量 - -## True - -## False - -## None - -## Ellipsis - -## NotImplemented - -## Inf diff --git a/doc/zh_TW/API/funcs.md b/doc/zh_TW/API/funcs.md deleted file mode 100644 index 0dc265a6..00000000 --- a/doc/zh_TW/API/funcs.md +++ /dev/null @@ -1,121 +0,0 @@ -# 功能 - -## 基本功能 - -### 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` 不可訪問 - -```erg -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 - -```erg -rep = repeat 1 # Repeater(1) -for! rep, i => - print! i -# 1 1 1 1 1 ... -``` - -### dup|T; N|(x: T, N: Nat) -> [T; N] - -```erg -[a, b, c] = dup new(), 3 -print! a # -print! a == b # False -``` - -### cycle|T|(it: Iterable T) -> CycleIterator T - -```erg -cycle([0, 1]).take 4 # [0, 1, 0, 1] -cycle("hello").take 3 # "hellohellohello" -``` - -## 定數式関數 - -### Class - -創建一個新類。與`Inherit`不同,通過`Class`傳遞與基類型無關,並且方法會丟失 -您將無法進行比較,但您可以進行模式匹配等操作 - -```erg -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`。 -如果您將其用於類型規範,則會出現警告。 - -```erg -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 deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/API/modules/external/alstruct.md b/doc/zh_TW/API/modules/external/alstruct.md deleted file mode 100644 index fabb7330..00000000 --- a/doc/zh_TW/API/modules/external/alstruct.md +++ /dev/null @@ -1,57 +0,0 @@ -# alstruct - -提供表示代數結構的托盤和相應補丁的模塊。 - -* member - -## binop - -``` erg -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 -``` - -## semigroup - -``` erg -SemiGroup Op: Kind 2 = Op(Self, Self) - -IntIsSemiGroupAdd = Patch Int, Impl=SemiGroup Add - -Int <: SemiGroup Add -``` - -## functor - -``` erg -## * 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 -} -``` - -## applicative - -``` erg -## * Identity law: x.app(x. pure(id)) == x -Applicative = Subsume Functor, Additional: { -t: . pure | type | = t - > self t -. app | t, u: type | = (self (t), self (t - > u)) - > self u -} -``` - -## monad - -``` erg -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 deleted file mode 100644 index 8570237d..00000000 --- a/doc/zh_TW/API/modules/repl.md +++ /dev/null @@ -1,24 +0,0 @@ -# module `repl` - -provides REPL(Read-Eval-Print-Loop)-related APIs。 - -## functions - -* ` gui _ help ` - -在瀏覽器中顯示關於對象的信息。離線也可以使用。 - -## types - -### Guess = Object - -## ## methods - -* * ` . guess ` - -根據所給出的自變量和返回值來推測函數。 - -``` erg -guess((1,), 2) # -[1, 2] . guess(3、4),[1,2,3,4])# < array (t, n) . concat method > -``` \ No newline at end of file diff --git a/doc/zh_TW/API/modules/status.md b/doc/zh_TW/API/modules/status.md deleted file mode 100644 index c4f16ba0..00000000 --- a/doc/zh_TW/API/modules/status.md +++ /dev/null @@ -1,6 +0,0 @@ -# module `status` - -定義了表示狀態的類型。請根據情況排除選項使用。 - -* 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 deleted file mode 100644 index 05dec139..00000000 --- a/doc/zh_TW/API/modules/unit.md +++ /dev/null @@ -1,73 +0,0 @@ -# module `unit` - -`unit`模塊是將數值計算中常用的單位定義為型的模塊。 -Erg的數值型有`Nat`, `Int`, `Ratio`等。但是,這些模型並沒有掌握“這意味著什麼”的信息,只能進行米和碼之間的加法等荒唐的計算。 -通過使用`unit`模塊,可以防止將單位不同的數值傳遞給函數的錯誤。 -這樣的失誤是實際發生,而且[單位系的錯誤火星探測器失踪](http://www.sydrose.com/case100/287/)等,可能引起嚴重的bug。 -如果想在進行數值計算的基礎上提高代碼的魯棒性的話應該事先使用這個模塊。 - -``` erg -{*} = import "unit" - -等價於x = 6m# `x = Meter.new(6)` -等價於t = 3s# `t = c.new(3)` -# m/s是速度的單位對象,Velocity型 -print !x/ t# 2m/s -print !x + 4m# 10m -print !x + 2s# TypeError: `+`(Meter, Sec) is not implemented -``` - -`m`, `s`, `m/s`這樣的對像被稱為單位對象。它本身就有1m, 1s, 1m/s的意思。 `m/s`可以說是m和s的合成產生的單位對象。 - -unit將以下單位定義為型。國際單位制(SI)。 - -* 長度:Meter(單位常數:m) -* 質量:KiloGram(單位常數:kg, g = 0.001kg) -* 時間:Sec(分鐘、時間、日、年等有由Sec生成的minute, hour, day, year等常數) -* 電流:Amper(單位常數:a) -* 溫度:Kelvin(單位常數:k, Fahren,也有Celsius型,可相互轉換) -* 物質的量:Mol(單位常數:Mol) -* 光度:Candela(單位常數:cd) - -另外,`Unit1`, `UnitMul`, `UnitDiv`這樣的類型被定義,使用這個可以合成基本類型創建新的單位。 -例如,振動頻率的單位赫茲(hertz)是用振動週期(秒)的倒數來定義的,所以`UnitDiv(Unit1, Sec)`。 -想要把這個類型視為有意義的類型(想要加上專用的方法,等等)的時候,[補丁](./../ . ./syntax/type/07_patch.md)。 - -``` erg -Hertz = Patch UnitDiv(Unit1, Sec) -SquareMeter = UnitMul(Meter, Meter) -``` - -輔助單位也被預先定義了幾個。 - -* 振動頻率:Hertz(hz) -* 力:Newton。 -* 能量:Joule(j) -* 工作量:Watt(w) -* 電勢:Volt(v) -* 電阻:Ohm(Ohm) -* 速度:Velocity(m/s) -* 面積:SquareMeter(m**2) -* 體積:CubicMeter(m**3) (litre = 10e- 3m **3) -* 角度:Degree(deg) (rad = 180/pi deg) -* 長度:Feet, Yard, Inch, Mile, Ly, Au, Angstrom -* 重量:Pond - -另外,前綴也有定義。 - -* 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單位系unit模塊的希望時,外部庫([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 deleted file mode 100644 index 0f950ba5..00000000 --- a/doc/zh_TW/API/modules/unsound.md +++ /dev/null @@ -1,24 +0,0 @@ -# module `unsound` - -提供的api執行在Erg的類型系統中無法保證安全的不健全和不安全的操作。 - -## `unsafe!` - -執行一個`Unsafe`過程。就像Rust一樣,`Unsafe`的api不能被直接調用,而是全部作為高階函數傳遞給這個過程。 - -``` erg -unsound = import "unsound" - -i = unsound.unsafe!do !: -# convert `Result Int` to `Int` -unsound.transmute input !() . try into (int), int -``` - -## transmute - -將第一個參數的對象轉換成第二個參數的類型。不進行模板檢查。 -這個函數損害型系統的型安全性。使用的時候請進行驗證等。 - -## auto_transmute - -與`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 deleted file mode 100644 index 21883d6e..00000000 --- a/doc/zh_TW/API/operators.md +++ /dev/null @@ -1,64 +0,0 @@ -# 運算符 - -## 中綴運算符 - -### `_+_`|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 deleted file mode 100644 index e86d53ff..00000000 --- a/doc/zh_TW/API/procs.md +++ /dev/null @@ -1,39 +0,0 @@ -# 過程 - -## print! - -``` erg -打印! (x)->無類型 -``` - - 使用換行符返回 x。 - -##調試&排除; - -``` erg -調試! (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 deleted file mode 100644 index b1cab7c9..00000000 --- a/doc/zh_TW/API/special.md +++ /dev/null @@ -1,175 +0,0 @@ -# 特殊形式 - -特殊形式是不能在 Erg 類型系統中表達的運算符、子程序(等等)。它被`包圍,但實際上無法捕獲。 -此外,為方便起見,還出現了“Pattern”、“Body”和“Conv”等類型,但不存在此類類型。它的含義也取決於上下文。 - -## `=`(pat: Pattern, body: Body) -> NoneType - -將 body 分配給 pat 作為變量。如果變量已存在於同一範圍內或與 pat 不匹配,則引發錯誤。 -它還用於記錄屬性定義和默認參數。 - -```erg -record = {i = 1; j = 2} -f(x: Int, y = 2) = ... -``` - -當主體是類型或函數時,`=` 具有特殊行為。 -左側的變量名嵌入到右側的對像中。 - -```erg -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 # -``` - -`=` 運算符的返回值為“未定義”。 -函數中的多個賦值和 `=` 會導致語法錯誤。 - -``` 呃 -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 匹配。如果它們不匹配,則拋出編譯錯誤。 - -```erg -a: Int -f x: Int, y: Int = x / y -``` - -也用於 `:` 應用樣式。 - -```erg -f x: - y - z -``` - -像`:`和`=`一樣,運算的結果是不確定的。 - -```erg -_ = 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。 - -```erg -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”。但是,無法刪除內置對象。 - -```erg -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 時才會計算表達式。 - -```erg -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型。 - -### `...` - -展開嵌套集合。它也可以用於模式匹配。 - -``` erg -[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 deleted file mode 100644 index 8c6a8690..00000000 --- a/doc/zh_TW/API/types.md +++ /dev/null @@ -1,262 +0,0 @@ -# 內置 Erg 類型列表 - -類型本身的屬性不存儲在 `.__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 等。 - -### 類型 - -* `__supers__`:超類型(`__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 deleted file mode 100644 index 3c45fb7b..00000000 --- a/doc/zh_TW/API/types/classes/Array!(T).md +++ /dev/null @@ -1,3 +0,0 @@ -# Array! T - -表示可變長度數組的類型。在編譯時長度未知時使用。有一個語法糖叫做` [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 deleted file mode 100644 index 107b4366..00000000 --- a/doc/zh_TW/API/types/classes/Array(T).md +++ /dev/null @@ -1,3 +0,0 @@ -# Array T: Type - -由`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 deleted file mode 100644 index f6d9694e..00000000 --- a/doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md +++ /dev/null @@ -1,34 +0,0 @@ -# ArrayWithLen T: Type, N: Nat - -`[T; N]`是語法糖。還有一個[`Array` 類型](./Array.md)省略了長度。 - -## methods - -* values_at(self, selectors: [Nat; N]) -> [T; N] - -```erg -assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] -``` - -* all(self, pred: T -> Bool) -> Bool - 返回是否所有元素都滿足 pred。 - 如果元素為 0,則無論 pred 為 `True`,但會發出警告。 - 該規範本身已被多種語言採用,是邏輯一致性所必需的。 - - ```erg - assert [].all(_ -> False) - ``` - - ```python - assert all(False for _ in []) - ``` - -## methods of ArrayWithLen T, N | T <: Eq - -* freq self -> [{T: Nat}] - 返回對像出現的次數。 - -```erg -assert ["a", "b", "c", "b", "c", "b"].freq() \ -== [{"a", 1}, {"b": 3}, {"c": 2}] -``` \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md deleted file mode 100644 index c38879d9..00000000 --- a/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md +++ /dev/null @@ -1,26 +0,0 @@ -# ArrayWithMutLength! T: Type, N: Nat! - -一個可變長度數組,其長度在編譯時已知。還有語法糖`ArrayWithMutLength(T, !N) == [T; !N]` - -## methods - -* 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 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Class.md b/doc/zh_TW/API/types/classes/Class.md deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/API/types/classes/Complex.md b/doc/zh_TW/API/types/classes/Complex.md deleted file mode 100644 index de15086f..00000000 --- a/doc/zh_TW/API/types/classes/Complex.md +++ /dev/null @@ -1,14 +0,0 @@ -# Complex - -表示複數的類型。在 Erg 中表示數字的類型,例如 Float、Int 和 Nat,通常在頂部有這種類型 - -## supers - -Num and Norm - -## methods - -* abs -* conjugate -* imag -* real \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Dict!.md b/doc/zh_TW/API/types/classes/Dict!.md deleted file mode 100644 index ddea3c04..00000000 --- a/doc/zh_TW/API/types/classes/Dict!.md +++ /dev/null @@ -1,7 +0,0 @@ -# Dict! K, V - -表示字典(哈希Map)的類型。有一個語法糖叫做`{K: V}` - -## methods - -* invert!(self) -> Self! V, K \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Either.md b/doc/zh_TW/API/types/classes/Either.md deleted file mode 100644 index 3bf6f0ce..00000000 --- a/doc/zh_TW/API/types/classes/Either.md +++ /dev/null @@ -1,12 +0,0 @@ -# Either L, R = L or R - -表示L或R的類型。您可以將其視為Or類型的二元形式 - -## methods - -* orl -* orr -* andl -* andr -* mapl -* mapr \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Float.md b/doc/zh_TW/API/types/classes/Float.md deleted file mode 100644 index 08ff7971..00000000 --- a/doc/zh_TW/API/types/classes/Float.md +++ /dev/null @@ -1,21 +0,0 @@ -# Float size - -表示實數(包含小數的數)的類型。符合IEEE 754的浮點數,在其他語言中一般是float的類型。 -Float的大小為8(1byte)~128(16byte)。如果只是Float,則表示`Float64`。 -Erg 中的 0.1 實際上屬於 Ratio 類型,而不是 Float 類型。沒有浮點類型字面量,它是由 `(Ratio object)f64` 生成的(例如 (1/2)f64, 15f64)。 f64 對應實數 1 - -## supers - -Complex and Ord - -## methods - -* sgn(self) -> {-1, 0, 1} - 返回標誌 - -* truncate(self) -> Int - 返回最接近自身的整數 - -* separate(self) -> [Str] -* separate(self, dight: Nat) -> [Str] - 按digit位數劃分。沒有自變量 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Function(N).md b/doc/zh_TW/API/types/classes/Function(N).md deleted file mode 100644 index 0955f2ec..00000000 --- a/doc/zh_TW/API/types/classes/Function(N).md +++ /dev/null @@ -1,9 +0,0 @@ -# Function N: Nat - -## methods of Function 1 - -* then(self, g: Self) -> Self - -```erg -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 deleted file mode 100644 index afcee108..00000000 --- a/doc/zh_TW/API/types/classes/Inf.md +++ /dev/null @@ -1,7 +0,0 @@ -# Inf - -Inf是一個類,其唯一實例是inf。 -inf的主要用途是用於區間類型。 -例如,大於等於 2 的整數類型是 `2.. Self(L1+L2, R1+R2) - -正常加法。 `Int` 和 `Nat` 的添加在此定義為假裝它在每個類中定義 - -```erg -0..10 + 1..12 == 1..22 -Int + 0..10 == _..|Int|_ + 0..10 == _..|Int|_ == Int -Nat + Nat == 0.._ + 0.._ == 0.._ == Nat -``` \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Interval.md b/doc/zh_TW/API/types/classes/Interval.md deleted file mode 100644 index 5f213e9b..00000000 --- a/doc/zh_TW/API/types/classes/Interval.md +++ /dev/null @@ -1,18 +0,0 @@ -# Interval begin, end := WellOrder - -表示有序集合類型 (WellOrder) 的子類型的類型。 Interval 類型具有派生類型,例如 PreOpen(x<..y)。 - -```erg -Months = 1..12 -Alphabet = "a".."z" -Weekdays = Monday..Friday -Winter = November..December or January..February -``` - -```erg -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 deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/API/types/classes/Kind(N).md b/doc/zh_TW/API/types/classes/Kind(N).md deleted file mode 100644 index 4a72aec9..00000000 --- a/doc/zh_TW/API/types/classes/Kind(N).md +++ /dev/null @@ -1,5 +0,0 @@ -# Kind N: Nat - -```erg -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 deleted file mode 100644 index 18c69b27..00000000 --- a/doc/zh_TW/API/types/classes/Matrix.md +++ /dev/null @@ -1,7 +0,0 @@ -# Matrix T: Num, Shape: [M, N] - -表示矩陣的類型。它繼承自 Tensor[M, N] - -## def - -Inherit Tensor T, [M, N] \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Module.md b/doc/zh_TW/API/types/classes/Module.md deleted file mode 100644 index 03b89e9f..00000000 --- a/doc/zh_TW/API/types/classes/Module.md +++ /dev/null @@ -1,3 +0,0 @@ -# Module - -## methods diff --git a/doc/zh_TW/API/types/classes/Nat.md b/doc/zh_TW/API/types/classes/Nat.md deleted file mode 100644 index d497c993..00000000 --- a/doc/zh_TW/API/types/classes/Nat.md +++ /dev/null @@ -1,18 +0,0 @@ -# Nat - -表示自然數的類型。用於數組索引和範圍類型 - -## def - -```erg -Nat = 0.._ -``` - -## methods - -* times!(self, p: () => NoneType) -> NoneType - -```erg -100.times! () => - print! "hello!" -``` \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Neg.md b/doc/zh_TW/API/types/classes/Neg.md deleted file mode 100644 index 2dfed2b1..00000000 --- a/doc/zh_TW/API/types/classes/Neg.md +++ /dev/null @@ -1,8 +0,0 @@ -# Neg - -表示負整數的類型。 Pos和Neg和{0} == Int -它還具有一些值得注意的屬性,例如不被零除和 Neg * Neg == Pos - -## def - -Inf<..-1 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Never.md b/doc/zh_TW/API/types/classes/Never.md deleted file mode 100644 index 00415554..00000000 --- a/doc/zh_TW/API/types/classes/Never.md +++ /dev/null @@ -1,13 +0,0 @@ -# Never - -它是所有類型的子類型。它是一個`Class`,因為它擁有所有的方法,當然還有 `.new`。但是,它沒有實例,並且Erg會在即將創建的那一刻停止。 -還有一種叫做`Panic`的類型沒有實例,但是`Never`用於正常終止或故意無限循環,`Panic`用於異常終止。 - -```erg -# 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 deleted file mode 100644 index f2dffc07..00000000 --- a/doc/zh_TW/API/types/classes/NonZero.md +++ /dev/null @@ -1,30 +0,0 @@ -# NonZero N - -表示非零數的類。保證除零的安全性 - -```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 -``` - -## methods - -@Impl SafeDiv R, O -.`/`: Self.(R) -> O \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Object.md b/doc/zh_TW/API/types/classes/Object.md deleted file mode 100644 index 12340489..00000000 --- a/doc/zh_TW/API/types/classes/Object.md +++ /dev/null @@ -1,7 +0,0 @@ -# Object - -它是所有類型的超類型 - -## methods - -* __sizeof__: Nat \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Operator.md b/doc/zh_TW/API/types/classes/Operator.md deleted file mode 100644 index 7560538f..00000000 --- a/doc/zh_TW/API/types/classes/Operator.md +++ /dev/null @@ -1,7 +0,0 @@ -# Operator [...T], O - -是運算符的類型 - -## def - -Inherit Func [...T], O \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Option.md b/doc/zh_TW/API/types/classes/Option.md deleted file mode 100644 index bf88a2cc..00000000 --- a/doc/zh_TW/API/types/classes/Option.md +++ /dev/null @@ -1,21 +0,0 @@ -# Option T = T or NoneType - -表示“可能失敗”的類型。 - -## methods - -* unwrap(self, msg = "unwrapped a None value") -> T or Panic - -提取它,期望內容是 `T` 類型。如果是 `None`,則輸出 `msg` 並恐慌 - -```erg -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 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Pos.md b/doc/zh_TW/API/types/classes/Pos.md deleted file mode 100644 index 08963541..00000000 --- a/doc/zh_TW/API/types/classes/Pos.md +++ /dev/null @@ -1,8 +0,0 @@ -# Pos - -Pos是一種表示正數(大於或等於1的整數)的類型。 -由於不包括0,因此具有消除被零除的可能性等優點。 - -## Def - -`Pos = 1.._` \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Ratio.md b/doc/zh_TW/API/types/classes/Ratio.md deleted file mode 100644 index decf10b3..00000000 --- a/doc/zh_TW/API/types/classes/Ratio.md +++ /dev/null @@ -1,5 +0,0 @@ -# Ratio - -表示有理數的類型。它主要用於當您要使用分數時。 -實際上,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類型之前,請進行真實的性能測試。業餘愛好者無條件偏愛較輕的模具。 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Record.md b/doc/zh_TW/API/types/classes/Record.md deleted file mode 100644 index 1b7809b9..00000000 --- a/doc/zh_TW/API/types/classes/Record.md +++ /dev/null @@ -1,14 +0,0 @@ -# Record - -記錄所屬的類。例如,`{i = 1}` 是`Structural {i = Int}` 類型的元素,並且是`{i = Int}` 類的實例 -請注意,其他類的實例是記錄類型的元素,而不是記錄類的實例 - -```erg -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} -``` \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Result.md b/doc/zh_TW/API/types/classes/Result.md deleted file mode 100644 index 3bf3e792..00000000 --- a/doc/zh_TW/API/types/classes/Result.md +++ /dev/null @@ -1,7 +0,0 @@ -# Result T, E - -```erg -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 deleted file mode 100644 index 5ffc3c30..00000000 --- a/doc/zh_TW/API/types/classes/Str!.md +++ /dev/null @@ -1,3 +0,0 @@ -# StrWithLen! N: Nat! = Inherit StrWithLen N - -表示可變長度字符串的類型 \ 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 deleted file mode 100644 index e29350a3..00000000 --- a/doc/zh_TW/API/types/classes/Str.md +++ /dev/null @@ -1,9 +0,0 @@ -# Str - -(不變長度)表示字符串的類型。簡單的 `Str` 類型是刪除了字符數的 `StrWithLen N` 類型(`Str = StrWithLen _`) - -## methods - -* 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 deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/API/types/classes/Subroutine.md b/doc/zh_TW/API/types/classes/Subroutine.md deleted file mode 100644 index 24204ec4..00000000 --- a/doc/zh_TW/API/types/classes/Subroutine.md +++ /dev/null @@ -1,19 +0,0 @@ -# Subroutine - -Func和Proc的基本類型。 - -## methods - -* return - -中斷子程序並返回指定的值。用於快速逃離嵌套 - -```erg -f x = - for 0..10, i -> - if i == 5: - do - f::return i - do - log i -``` \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Tensor.md b/doc/zh_TW/API/types/classes/Tensor.md deleted file mode 100644 index 1a4ca2b7..00000000 --- a/doc/zh_TW/API/types/classes/Tensor.md +++ /dev/null @@ -1,24 +0,0 @@ -# Tensor Shape: [Nat; N] - - 用於有效操作多維數組的類。它還定義了諸如多維數組上的乘法之類的操作 - Matrix、Vector 等都繼承自該類型 - -```erg -Tensor.arange(0..9) # Tensor [10] -``` - -* reshape(self, NewShape: [Nat; M]) -> Self NewShape - -```erg -(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 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/TransCell(T).md b/doc/zh_TW/API/types/classes/TransCell(T).md deleted file mode 100644 index b31ac1e7..00000000 --- a/doc/zh_TW/API/types/classes/TransCell(T).md +++ /dev/null @@ -1,12 +0,0 @@ -# TransCell! T: Type! - -它是一個單元格,其內容可以針對每個模具進行更改。由於它是T類型的子類型,因此它也表現為T類型 -當它在初始化時輸入T時很有用,並且在某個點之後總是輸入U - -```erg -a = TransCell!.new None -a: TransCell! !NoneType -a.set! 1 -a: TransCell! !Int -assert a + 1 == 2 -``` \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Tuple.md b/doc/zh_TW/API/types/classes/Tuple.md deleted file mode 100644 index 294b6743..00000000 --- a/doc/zh_TW/API/types/classes/Tuple.md +++ /dev/null @@ -1,27 +0,0 @@ -# Tuple T: ...Type - -包含多種類型對象的集合 - -## methods - -* zip self, other - - 組合兩個有序集合(數組或元組) - - ```erg - assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4) - ``` - -* zip_by self, op, other - - 一種泛化 zip 的方法。您可以指定一個二進制操作來組合 - `()`、`[]`、`{}`、`{:}` 也可以指定為運算符,分別生成元組、數組、集合和字典 - - ```erg - 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 - ``` \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Type.md b/doc/zh_TW/API/types/classes/Type.md deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/API/types/classes/Vector.md b/doc/zh_TW/API/types/classes/Vector.md deleted file mode 100644 index d5351a61..00000000 --- a/doc/zh_TW/API/types/classes/Vector.md +++ /dev/null @@ -1,3 +0,0 @@ -# Vector T: Num, N: Nat - -表示向量的類型。與同名的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 deleted file mode 100644 index 4c212763..00000000 --- a/doc/zh_TW/API/types/patches/BinOp.md +++ /dev/null @@ -1,7 +0,0 @@ -# BinOp L, R, O - -二元運算符的類型 - -## Patches - -Operator [L, R], O \ No newline at end of file diff --git a/doc/zh_TW/API/types/patches/UnaryOp.md b/doc/zh_TW/API/types/patches/UnaryOp.md deleted file mode 100644 index e5d26abd..00000000 --- a/doc/zh_TW/API/types/patches/UnaryOp.md +++ /dev/null @@ -1,7 +0,0 @@ -# UnaryOp T, O - -一元運算符的類型 - -## def - -Operator [T], O \ No newline at end of file diff --git a/doc/zh_TW/API/types/traits/Add(R,O).md b/doc/zh_TW/API/types/traits/Add(R,O).md deleted file mode 100644 index 91aa315c..00000000 --- a/doc/zh_TW/API/types/traits/Add(R,O).md +++ /dev/null @@ -1,34 +0,0 @@ -# Add R - -```erg -Add R = Trait { - .AddO = Type - .`_+_` = (Self, R) -> Self.AddO -} -``` - -`Add`是一種定義加法的類型。加法有兩種類型的`+`:方法和函數 -`+`作為二元函數,即`_+_`,定義如下: - -```erg -`_+_`(l: Add(R, O), r: R): O = l.`_+_` r -``` - -這個定義的目的是讓 `+` 可以被視為一個函數而不是一個方法 - -```erg -assert [1, 2, 3].fold(0, `_+_`) == 6 - -call op, x, y = op(x, y) -assert call(`_+_`, 1, 2) == 3 -``` - -加法是這樣輸入的 - -```erg -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 -``` \ No newline at end of file diff --git a/doc/zh_TW/API/types/traits/Div(R,O).md b/doc/zh_TW/API/types/traits/Div(R,O).md deleted file mode 100644 index b31431d0..00000000 --- a/doc/zh_TW/API/types/traits/Div(R,O).md +++ /dev/null @@ -1,9 +0,0 @@ -# Div R, O - -如果除以零沒有錯誤,請使用“SafeDiv” - -```erg -Div R, O = Trait { - .`/` = Self.(R) -> O or Panic -} -``` \ No newline at end of file diff --git a/doc/zh_TW/API/types/traits/Eq.md b/doc/zh_TW/API/types/traits/Eq.md deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/API/types/traits/Into.md b/doc/zh_TW/API/types/traits/Into.md deleted file mode 100644 index e6ae5e72..00000000 --- a/doc/zh_TW/API/types/traits/Into.md +++ /dev/null @@ -1,11 +0,0 @@ -# Into T - -一種類型,表明它可以被類型轉換為類型T。 -即使Self和T之間沒有繼承關係,也是在關係可以相互轉換的時候定義的。 -與繼承不同,沒有隱式轉換。您必須始終調用 `.into` 方法。 - -## methods - -* into(self, T) -> T - - 変換を行います。 \ No newline at end of file diff --git a/doc/zh_TW/API/types/traits/Iterable.md b/doc/zh_TW/API/types/traits/Iterable.md deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/API/types/traits/Num.md b/doc/zh_TW/API/types/traits/Num.md deleted file mode 100644 index 5745c5ce..00000000 --- a/doc/zh_TW/API/types/traits/Num.md +++ /dev/null @@ -1,16 +0,0 @@ -# Num - -## definition - -```erg -Num R = Add(R) and Sub(R) and Mul(R) and Eq -Num = Num Self -``` - -## supers - -Add and Sub and Mul and Eq - -## methods - -* `abs` diff --git a/doc/zh_TW/API/types/traits/Ord.md b/doc/zh_TW/API/types/traits/Ord.md deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/API/types/traits/SafeDiv(R,O).md b/doc/zh_TW/API/types/traits/SafeDiv(R,O).md deleted file mode 100644 index 54c3a1b1..00000000 --- a/doc/zh_TW/API/types/traits/SafeDiv(R,O).md +++ /dev/null @@ -1,8 +0,0 @@ -# SafeDiv R, O - -```erg -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 deleted file mode 100644 index 12d09b4a..00000000 --- a/doc/zh_TW/API/types/traits/Sample.md +++ /dev/null @@ -1,31 +0,0 @@ -# Sample - -具有“隨機”選擇實例的`sample`和`sample!`方法的特徵。 `sample`方法總是返回相同的實例,而`sample!`方法返回一個隨機實例,該實例隨調用而變化 - -請注意,這是一個假設您想要一個適當的實例進行測試等的特徵,並且它不一定是隨機的。如果您想要隨機抽樣,請使用“隨機”模塊。 - -所有主要的值類都實現了 `Sample`。它還在由“Sample”類組成的元組類型、記錄類型、Or類型和篩選類型中實現 - -```erg -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`的實現示例 - -```erg -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} -``` \ No newline at end of file diff --git a/doc/zh_TW/API/types/traits/Seq.md b/doc/zh_TW/API/types/traits/Seq.md deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/API/types/traits/Show.md b/doc/zh_TW/API/types/traits/Show.md deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/API/types/traits/Unpack.md b/doc/zh_TW/API/types/traits/Unpack.md deleted file mode 100644 index c78b03ba..00000000 --- a/doc/zh_TW/API/types/traits/Unpack.md +++ /dev/null @@ -1,13 +0,0 @@ -# Unpack - -標記性狀。實現時,元素可以像記錄一樣通過模式匹配來分解 - -```erg -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 -``` \ No newline at end of file diff --git a/doc/zh_TW/compiler/TODO_hint.md b/doc/zh_TW/compiler/TODO_hint.md deleted file mode 100644 index 3844f83f..00000000 --- a/doc/zh_TW/compiler/TODO_hint.md +++ /dev/null @@ -1,4 +0,0 @@ -# Hint (not implemented) - -* `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/zh_TW/compiler/TODO_recov_suggest.md b/doc/zh_TW/compiler/TODO_recov_suggest.md deleted file mode 100644 index cf919c9f..00000000 --- a/doc/zh_TW/compiler/TODO_recov_suggest.md +++ /dev/null @@ -1,11 +0,0 @@ -# Error recovery suggestions (not implemented yet) - -* `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`? -* `: [1, 2]` => `: {1, 2}`? -* `: [Int, 2]` => `: [Int; 2]`? -* `[Int; Str]` => `(Int, Str)` (Tuple) or `[Int: Str]` (Dict)? -* `{x: Int}` => `{x = Int}`? -* `{x = Int}!` => `{x = Int!}`? -* `ref! immut_expr` => `ref!!immut_expr`? diff --git a/doc/zh_TW/compiler/TODO_warn.md b/doc/zh_TW/compiler/TODO_warn.md deleted file mode 100644 index bc503a9f..00000000 --- a/doc/zh_TW/compiler/TODO_warn.md +++ /dev/null @@ -1,5 +0,0 @@ -# warnings (not implemented yet) - -* `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/zh_TW/compiler/abandoned.md b/doc/zh_TW/compiler/abandoned.md deleted file mode 100644 index d858a2f0..00000000 --- a/doc/zh_TW/compiler/abandoned.md +++ /dev/null @@ -1,10 +0,0 @@ -# 廢棄/拒絕的語言規範 - -## 重載(臨時多態性) - -被放棄了,因為它可以用參數+子類型多態來代替,並且與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 deleted file mode 100644 index 2f685f0a..00000000 --- a/doc/zh_TW/compiler/architecture.md +++ /dev/null @@ -1,39 +0,0 @@ -# `ergc` 的架構 - -## 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` 和 `DummyVM` 實現。 - -## 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` 有每個變量的類型信息。它是用於“高級中間表示”的。 -* `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 是基於寄存器的。 - 這個轉換過程會多出幾層中間過程。 diff --git a/doc/zh_TW/compiler/errors.md b/doc/zh_TW/compiler/errors.md deleted file mode 100644 index a8ff3779..00000000 --- a/doc/zh_TW/compiler/errors.md +++ /dev/null @@ -1,131 +0,0 @@ -# Erg Compiler Errors - -## AssignError - -嘗試重寫不可變變量時發生 - -## AttributeError - -嘗試訪問不存在的屬性時發生 - -## PurityError - -當您在不允許副作用的範圍內(函數、不可變類型等)編寫導致副作用的代碼時發生 - -## MoveError - -嘗試訪問已移動的變量時發生 - -## BorrowError - -在存在對對象的借用時嘗試獲取可變引用時發生 - -## CyclicError - -當你有一個明顯不可阻擋的循環時發生 - -```erg -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 - -在定義之前使用變量時發生 -更準確地說,它發生在以前使用過在範圍內定義的變量時 - -```erg -i = 0 -f x = - y = i + x - i = 1 - y + i -``` - -在這段代碼中,`y = i + x` 中的 `i` 是一個未定義的變量 -但是,常量可以在定義之前在另一個函數中調用 - -```erg -f() = g() -g() = f() -``` - -## Erg Compiler Warnings - -## SyntaxWarning - -它在語法上很好,但是當我們檢測到冗餘或不常見的代碼(不必要的 `()` 等)時就會發生這種情況 - -```erg -if (True): # SyntaxWarning: unnecessary parentheses - ... -``` - -## DeprecationWarning - -在不推薦使用引用的對象時發生 -(開發人員在生成此警告時應始終提供替代方法作為提示) - -## FutureWarning - -當您檢測到將來可能導致問題的代碼時發生 -此警告是由版本兼容性問題(包括庫)以及語法和 API 的更改引起的 - -## ImportWarning \ No newline at end of file diff --git a/doc/zh_TW/compiler/hir.md b/doc/zh_TW/compiler/hir.md deleted file mode 100644 index b7b64b68..00000000 --- a/doc/zh_TW/compiler/hir.md +++ /dev/null @@ -1,148 +0,0 @@ -# 高レベル中間表現(HIR, High-level Intermediate Representation) - -HIR 是 Erg 編譯器從 AST 生成的結構 -此結構包含源代碼中每個表達式的完整類型信息,並且在語法上已脫糖 -AST與源代碼一一對應(純文本),但是HIR去掉了不必要的代碼信息,添加了省略的類型信息,所以HIR可以轉換為源代碼很難恢復 -讓我們在下面的代碼中查看 HIR 的示例 - -```erg -v = ![] -for! 0..10, i => - v.push! i -log v.sum() -``` - -從此代碼生成的 AST 如下所示: - -```erg -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 如下所示: - -```erg -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 deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/compiler/inference.md b/doc/zh_TW/compiler/inference.md deleted file mode 100644 index 5efd4f9d..00000000 --- a/doc/zh_TW/compiler/inference.md +++ /dev/null @@ -1,436 +0,0 @@ -# 類型推理算法 - -> :本節正在編輯中,可能包含某些錯誤。 - -以下是使用的表示方法。 - - -```erg -自由類型變量(類型,未綁定):?T, ?U,... -自由類型變量(值,未綁定):?a, ?b,... -輸入環境 (Γ): { x: T,... } -類型分配規則 (S): { ?T --> T,...} -類型參數評估環境 (E): { e -> e',...} -``` - -下面的代碼是一個示例。 - - -```erg -v = ![] -v.push! 1 -print! v -``` - -Erg 類型推理的主要框架是 Hindley-Milner 類型推理算法(但進行了各種擴展)。具體來說,類型推論是按照以下步驟進行的。術語描述將在後面介紹。 - -1. 推斷右邊值的類型(search) -2. 使得到的類型具體化(instantiate) -3. 調用時進行類型賦值(substitute) -4. 體現單相特寫(resolve traits) -5. 求值和簡化類型變量值(eval) -6. 刪除鏈接的類型變量(deref) -7. 對於可變依賴方法,傳播更改(propagate) -8. 如果左側值存在且可調用,則執行參數類型的一般化(generalize) -9. 如果有左側值,則(返回值)類型一般化(generalize) -10. 如果賦值,則在符號表()中登記類型信息(update)。 - -具體操作如下。 - -line 1. Def{sig: v, block: ![]} - get block type: - get UnaryOp type: - get Array type: `['T; 0]`instantiate: `[?T; 0]`(substitute, eval are omitted) - update: `Γ: {v: [?T; 0]!}`expr returns `NoneType`: OK - -line 2. CallMethod{obj: v, name: push!, args: [1]} - get obj type: `Array!(?T, 0)` - search: `Γ Array!(?T, 0).push!({1})`get: `= Array!('T ~> 'T, 'N ~> 'N+1).push!('T) => NoneType`instantiate: `Array!(?T, ?N).push!(?T) => NoneType`substitute(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!(Nat) => NoneType`eval: `Array!(Nat, 0 ~> 1).push!({1}) => NoneType`update: `Γ: {v: [Nat; 1]!}` - expr returns `NoneType`: OK - -line 3. Call{obj: print!, args: [v]} - get args type: `[[Nat; 1]!]`get obj type: - search: `Γ print!([Nat; 1]!)`get: `= print!(...Object) => NoneType` - expr returns `NoneType`: OK - -## 實現類型變量 - -類型變量最初在的中表示如下。雖然現在以不同的形式實現,但本質上是相同的想法,所以我用更簡單的表達方式——這個實現來思考。 的包裝類型。 - - -```rust -pub enum Type { - ... - Var(RcCell>), // a reference to the type of other expression, see docs/compiler/inference.md - ... -} -``` - -類型變量可以實現在外部字典中具有實體類型,而類型變量本身僅具有該鍵。然而,使用實現通常更有效(需要驗證,)。 - -類型變量首先按進行初始化。此類型變量在代碼分析過程中被重寫,以確定類型。如果內容始終為 None,則會產生一個類型變量,不能(立即)確定為特定類型。例如,類型。我們將這種狀態下的類型變量稱為(確切術語未知)。與此相對,如果指定了某種特定類型,則稱為。 - -這兩種類型都是自由變量(很明顯,我們認為這一術語是根據“自由變量”命名的)。這些是編譯器用於推理的類型變量。這是因為它與程序員指定的類型變量不同,例如中的。 - -未綁定變量應表示為和。在型理論的上下文中使用α和β的情況比較多,但是為了輸入的簡便化,採用了這個。請注意,這是一種用於一般討論的符號,實際上並不是使用字符串標識符實現的。 - -當未綁定的變量被置於類型環境中時,它被替換為。這就是我們所說的。它類似於程序員指定的類型變量,如。它的內容只是一個字符串,不像自由變量那樣可以鏈接到特定類型。 - -將未綁定變量替換為量化變量的操作稱為(或泛化)。如果仍然是未綁定的變量,則必須在一次調用中固定類型(例如,在調用後,的返回類型變為),因此必須將其一般化。這樣,將在類型環境中註冊包含量化變量的廣義定義。 - -## 一般化、類型方案、具體化 - -將未綁定變量一般化的操作表示為。假設得到的廣義變量為。在類型理論中,量化類型(例如,多相關數類型)通過在其前面加上來進行區分(例如,大塊等符號稱為(全稱)量化器)。這種表達式(e.g.)稱為類型方案。 Erg 中的類型方案表示為等。類型方案通常不被視為一級類型。這樣配置類型系統可能會導致類型推理無法正常工作。然而,在某些情況下,Erg 被視為主要類型。有關詳細信息,請參見。 - -現在,當在類型推理中使用得到的類型方案(e.g.)時,必須取消一般化(e.g.)。這種反變換稱為。我們將此操作稱為。 - - -```erg -gen ?T = 'T -inst 'T = ?T (?T ∉ Γ) -``` - -重要的是,這兩個操作都會替換該類型變量出現的所有位置。例如,如果將具體化,則得到。在實現過程中,需要 Dict 來替換它,但在一般化過程中,只需將鏈接到即可替換它。 - -然後給出參數的類型,得到所需的類型。我們將此操作稱為類型賦值(Type substitution),並將其表示為。此外,表示當表達式是調用時獲得返回類型的操作。第一個參數是參數類型列表,第二個參數是目標類型。 - -類型賦值規則表示將重寫為同一類型。此操作稱為也可以是類型變量。關於單一化的詳細算法,請參見。單一化操作應表示為。 - - -```erg -unify(?T, Int) == Ok(()) # ?T == (Int) - -# Sは型代入規則、Tは適用する型 -subst(S: {?T --> X}, T: ?T -> ?T) == X -> X -# 型代入規則は{?T --> X, ?U --> T} -subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y -``` - -## 半單一化 - -單一化的一個亞種是半單一化(__Semi-unification__)。這是更新類型變量約束以滿足子類型關係的操作。在某些情況下,類型變量可以是單一變量,也可以是不單一變量,因此稱為“半”單一變量。 - -例如,在賦值參數時會發生半單一化。實際參數類型必須是虛擬參數類型的子類型。如果參數的類型是類型變量,則必須更新子類型關係以滿足該類型。 - - -```erg -# 仮引數の型をTとすると -f(x: T): T = ... - -a: U -# U <: Tでなくてはならない、さもなければ型エラー -f(a) -``` - -## 一般化 - -一般化不是一項簡單的工作。如果涉及多個範圍,就需要對類型變量進行“級別管理”。為了了解等級管理的必要性,首先確認不引入等級管理的類型推理會產生問題。試著推論以下無名函數的類型。 - - -```erg -x -> - y = x - y -``` - -首先,Erg 分配類型變量,如下所示。 y 的類型也是未知的,但現階段不指定它。 - - -```erg -x(: ?T) -> - y = x - y -``` - -首先要確定的是右邊值 x 的類型。右邊的值是“使用”,因此它是具體化的。但是,x 的類型是一個自由變量,因此已經被具體化。因此,仍然是右邊值的類型。 - - -```erg -x(: ?T) -> - y = x (: inst ?T) - y -``` - -在註冊為類型 y 的左側值時進行一般化。但是,稍後將會發現,這種一般化是不完整的,結果是錯誤的。 - - -```erg -x(: ?T) -> - y(: gen ?T) = x (: ?T) - y -``` - - -```erg -x(: ?T) -> - y(: 'T) = x - y -``` - -y 的類型現在是量化變量。在下一行中,被立即使用。具體化。 - - -```erg -x: ?T -> - y(: 'T) = x - y(: inst 'T) -``` - -需要注意的是,在實現過程中,必須生成與任何已存在的(自由)類型變量不同的(自由)類型變量(一般化也是如此)。這些類型變量稱為新鮮類型變量。 - - -```erg -x: ?T -> - y = x - y(: ?U) -``` - -然後看得到的整個公式的類型。 。但很明顯,這個公式應該是,你會發現推理有問題。之所以會這樣,是因為我們沒有對類型變量進行“級別管理”。 - -因此,使用以下符號引入類型變量的級別。級別以自然數表示。 - - -```erg -# 通常のType型変數 -?T<1>, ?T<2>, ... -# 部分型製約を付けられた型変數 -?T<1>(<: U) or ?T(<: U)<1>, ... -``` - -現在,我再試一次。 - - -```erg -x -> - y = x - y -``` - -首先,按如下所示賦值級別變量。頂級級別為 1. 範圍越深,等級就越高。函數的參數屬於內部範圍,因此它位於比函數本身大一個級別。 - - -```erg -# level 1 -x (: ?T<2>) -> - # level 2 - y = x - y -``` - -首先,將右邊值具體化。和剛才一樣,什麼都不會改變。 - - -```erg -x (: ?T<2>) -> - y = x (: inst ?T<2>) - y -``` - -從這裡開始就是基莫。這是分配給類型左邊值時的一般化。剛才這裡的結果很奇怪,所以我們要改變廣義算法。如果類型變量的級別小於或等於當前範圍的級別,則一般化後將保持不變。 - - -```erg -gen ?T = if n <= current_level, then= ?T, else= 'T -``` - - -```erg -x (:?T<2>) -> - # current_level = 2 - y (: gen ?T<2>) = x (: ?T<2>) - y -``` - -也就是說,左邊值的類型為。 - - -```erg -x (: ?T<2>) -> - # ↓ not generalized - y (: ?T<2>) = x - y -``` - -y 的類型現在為未綁定變量。在下一行中進行說明。但是,類型並不通用,因此不會發生任何情況。 - - -```erg -x (: ?T<2>) -> - y (: ?T<2>) = x - y (: inst ?T<2>) -``` - - -```erg -x (: ?T<2>) -> - y = x - y (: ?T<2>) -``` - -成功地得到了正確的類型。 - -我再看一個例子。這是更常見的情況,函數,運算符應用,前向參照。 - - -```erg -f x, y = id(x) + y -id x = x - -f 10, 1 -``` - -讓我們一條一條地看。 - -在推論中,引用了後面定義的函數常量。在這種情況下,可以在之前插入一個聲明,並分配一個自由變量。請注意,此時類型變量的級別為。這是為了避免在其他函數中被一般化。 - - -```erg -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 -``` - -類型變量之間的統一會將較高級別的類型變量替換為較低級別的類型變量。如果級別相同,這兩個級別都可以。 - -類型變量之間的半單一化,情況稍有不同。對於不同級別的類型變量,不能相互施加類型約束。 - - -```erg -# BAD -f x (: ?V<2>), y (: ?W<2>) = - # ?V<2>(<: ?T<1>) - # ?T<1>(:> ?V<2>) - id(x) (: ?U<1>) + y (: ?W<2>) -``` - -這樣,你就無法確定類型變量的具體體現位置。對於 Type 類型變量,請執行常規的單一化,而不是半單一化。也就是說,讓他們單一化到低級別。 - - -```erg -# OK -f x (: ?V<2>), y (: ?W<2>) = - # ?V<2> --> ?T<1> - id(x) (: ?U<1>) + y (: ?W<2>) -``` - - -```erg -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 -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 -id: ?T<1> -> ?U<1> -f x (: ?T<1>), y (: ?W<2>) = - # ?U<1>(<: Add(?W<2>)) # 繼承 ?L 的約束 - # ?L<2> --> ?U<1> - # ?R<2> --> ?W<2> (?R(:> ?W), ?W(<: ?R)とはしない) - (id(x) + x) (: ?U<1>.AddO) -``` - - -```erg -# current_level = 1 -f(x, y) (: gen ?T<1>, gen ?W<2> -> gen ?U<1>.AddO) = - id(x) + x -``` - - -```erg -id: ?T<1> -> ?U<1> -f(x, y) (: |'W: Type| (?T<1>, 'W) -> gen ?U<1>(<: Add(?W<2>)).AddO) = - id(x) + x -``` - - -```erg -f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) = - id(x) + x -``` - -在定義時進行升級以使其一般化。 - - -```erg -# ?T<1 -> 2> -# ?U<1 -> 2> -id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>) -``` - -如果已分配返回類型,則將返回類型與返回類型合併()。 - - -```erg -# ?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>) -``` - -如果一個類型變量只是一個類型變量,則它所依賴的類型變量也是一個類型變量。一般化類型變量在每個函數中都是獨立的。 - - -```erg -f(x, y) (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = - id(x) + x -id(x) (: |'T: Type| 'T -> gen 'T) = x -``` - - -```erg -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) -``` - - -```erg -f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<1>) -> ?T<1>.AddO)) -``` - -類型變量將擴展到其實現的最小類型。 - - -```erg -# ?T(:> {10} <: Add(?W<1>))<1> -# ?W(:> {1})<1> -# ?W(:> {1})<1> <: ?T<1> (:> {10}, <: Add(?W(:> {1})<1>)) -# 序列化 -# {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) -``` - -因此,整個程序的類型是這樣的。 - - -```erg -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 -``` - -重新提示原始未顯式輸入的程序。 - - -```erg -f x, 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 deleted file mode 100644 index b3621bd5..00000000 --- a/doc/zh_TW/compiler/overview.md +++ /dev/null @@ -1,36 +0,0 @@ -# 概覽 - -介紹每個圖層的工作方式以及特別重要的函數和方法。 - -## 1. 詞法分析 - -* 執行詞法分析。 (作為迭代器實現)是詞法分析的主要邏輯。將輸出作為分析的結果。 - -## 2. 語法分析 - -* 執行解析。尤其重要的是。作為分析的結果,將輸出,它是的集合。 - -## 3. 脫糖 - -* 進行脫糖。將輸出。 - -## 4. 類型檢查/類型推理 - -* 用於輸入數據。類型檢查主要通過進行。特別重要的是(確定子類型關係),(對類型變量進行單一化/半單一化)和(定義嵌入式 API)。將輸出作為分析的結果。 - -## 5. 副作用檢查 - -* 。 - -## 6. 所有權檢查 - -* 。 - -## 7. 字節碼生成 - -* 將轉換為保留字節碼和執行設置。尤其重要的是。 - ---- - -* 所有這些操作都由作為外立面進行總結。 -* 生成的字節碼當然由 Python 執行,但它被稱為。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/parsing.md b/doc/zh_TW/compiler/parsing.md deleted file mode 100644 index 5024f080..00000000 --- a/doc/zh_TW/compiler/parsing.md +++ /dev/null @@ -1,31 +0,0 @@ -# 解析 Erg 語言 - -## 處理空白 - -在 Erg 的語法中,特別的是 space-sensitive(根據空白進行區分)這一點。這是為了彌補的省略導致的表現力下降。同樣的語法也可以在可以省略的 Nim 中看到。 - - -```erg -f +1 == f(+1) -f + 1 == `+`(f, 1) -f (1,) == f((1,)) -f(1,) == f(1) -(f () -> ...) == f(() -> ...) -(f() -> ...) == (f() -> ...) -``` - -## 左側值,右側值 - -在 Erg 中,所謂左邊值並不是的左側這樣簡單的值。實際上,的左側也存在右邊值(非常容易混淆),的右側也存在左邊值。甚至在右邊值中存在左邊值。 - - -```erg -# 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} -``` - -左邊值、右邊值的正確定義是“如果可以評價的話是右邊值,如果不是的話是左邊值”。以這一代碼為例。第 2 個是可以評價的右邊值,第 1 個是左邊值。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/refinement_subtyping.md b/doc/zh_TW/compiler/refinement_subtyping.md deleted file mode 100644 index fa8a4aa5..00000000 --- a/doc/zh_TW/compiler/refinement_subtyping.md +++ /dev/null @@ -1,155 +0,0 @@ -# 篩子型 - -篩型是指以下類型。 - - -```erg -{I: Int | I >= 0} -{S: StrWithLen N | N >= 1} -{T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0} -``` - -在 Erg 中,通過將 Enum,Interval 型轉換為篩子型,可以進行型的判定。 - -## 轉換為篩子類型 - -在 [篩型] 一項中,區間型和列舉型是篩型的糖衣句法。分別進行如下變換。 - -* {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 and I <= a` - * `i!= a` => `I >= a+1 or I <= a-1` -* 恆真規則 - * `I >= a or I <= b (a < b)` == `{...}` -* 恆偽規則 - * `I >= a and I <= b (a > b)` == `{}` -* 更換規則 - * 順序表達式按,的順序進行替換。 -* 延長規則 - * `I == n or I >= n+1` => `I >= n` - * `I == n or I <= n-1` => `I <= n` -* 最大規則 - * `I <= m or I <= n` => `I <= max(m, n)` - * `I >= m and I >= n` => `I >= max(m, n)` -* 最小規則 - * `I >= m or I >= n` => `I >= min(m, n)` - * `I <= m and I <= n` => `I <= min(m, n)` -* 刪除規則 - * 左邊的,在右邊有時可以去除。 - * 如果不能移除左邊的所有等式,則返回 False - -e.g. - - -```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 deleted file mode 100644 index f4a1e55c..00000000 --- a/doc/zh_TW/compiler/trait_method_resolving.md +++ /dev/null @@ -1,86 +0,0 @@ -# 解決修補程序方法 - -是大於 0 的,即的子類型。本來不存在於 Python 的類階層中。 Erg 如何解決這個補丁的方法呢? - - -```erg -1.times do: - log "hello, world" -``` - -是的補丁方法。由於的實例,所以首先要沿著的 MRO(方法解析順序)進行搜索。 Erg 在的 MRO 中有。它來自 Python(在 Python 中)。 方法在這兩個方法中都不存在。從這裡開始,進入該子類型的探索。 - -~ - -整數在其上位型中顯然應該具有實數和復數,甚至是整體數,但在與 Python 具有互換性的層中卻不出現這一事實。但是實際上在 Erg 中,和。至於,雖然是與沒有繼承關係的類,但作為類型被判斷為具有互換性。究竟是怎麼回事? - -~ - -對於某個對象,其所屬的類型有無數個。但是實際上必須考慮的是擁有方法的類型,即只有擁有名字的類型。 - -Erg 編譯器擁有所有提供方法及其安裝的補丁型散列映射。每次新定義類型時,此表都會更新。 - - -```erg -provided_method_table = { - ... - "foo": [Foo], - ... - ".times": [Nat, Foo], - ... -} -``` - -具有方法的類型為。從這些中,尋找符合型的。符合判定有兩種。篩型判定和記錄型判定。從篩型判定開始進行。 - -## 篩子型判定 - -檢查候選類型是否與類型兼容。篩型中與兼容的有等。 等有限元的代數運算類型,如果聲明為基本類型,則被歸一化為篩子類型(即,)。在這次的情況下,由於,所以是兼容的。 - -## 記錄類型判定 - -確認是否與候選類型為 1 的類兼容。此外,當的補丁,並且具有所有的要求屬性時,也具有兼容性。 - -~ - -因此,是合適的。但是,當也符合時,根據的包含關係進行判定。也就是說,選擇子類型的方法。如果兩者沒有包含關係,則會出現編譯錯誤(這是一種安全措施,可防止執行與程序員意圖相反的方法)。為了消除錯誤,必須明確指定修補程序。 - - -```erg -o.method(x) -> P.method(o, x) -``` - -## 全稱補丁程序方法解析 - -定義如下補丁。 - - -```erg -FnType T: Type = Patch T -> T -FnType.type = T -``` - -在補丁的基礎上可以進行以下代碼。這又將如何解決呢? - - -```erg -assert (Int -> Int).type == Int -``` - -首先,中以以下形式登錄。 - - -```erg -provided_method_table = { - ... - "type": [FnType(T)], - ... -} -``` - -檢查是否符合的補丁類型。此時,的補丁類型為。這符合。匹配後,進行單相化置換(取的 diff。)。 - - -```erg -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 deleted file mode 100644 index c87ab9e0..00000000 --- a/doc/zh_TW/compiler/transpile.md +++ /dev/null @@ -1,91 +0,0 @@ -# Erg 代碼如何轉堆到 Python 代碼中? - -準確地說,Erg 代碼被轉堆為 Python 字節代碼。但是 Python 字節碼幾乎可以恢復為 Python 代碼,所以這裡給出一個等效的 Python 代碼作為例子。順便說一下,這裡的示例是優化級別較低的示例。進一步的高級優化將清除不需要生成實體的內容。 - -## Record, Record type - -變換成 namedtuple。有關 namedtuple 的信息,請參見。類似的功能包括 dataclass,但由於自動實現和,dataclass 的性能略有下降。 - - -```erg -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' -``` - -如果可以進一步優化,它還將轉換為簡單的元組。 - -## Polymorphic Type - -> WIP - -## Instant Scope - -如果名稱空間中不發生衝突,則只會進行彎曲和展開。像這樣的名稱在字節碼中使用,不能與 Python 代碼相對應,但如果強行表示,則會出現以下情況。 - - -```erg -x = - y = 1 - y + 1 -``` - - -```python -x::y = 1 -x = x::y + 1 -``` - -如果發生衝突,請定義和使用只能在內部引用的函數。 - - -```erg -x = - y = 1 - y + 1 -``` - - -```python -def _(): - x = 1 - y = x - return y + 1 -x = _() -``` - -## Visibility - -對於公共變量,它是 Python 的缺省值,因此不執行任何操作。私域變量是由 Munging 處理的。 - - -```erg -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 deleted file mode 100644 index a4d46e87..00000000 --- a/doc/zh_TW/compiler/type_var_normalization.md +++ /dev/null @@ -1,35 +0,0 @@ -# 歸一化 - -* Erg 的類型參數規範化使用 SymPy 的 simplify 函數。 - -例如,在定義時,必須不具體化類型變量和自變量而進行一致判定。等式判定自然是有界限的,目前可能的判定及其方式如下所示。 - -* 相加/乘法對稱性: - - `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 and 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 deleted file mode 100644 index 344a9ad2..00000000 --- a/doc/zh_TW/dev_guide/branches.md +++ /dev/null @@ -1,35 +0,0 @@ -# 分支機構命名和運營策略 - -## main - -* 主要開發分支 -* 必須滿足以下條件 - -* 編譯成功 - -## beta(目前不創建) - -* 最新的 Beta 版本 -* 必須滿足以下條件 - -* 編譯成功 -* 所有測試都會成功 - -## feature-* - -* 開發特定功能的分支 -* 切開 main - -* 沒有條件 - -## issue-* - -* 解決特定 issue 的分支 - -* 沒有條件 - -## fix-* - -* 修復特定錯誤的分支(如果該問題是一個錯誤,則代替`issue-*`創建)。 - -* 沒有條件 diff --git a/doc/zh_TW/dev_guide/build_features.md b/doc/zh_TW/dev_guide/build_features.md deleted file mode 100644 index 75ae2100..00000000 --- a/doc/zh_TW/dev_guide/build_features.md +++ /dev/null @@ -1,17 +0,0 @@ -# `erg` build features - -## debug - -進入調試模式。由此,在 Erg 內部的舉動被逐次記錄表示出來。獨立於 Rust 的標誌。 - -## japanese - -系統語言為日語。 Erg 內的選項、幫助(如 help、copyright、license)和錯誤顯示都保證為日語。 - -## simplified_chinese - -系統語言為簡體中文。 - -## traditional_chinese - -系統語言為繁體中文。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/directories.md b/doc/zh_TW/dev_guide/directories.md deleted file mode 100644 index df1f008c..00000000 --- a/doc/zh_TW/dev_guide/directories.md +++ /dev/null @@ -1,24 +0,0 @@ -# Erg存儲表結構 - -```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:測試代碼 -``` diff --git a/doc/zh_TW/dev_guide/doc_guideline.md b/doc/zh_TW/dev_guide/doc_guideline.md deleted file mode 100644 index ac75168a..00000000 --- a/doc/zh_TW/dev_guide/doc_guideline.md +++ /dev/null @@ -1,13 +0,0 @@ -# 格式 - -所有不符合以下規則的文檔都是修正的對象。 - -* 代碼註釋或內部文檔以這種方式編寫。 -* 向外部(普通用戶)展示的文檔要用簡單易懂的語言書寫。 -* 文檔中首次出現的術語必須同時記錄定義、含義或鏈接。 -* ()作為補充,僅用於理解正文所必需的句子,而非理解正文所必需的句子則使用腳註。 -* 如果文檔內容過期,則根據進行更新。 - ---- - -1腳註的寫法參照此。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/env.md b/doc/zh_TW/dev_guide/env.md deleted file mode 100644 index 4f65afa3..00000000 --- a/doc/zh_TW/dev_guide/env.md +++ /dev/null @@ -1,19 +0,0 @@ -# 開發環境 - -## 需要安裝的內容 - -* Rust (installed with rustup) - - * ver >= 1.63.0 - * 2021 edition - -* [pre-commit](https://pre-commit.com/) - -* Python3 解釋器 - -## 建議 - -* 編輯器:Visual Studio 代碼 -* 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 -* 其他:pyenv,mold \ 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 deleted file mode 100644 index 00ae6363..00000000 --- a/doc/zh_TW/dev_guide/faq_syntax.md +++ /dev/null @@ -1,107 +0,0 @@ -# Erg design's "Why" and Answers - -## 為什麼擁有所有權系統仍然同時使用GC? - -因為 Erg 推出所有權系統的動機並不是為了 Rust 那樣的“不依賴 GC 的內存管理”。最初,由於 Erg 是一種語言,目前使用 Python VM,因此最終仍使用 GC。 Erg 引入產權系統的目標是“可變狀態的局部化”。在 Erg 中,可變對象具有所有權概念。這是根據共享可變狀態容易成為 bug 的溫床,甚至是類型安全性的侵犯(詳見)來判斷的。 - -## 為什麼類型參數周圍的括號不是 <> 或 []? - -因為在和中會發生語法衝突。 - -```erg -# []版 -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 設計為將類型本身也視為值。 - - -```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 -``` - -## 你打算在 Erg 中實現宏嗎? - -目前沒有。宏觀大致分為四個目的。第一個是編譯時計算。這在 Erg 中由編譯時函數負責。第二,代碼執行的延遲。這可以用 do 塊來代替。第三個是處理通用化,對此多相關數和全稱類型是比宏觀更好的解決方案。第四個是自動生成代碼,但這會造成可讀性的下降,所以我們不敢在 Erg 中實現。因此,宏的大部分功能都由 Erg 型系統承擔,因此沒有動力進行部署。 - -## 為什麼 Erg 沒有例外機制? - -在許多情況下,錯誤處理類型是更好的解決方案。類型是一種錯誤處理方法,通常在較新的編程語言中使用。 - -在 Erg 中,運算符使你可以在不太注意錯誤的情況下編寫。 - - -```erg -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? - -默認情況下,指向結構托盤會使類型指定變得複雜,並且可能會混合程序員的非預期行為。 - - -```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 -``` - -## Erg 是否實現了定義自己的運算符的功能? - -A:沒有那個計劃。最重要的原因是,如果允許定義自己的運算符,就會出現如何處理組合順序的問題。可以定義自己的運算符的 Scala 和 Haskell 等都有不同的對應,但這可以看作是可能產生解釋差異的語法的證據。此外,獨立運算符還有一個缺點,那就是可能產生可讀性較低的代碼。 - -## 為什麼 Erg 取消了 += 這樣的擴展賦值運算符? - -首先,Erg 中沒有變量的可變性。也就是不能重新賦值。一旦對象與一個變量關聯,它將一直綁定到該變量,直到它脫離作用域並被釋放。在 Erg 中,可變性是指對象的可變性。明白了這個,故事就簡單了。例如,表示,但由於變量是不可重新賦值的,因此這種語法是非法的。還有一個 Erg 的設計原則是運算符沒有副作用。 Python 通常也是如此,但對於某些對象(如 Dict),擴展賦值運算符會更改對象的內部狀態。這算不上是一個很漂亮的設計。因此,擴展賦值運算符被完全廢棄。 - -## 為什麼 Erg 在語法上特別對待有副作用的物體? - -副作用的局部化是代碼維護的一個關鍵因素。 - -但是,確實也不是沒有方法可以不在語言上特殊對待副作用。例如,可以用代數效果(類型系統上的功能)替代過程。但這樣的合一併不總是正確的。例如,Haskell 沒有對字符串進行特殊處理,只是一個字符數組,但這種抽像是錯誤的。 - -什麼情況下,可以說合一化是錯的?一個指標是“是否會因其合一而難以看到錯誤信息”。 Erg 設計師發現,將副作用特殊處理會使錯誤消息更容易閱讀。 - -Erg 有一個強大的類型系統,但並不是所有的類型都決定了它。如果這樣做了,你的下場就跟 Java 試圖用類來控制一切一樣。 diff --git a/doc/zh_TW/dev_guide/i18n_messages.md b/doc/zh_TW/dev_guide/i18n_messages.md deleted file mode 100644 index ef93cda6..00000000 --- a/doc/zh_TW/dev_guide/i18n_messages.md +++ /dev/null @@ -1,55 +0,0 @@ -# Multilingualization of Messages - -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`)嵌入到字符串中。 - -## Build - -現在,我們使用選項構建它。 - -screenshot_i18n_messages - -你做到了! - -## FAQ - -Q:像這樣的指定是什麼意思? A:{RED} 及更高版本將顯示為紅色。重新啟動交互渲染。 - -Q:如果想添加自己的語言,該如何替換部分?答:目前支持以下語言。 - -* "english"(默認設置) -* "japanese"(日語) -* "simplified_chinese" (簡體中文) -* "traditional_chinese" (繁體中文) - -如果你想添加其他語言,請提出請求。 diff --git a/doc/zh_TW/dev_guide/index.md b/doc/zh_TW/dev_guide/index.md deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/dev_guide/rust_code_guideline.md b/doc/zh_TW/dev_guide/rust_code_guideline.md deleted file mode 100644 index 9ce19cfd..00000000 --- a/doc/zh_TW/dev_guide/rust_code_guideline.md +++ /dev/null @@ -1,23 +0,0 @@ -# Rust 代碼準則 - -## 本地規則 - -* 用於調試的輸出使用(釋放時所需的輸出處理也使用等)。 -* 未使用或內部(專用和僅用於特定功能)的變量方法以一個開頭。如果想避免與保留字的衝突,則在後面加上一個。 - -## 鼓勵代碼 - -* 定義並使用特定於域的 Enum,而不是數字枚舉和 bool。 -* 存取修飾符為必要的最小限度。即使公開時也優先使用和。 -* for 表達式中的 iterable 對象顯式轉換為迭代器(,而不是)。 -* 延遲評估。例如,當不是文字時,使用而不是。 - -## 不鼓勵的代碼 - -* 經常使用 return type overloading。具體來說,經常使用不明確的的代碼。這是因為型推論結果有時違反直覺。在這種情況下,建議使用代替。 -* 經常使用。這實質上引起了與繼承相同的問題。 - -## 根據上下文判斷不同的代碼 - -* 定義未使用的 helper 方法。 -* 經常使用,。在某些情況下,有些人別無選擇,只能這樣做。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/terms.md b/doc/zh_TW/dev_guide/terms.md deleted file mode 100644 index 0969124e..00000000 --- a/doc/zh_TW/dev_guide/terms.md +++ /dev/null @@ -1,831 +0,0 @@ -# 術語詞典 - -## 符號 - -### ! - -過程或附加在標識符末尾的標記,以指示其為可變類型。或者變量運算符。 - -### ../syntax/00_basic.md/# 註釋 - -### $ - -### % - -### & - -### ′(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 - -### [秩 1 多相] - -### [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 - -### Trait - -### [True] - -### [Type] - -### [type] - -## U - -## V - -## W - -### [while!] - -## X - -## Y - -## Z - -## 阿行 - -### 斷言 - -檢查代碼中的條件是否成立(通常是在運行時)。使用函數等進行操作。 - - -```erg -sum = !0 -for! 0..10, i => - sum.add! i - -assert sum == 55 -``` - -### 值對象 - -在 Erg 中,與基本對象相同。編譯時可以進行評價,擁有不言而喻的比較方法。 - -### 附著面片../syntax/29_decorate.md#attach - -為 Tracet 提供標準實現的補丁程序。 - -### 即席多相-> - -所謂超載的多相。 - -### 屬性-屬性 - -標識符中的部分。 - -### 安利 - -運算符使用多少個操作數。 - -### 依賴關係../syntax/type/dependent_type.md - -以值(通常為非類型)為參數的類型。 - -### 可變體-> 不可變 - -表示目標保持不變。在其他語言中,變量也具有可變/可變特性,但在 Erg 中,變量都是可變的。 - -### 參數-> 參數 - -### 實例 - -類創建的對象。類類型的元素。 - -### 即時塊(../syntax/00_basic.md# 表達式分隔符) - - -```erg -x = - y = f(a) - z = g(b, c) - y + z -``` - -### 索引 - -形式為,或其中的部分。稱為 Indexable 對象。 - -### 縮進../syntax/00_basic.md# 縮進 - -靠空格使句子向右靠。縮進。 Erg 通過縮進來表現塊。這叫做越位規則。 - -### 別名 - -別名。 - -### 錯誤 - -規範規定的異常狀態。 - -* [エラーハンドリング] - -### 運算符../syntax/06_operator.md - -將運算應用於操作數的對象。或表示對象的符號。 - -* [演算子の結合強度] - -### 覆蓋 - -用子類覆蓋超類的方法。在 Erg 中,覆蓋時必須安裝裝飾器。 - -### 禁止過載(../syntax/type/overloading.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_scop.md# 避免變量狀態函數型編程) - -### 基本類型 - -### 記名的 - -通過名稱而不是對稱結構來區分。 - -* [記名型]-> -* [記名化] -* 記名部分類型../syntax/type/05_nst_vs_sst.md - -### 捕捉-> 閉包 - -### 協變 - -在 Erg 中,當時,如果,則為協變。 - -### 關鍵字參數 - -函數調用形式中的。實際自變量可以用假自變量名而不是順序指定。 - -### 空集->[{}] - -### 區間 - -* 間隔類型(../syntax/type/11_interval.md) -* 區間運算符 - -### 嵌入 - -未在.er 文件中實現的 Erg 標準 API。 - -### 類../syntax/type/04_class.md - -具有繼承功能的結構和抽像數據類型。在 Erg 中是為了實現記名式分型以及覆蓋的類型。在其他語言中也有承擔模塊和型的責任和義務的情況,在 Erg 中,模塊是模塊對象,型是型對象承擔其責任和義務。 - -### 閉合 - -### 全局變量 - -### 克隆 - -### 繼承 - -定義以某個類為上級集合的類。繼承源的類稱為超類,繼承目標的類稱為子類。子類具有超類的所有功能。 - -### 高階 - -* 高階../syntax/type/advanced/kind.md -* 高階型 -* 高階函數 - -### 公共變量 - -### 結構子類型 - -### ~~ 向後參照 ~~~->[向前參照] - -### 複製 - -### 註釋 - -### 集合../syntax/10_array.md - -### 冒號->[:] - -### 構造函數(../syntax/type/04_class.md) - -### 集裝箱 - -### 編譯器 - -### 編譯時計算../syntax/04_function.md# 編譯時函數 - -### 逗號->[,] - -## 差行 - -### 遞歸 - -指自己。 - -* 遞歸型 -* 遞歸函數../syntax/04_function.md# 遞歸函數 - -### 下標-> 索引 - -### 多相子類型(../syntax/type/overloading.md) - -多相分型。子類型是指在類型中與集合的包含關係相對應的類型。 - -### 子程序 - -模塊化處理的對象。 Erg 中函數、過程和方法的通用名稱。 - -### 參考(../syntax/18_memory_management.md# 借用) - -* 引用對象 -* 參照計數 (RC) (../syntax/18_memory_management.md# 內存管理) -* 參考等效性-> - -### 標識符(../syntax/02_variable.md/# 賦值) - -### 簽名 - -* 類型簽名 - -### 詞典../syntax/11_dict.md - -### 自然數->Nat - -### 通用->[全稱類型] - -### 發電機 - -### 投影類型 - -### 借用-> - -### 陰影(../syntax/02_name.md# 變量) - -在內部作用域中定義一個同名的變量,並覆蓋該變量的引用。 - -### 種子-> - -大致是個模子。 - -### 集-> 集 - -在 Erg 中是 Set 對象。 - -### 謂語 - -* [述語関數] - -返回布爾類型的函數。 - -### 條件分歧 - -### 所有權 - -關於對象唯一性的概念。如果擁有對象的所有權,則可以對對象進行可變引用。 - -### 真偽類型-> 布爾 - -### 單噸 - -從只能生成一個實例的類生成的實例。也指確保只生成一個類實例的設計模式。 - -### 符號-> - -* [シンボル化] - -### 腳本../syntax/00_basic.md# 腳本 - -描述 Erg 程序的文件。 - -### 範圍 - -變量管理中的單位。外側的範圍不能參照存在於內側範圍的變量。另外,脫離範圍時,參照點數為 0 的對像被釋放。 - -### 跨頁運算符-> 展開賦值 - -### 切片../syntax/10_array.md# 切片 - -以形式生成的表示數組子串的對象。 - -### 控製字符 - -### 整數-> 輸入 - -自然數加負數的集合。 - -### 集../syntax/12_set.md - -### 分號->[;] - -### 聲明../syntax/03_declaration.md - -顯式設置變量類型。 - -### 全稱 - -* 全稱類型-> - * 封閉全稱類型 - * 打開的全稱類型 -* 全稱函數-> 多相關數 -* 全稱量化 - -### 前綴運算符 - -以格式應用的運算符。 - -### 互相的遞歸 - -### 下標-> 索引 - -### 屬性 - -* [屬性的部分型] - -## 多行 - -### 代數../syntax/02_name.md - -* 代數類型(../syntax/type/13_algebraic.md) -* 代數數據類型 - -### 賦值../syntax/02_variable.md/# 賦值 - -### 多重 - -* 多重繼承(../syntax/type/07_inheritance.md/# 禁止多重繼承) -* 多重賦值 -* 多重定義-> 禁止過載 - -### 多相 - -* 多相類型(../syntax/type/quantified.md) -* 多相關數 - -### 多態-> 多態 - -### 烤鴨打字 - -### 元組(../syntax/11_tuple.md) - -### 單相 - -* 單相化 -* 單相型 -* 單相關數 - -### 延遲初始化 - -### 抽出賦值 - -### 抽象語法樹->[AST] - -### 中置運算符 - -以格式應用的運算符。 - -### 常量../syntax/02_name.md/# 常量 - -可執行的、編譯時可評估的代數。 - -* 常量類型(../syntax/type/advanced/const.md) -* 常量表達式(../syntax/type/advanced/const.md) - -### 定義 - -分配與變量對應的對象。 - -### 授課屬性 - -可用作 API 的屬性。特別是由trait自動實現的屬性。 - -### 應用 - -將參數傳遞給函數對像以獲得評估結果。 - -### 裝飾器../syntax/29_decorate.md - - -```erg -@deco -f x = ... -``` - -的语法糖,或者。大約等於。本身只是一個高階子程序。 - -### 析構 - -銷毀對象時調用的方法。 - -### 過程-> - -讀取和寫入可變狀態的子程序。有時會解釋程序根據調用順序的不同,程序的執行結果也會發生變化,但如果說的是可換性的話,這是錯誤的。例如,作為函數子類型的運算符一般不是可換的。 - -### 缺省參數../syntax/04_function.md/# 缺省參數 default-parameters - -通過為虛擬自變量指定缺省值,調用時可以省略實際自變量指定的功能。 - -### 展開 - -* [展開演算子] -* [展開代入] - -### 特殊格式(../syntax/../API/special.md) - -不能傳遞給實際參數的對象。 - -### 匿名函數-> - -由未命名函數運算符生成的函數對象。不用定義名字就能使用。 - -### 點運算符()->[屬性引用] - -### 頂部 - -* 頂部類型-> 結構對象 -* 頂級-> 對象 - -### TRAIT(../syntax/type/03_trait.md) - -## 標題 - -### 內涵符號../syntax/27_comprehension.md - -### 中置算子 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -### 名稱空間 - -## 派系 - -### 陣列../syntax/10_array.md - -### 派生類型(../syntax/type/variances.md/# 用戶定義類型的退化) - -### 圖案(匹配)../syntax/26_pattern_matching.md - -### 軟件包../syntax/33_package_system.md - -### 哈希映射-> - -### 面片../syntax/type/07_patch.md - -### 公共變量-> - -### 參數-> - -### 參數化多相(../syntax/type/overloading.md) - -### 反變(../syntax/type/advanced/variance.md) - -### 比較 - -* [比較演算子] -* [比較可能型] - -### 私有變量../syntax/19_visibility.md - -### 標準 - -* 標準輸出 -* 標準輸入 -* 標準庫 - -### 副作用../syntax/07_side_effect.md - -代碼不能讀取或寫入外部可變狀態。 - -### 複數-> - -### 浮點數-> 浮點 - -### 專用變量-> 專用變量 - -### 布爾代數-> 布爾 - -### 程序../syntax/08_procedure.md - -### 參數(../syntax/04_function.md) - -### 部分類型-> 子類型 - -### 不變 - -在 Erg 中,對像不改變其內容。 - -* [不変オブジェクト] -* [不変型] -* [不変參照] - -### 篩型(../syntax/type/12_refinement.md) - -### 塊 - -### 分解賦值 - -### 變量../syntax/02_variable.md - -### 底部 - -* 底部->[{}] -* 底部類->Never - -### 多態 - -## 真行 - -### 前綴運算符 ~~~~~~ 前綴運算符 - -### 標記類型../syntax/type/advanced/marker_trait.md - -### 無名函數../syntax/21_lambda.md - -### 可變-> 可變 - -### 移動 - -### 方法 - -### 元字符 - -### 模塊(../syntax/24_module.md) - -### 字符串->Str - -* 字符串插值(../syntax/01_literal.md/#Str 文字) - -### 返回值 - -## 夜行 - -### 幽靈類型(../syntax/type/advanced/phantom.md) - -### 請求屬性 - -### 元素 - -### 調用 - -## 羅列 - -### 庫 - -### 拉姆達公式-> - -### 等級 - -* 通道 2 多相../syntax/type/advanced/rank2type.md - -### 文字(../syntax/01_literal.md) - -* 文字標識符(../syntax/18_naming_rule.md/# 文字標識符) - -### 量化(../syntax/type/quantified.md) - -### 佈局(../syntax/type/mut.md) - -### 枚舉類型(../syntax/type/10_enum.md) - -### 記錄../syntax/12_record.md - -* [レコード型] -* 記錄多相-> 列多相 - -### 列多相 - -### 局部變量../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 deleted file mode 100644 index 0c033c90..00000000 --- a/doc/zh_TW/dev_guide/unify_terms.md +++ /dev/null @@ -1,80 +0,0 @@ -# 術語統一 - -## 可見性、可見性 - -使用“Visibility(可見性)”。 - -## 完全(非、補) - -使用否定類型。 Complement 的結果不一定是 Not 型。 - -## Diff(差分型、排除型、直差型) - -使用排除類型。 Diff 的結果不一定是 Not 型。 - -## Intersection(交集、交集、笛卡爾) - -使用交叉類型。不使用笛卡兒積型。這是因為也有將元組視為笛卡兒積型的用法。但是,從屬性部分型的觀點來看,是與 Erg 的 And 型本質上等價的概念。另外,Intersection 的結果不一定是 And 型。例如。 - -## Nominal subtyping 的翻譯 - -雖然有記名的/名目的/標稱的部分定型,但是使用記名的部分定型。 - -## Ratio 型譯詞 - -使用有理數型。由於 Float 是單獨提供的,所以不稱為浮點數型。 - -## Union(合併、直和) - -使用合併類型。 Union 的結果不一定是 Or 型。 - -## 類型邊界(Type bound)、類型約束(Type constraint) - -量化型、篩子型所給謂詞式的列表。使用類型邊界。 - -## 子程序,例程,子程序 - -中描述的相應參數的值。 - -## 參照透明/不透明,有/無副作用 - -使用有/無副作用。 - -## 標識符、代數、變量、名稱、符號 - -原來的意思是, - -* 符號(Symbol):非字符串對象(未括在“”中)的純文本源代碼字符(符號、控製字符等除外)。 Ruby 和 Lisp 等中作為基本類型的符號存在,但在 Erg 中不被作為對象處理。 -* 標識符(Identifier):指向(也可以)某個對象的符號,而不是保留字。例如,在 Python 中,class 和 def 不能作為標識符使用。由於 Erg 中沒有保留字,所以除去一部分符號的所有符號都可以作為標識符使用。 -* 名稱(Name):幾乎等同於標識符。在 Erg 中也有與代數相同的意思使用。 -* 代數名(Algebra name):在 Erg 中等同於標識符。在 C 語言中,函數名是標識符,但不是代數名。 “代數”是指能夠用(變量賦值運算符)或(常量賦值運算符)賦值對象的語言功能本身。 - - -```erg -代數名 <: (名前 == 識別子) <: シンボル -変數 + 定數 == 代數 -``` - -但是,本來應該被稱為“代數”的多被稱為“變量”。這是數學術語的影響。值的內容可能變化的變量是可互斥變量,值的內容不變的變量是可互斥變量。另外,常數一定是可變的。 - -Erg 中代數名,不使用名稱,用標識符統一。但是,一般來說,的被稱為“變量 v”(“Variable v”),被稱為“常數 C”(“Constant C”)。 - -## 屬性、字段和特性 - -屬性,使用屬性。順便一提,記錄是指在沒有類的情況下可以定義具有要素屬性的對象的功能。 - -## 應用(Application)、調用(Call) - -通過向子程序對象提供參數來獲得結果。使用調用(Call)。因為 Application 具有“應用軟件”的用法。 - -## 數組、列表 - -使用 Array。這是因為 Erg 的排列(通常)是在存儲器上連續排列的。 List 指的是所謂的連接列表,或者作為 Python 的數據類型的列表。 - -## 過程,過程 - -與過程一致。子例程是函數(和運算符)、過程和方法的總稱。 Callable 是安裝了的全部。 - -## Lambda 函數、Lambda 表達式、匿名函數、匿名函數 - -統一為無名函數。英語中為了縮短字數可以使用 Lambda,但正式名稱是 Anonymous function。另外,Erg 的無名函數不是匿名的,所以不使用匿名函數。 \ No newline at end of file diff --git a/doc/zh_TW/faq_general.md b/doc/zh_TW/faq_general.md deleted file mode 100644 index 5e522c54..00000000 --- a/doc/zh_TW/faq_general.md +++ /dev/null @@ -1,27 +0,0 @@ -# Erg FAQ - -本常見問題解答適用於一般 Erg 入門用戶。請參閱以了解具體的(常見的)技術問題,或參閱以了解語法的決定(為什麼出現這種語法)。 - -## Erg 是 Python 兼容語言是什麼意思? - -~~A:Erg 的執行系統 EVM(Erg VirtualMachine,EVM)執行由 Python 字節代碼擴展而成的 Erg 字節代碼。這是在 Python 字節碼中引入的靜態定型系統(在不帶參數的指令中引入參數,在空號中實現專有指令)。這使得 Erg 能夠無縫調用 Python 的代碼,並實現快速執行。 ~~ - -答:Erg 腳本將轉換成 Python 字節碼。也就是說,它與 Python 在同一解釋器上運行。最初,我們計劃開發一個由 Python 解釋器(CPython)擴展而成的向上兼容處理系統,並將其與編譯器合併為“Erg”,但由於處理系統的開發遠遠落後於編譯器,因此我們決定只先公開編譯器。現在處理系統正在積極開發中。 - -## Erg 受到了什麼語言的影響? - -雙手也受到無數種語言的影響,其中受影響特別強烈的是 Python/Rust/Nim/Haskell。 Python 繼承了許多與越位規則兼容的語義學,Rust 繼承了面向表達式和trait,Nim 繼承了過程,Haskell 繼承了函數型編程相關的功能。 - -## 可以調用 Python 的語言包括 Julia。你為什麼做 Erg? - -答:Erg 的一個設計動機是,他想要一種語言,既易於使用,又具有強大的類型系統。即具有類型推理、卡印、依賴性等的語言。雖然 Julia 可以進行類型化,但它實際上是一種動態的類型化語言,不能提供靜態類型化語言的編譯時錯誤檢測優勢。 - -## Erg 支持多種樣式,包括函數型編程和麵向對象編程。這是不是與 Python 的“There should be one-and preferably only one--obvious way to do it.”背道而馳? - -A:在 Erg 中,這個詞可以理解成更狹隘的意思。例如,Erg API 通常沒有別名。在這個意義上,Erg 是“only one way”。在更大的意義和框架中,如函數類型或 OOP,只有一種方法不一定會帶來便利。例如,JavaScript 有多個庫來幫助創建可轉換程序,而 C 語言有多個垃圾回收庫。但是,如果有多個庫來執行這些基本功能,不僅會佔用選擇時間,而且會在使用不同庫的代碼之間進行集成時產生明顯的困難。即使是純函數語言 Haskell 也有支持面向對象的庫。如果沒有程序員,他們就會自己創造出來。那樣的話,我認為還是按標準提供比較好。這也符合 Python 的“Battery included”。 - -## Erg 名字的由來是什麼? - -名稱來源於 cgs 單位制中能量的單位 erg。這是一種雙重混合語言,它是一種人類工程學(ergonomic)語言,為程序員提供能量(雖然是後綴)。 - -雖然還有一些其他候選,但由於它們最短(Ruby 的作者 Matz 說,語言的名稱越短越好),並且具有相應的高格格不入性,因此決定了這一點。 \ No newline at end of file diff --git a/doc/zh_TW/faq_technical.md b/doc/zh_TW/faq_technical.md deleted file mode 100644 index 015fc33c..00000000 --- a/doc/zh_TW/faq_technical.md +++ /dev/null @@ -1,25 +0,0 @@ -# 技術常見問題解答 - -本節回答了使用 Erg 語言的技術問題。即,以“What”、“Which”開頭的問題,以及可以回答“Yes/No”的問題。 - -關於根本語法的決定,請參閱,關於為什麼創建這種語言,如何實現這種功能等更大的話題,請參閱。 - -## Erg 沒有異常機制嗎? - -A:沒有。 Erg 使用類型代替。有關為什麼 Erg 沒有異常機制的信息,請參見。 - -## Erg 沒有與 TypeScript 中的 Any 相對應的類型嗎? - -A:沒有。所有對象至少屬於類,但此類型只提供最少的屬性,不能像 Any 那樣隨心所欲。 類通過動態檢查(如)轉換為所需的類型。它與 Java 中的類似。在 Erg 的世界裡,不會出現像 TypeScript 那樣追尋 API 定義的結果是 Any 的絕望和混亂。 - -## Never,{},None,(),NotImplemented,Ellipsis 有什麼不同? - -A:類型為“不可能發生”。生成運行時錯誤的子例程返回類型為(或的合併類型)。如果檢測到這一點,程序將立即停止。儘管類型在定義上也是所有類型的子類,但類型對像不會出現在 Erg 代碼中,也不會生成。 等於是表示省略的對象,來自 Python。也來自 Python。這被用作未實現的標記,但 Erg 建議使用函數來生成錯誤。 的實例。常用於類型。 是單元類型,也是實例本身。如果要返回“無意義的值”(如過程的返回值),則使用此選項。 - -## 為什麼有效,而是 EffectError? - -A:不是標記副作用的產物,而是標記可能產生副作用的物體。過程和可變類型可能會產生副作用,但例如,如果返回的類型為,則其本身不會產生副作用。 - -## 嘗試使用 Python API 時,在 Erg 中,在 Python 中有效的代碼出現類型錯誤。這是什麼意思? - -答:Erg 的 API 盡量按照 Python 的 API 規范進行定型,但有些情況無論如何也無法表達。此外,根據 Erg 開發團隊的判斷,被認為有效但不期望的輸入(例如,可以在應輸入 int 的地方輸入浮點的規範)可能是類型錯誤。 \ No newline at end of file diff --git a/doc/zh_TW/improved_points.md b/doc/zh_TW/improved_points.md deleted file mode 100644 index b65b999c..00000000 --- a/doc/zh_TW/improved_points.md +++ /dev/null @@ -1,46 +0,0 @@ -# Python 的改進 - -## 執行靜態分析(靜態檢查、變量屬性檢查) - -雖然靜態檢查的好處不必再強調了,但檢查變量屬性的存在也是一個非常有效的部分。 - -## 嚴格處理範圍 - -Python 中的語句沒有作用域。因此,在和中定義的變量會影響外部。我不能隨便命名變量。 - - -```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 -``` - -## trait - -就像 Java 的界面一樣,它可以進行基於合約的編程。 - -Python 也有一個抽象基類,但這種結構與靜態定型結合在一起可以發揮最大的作用。 - -## 靜態解析依賴關係 - -防止長時間運行後模塊不足而導致錯誤等導致的遊戲體驗。 - -## 內置包管理器 - -使用標準化的目錄結構和構建文件進行可重複的構建。當然,還會生成鎖定文件並對其進行版本控制。我們不需要對 anaconda,pyenv,poetry,每個項目進行取捨和組合。 \ No newline at end of file diff --git a/doc/zh_TW/index.md b/doc/zh_TW/index.md deleted file mode 100644 index de23b5dc..00000000 --- a/doc/zh_TW/index.md +++ /dev/null @@ -1,25 +0,0 @@ -# 指數 - -## [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 deleted file mode 100644 index e01a174e..00000000 --- a/doc/zh_TW/migration_from_py.md +++ /dev/null @@ -1,28 +0,0 @@ -# Python 到 Erg 遷移的 Tips - -## 要將字符串轉換為 int 等 - -請使用類中的方法。它返回類型。 - - -```python -s: str -i: int = int(s) -``` - - -```erg -s: Str -res: Result(Int, IntParseError) = s.parse Int -i: Int = res.unwrap() -f: Result(Float, FloatParseError) = s.parse Float -``` - -也可以使用方法。 - - -```erg -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 deleted file mode 100644 index fad39b15..00000000 --- a/doc/zh_TW/python/bytecode_instructions.md +++ /dev/null @@ -1,106 +0,0 @@ -# Python Bytecode Instructions - -Python bytecode 的變量操作系統的指令通過 namei(name index)進行訪問。這是為了實現 Python 的動態變量訪問(可以使用 eval 等以字符串訪問)。 1 命令為 2byte,命令、自變量用 little endian 收納。不取參數的命令也使用 2byte(參數部分為 0)。 - -## STORE_NAME(namei) - - -```python -globals[namei] = stack.pop() -``` - -## LOAD_NAME(namei) - - -```python -stack.push(globals[namei]) -``` - -只能在頂層調用。 - -## LOAD_GLOBAL(namei) - - -```python -stack.push(globals[namei]) -``` - -這是為了在內部作用域中 Load 在頂層 STORE_NAME 後的內容,但如果在頂層,則與某個作用域代碼對像中的 namei 不一定相同(名稱相同,而不是 namei) - -## LOAD_CONST(namei) - - -```python -stack.push(consts[namei]) -``` - -從常量表中加載常量。目前(Python 3.9),CPython 將每個 Lambda 函數都命名為“\” - - -```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(namei) - -fastlocals[namei]=stack.pop()可能沒有(或單個)與頂級 STORE_NAME 相對應的參照的變量被認為是這樣存儲的特意全局空間有自己的指令是為了優化? - -## LOAD_FAST(namei) - -stack.push(fastlocals[namei] )fastlocals 是 varnames? - -## LOAD_CLOSURE(namei) - - -```python -cell = freevars[namei] -stack.push(cell) -``` - -然後,只有在調用 BUILD_TUPLE 的閉包中才會調用 BUILD_TUPLE,cellvars 將每個 cell(包含引用的容器)push 到堆棧中,而 LOAD_DEREF 似乎存儲閉包中的引用 - -## STORE_DEREF(namei) - - -```python -cell = freevars[namei] -cell.set(stack.pop()) -``` - -內部作用域中沒有參照的變量被 STORE_FAST,但是被參照的變量被 STORE_DEREF 的 Python 中,在這個命令內進行參照計數的增減 - -## LOAD_DEREF(namei) - - -```python -cell = freevars[namei] -stack.push(cell.get()) -``` - -## 名稱列表 - -### varnames - -與 fast_locals 相對應的函數內部變量的名稱列表 names 中具有相同名稱的變量基本上不相同(新創建的變量,不能從該範圍訪問外部變量),即沒有在範圍內定義的外部參照的變量將包含在 varnames 中 - -### names - -與 globals 相對應範圍內使用的外部常量(僅引用)的名稱列表(即使在頂層是普通變量,也會在 names 中)即,範圍外定義的常量會在 names 中 - -## free variable - -對應於 freevars 的閉包捕獲的變量。在同一函數實例內進行 static 行為。 - -## cell variables - -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 deleted file mode 100644 index 16bdccf4..00000000 --- a/doc/zh_TW/python/bytecode_specification.md +++ /dev/null @@ -1,70 +0,0 @@ -# Python bytecode specification - -## 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 - -* 如果我使用ascii以外的字符,它會變成PyUnicode嗎? -* "あ", "𠮷“,”和“α”是PyUnicode(不再使用?) - -* 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 - -* 說是 short,100 個以上的字也是這個 -* 或者說不是 short 沒有 ascii(short 是數據類型?) - -* 0 byte: 0xFA (means 'z') -* 1~4 byte: length of string -* 5~ byte: payload - -## PyInternedObject - -** intern 化的對象註冊在專用的 map 中,可以用 is 進行比較例如字符串等可以在不考慮長度的常量時間內進行比較 - -* 0 byte: 0x74 (means 't') - -## PyShortAsciiInternedObject - -* 0 byte: 0xDA (means 'Z') -* 1~4 byte: length of string -* 5~ byte: payload \ No newline at end of file diff --git a/doc/zh_TW/python/class_system.md b/doc/zh_TW/python/class_system.md deleted file mode 100644 index 8402fb32..00000000 --- a/doc/zh_TW/python/class_system.md +++ /dev/null @@ -1,95 +0,0 @@ -# Python 類系統(與 Erg 相比) - -## 方法 - -方法即使參照前方也沒有關係,這並不是因為使用了特別的技術,而是因為方法的實際存在被動態檢查。 (在 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 - File "", line 3, in g -TypeError: can only concatenate str (not "int") to str -``` - -在 Erg 中靜態檢查與母類的一致性。在覆蓋時,必須賦予裝飾器,並且要覆蓋的函數類型必須是要覆蓋的函數類型的部分類型。 - - -```erg ->>> C = Class() -... .f self = 1 -... .g self = self.f() + 1 -... ->>> D = Inherit C -... .f self = "a" -... -Error[#XX]: File "", line 5, in D -.f(self) is already defined in C. To override f, it must be added `Override` decorator and its type must be `Self.() -> Nat` or the subtype of that -.f(self)は既にCで定義されています。オーバーライドするためには`Override`デコレータを付與し、`Self.() -> Nat`型かそのサブタイプである必要があります。 -``` - -## 類型檢查 - -類型檢查大體上只限於函數自變量的類型檢查。在 Python 中,大部分的操作都是方法調用。調用時,如果對象所屬的類中附有方法的話,就到此為止。 - - -```python -def f(x): - return x.m() - -class C: - def m(self): return None - -c = C() -f(c) -f(1) # TypeError -``` - - -```erg -# 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) # TypeError: f takes a type has method `.m` as an argument, but passed Nat -``` \ No newline at end of file diff --git a/doc/zh_TW/python/index.md b/doc/zh_TW/python/index.md deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/syntax/00_basic.md b/doc/zh_TW/syntax/00_basic.md deleted file mode 100644 index 2749429e..00000000 --- a/doc/zh_TW/syntax/00_basic.md +++ /dev/null @@ -1,121 +0,0 @@ -# 基本信息 - -> :此文檔尚未完成。未進行校樣(文體、正確鏈接等)。此外,Erg 的語法在 0.* 版本之間可能會有顛覆性的改變,隨之而來的文檔更新可能跟不上。請事先諒解。 -> 此外,如果你發現本文檔中的錯誤,請從或提出更正建議。 - -本文檔介紹了 Erg 的基本語法。和位於不同的目錄中。 - -## Hello, World! - -首先按照慣例舉辦 Hello World 活動吧。 - - -```erg -print!("Hello, World!") -``` - -跟 Python 和同系語言差不多。引人注目的是後面的,我會慢慢解釋它的含義。此外,在 Erg 中,如果解釋不准確,可以省略括號。與 Ruby 類似,它可以省略括號,但它不能具有多個解釋,也不能在參數為 0 時省略,就像 Python 一樣。 - - -```erg -print! "Hello, World!" # OK -print! "Hello,", "World!" # OK -print!() # OK -print! # OK, but this does not mean to call, simply to get `print!` as a callable object - -print! f x # OK, interpreted as `print!(f(x))` -print!(f(x, y)) # OK -print! f(x, y) # OK -print! f(x, g y) # OK -print! f x, y # NG, can be taken to mean either `print!(f(x), y)` or `print!(f(x, y))` -print!(f x, y) # NG, can be taken to mean either `print!(f(x), y)` or `print!(f(x, y))` -print! f(x, g y, z) # NG, can be taken to mean either `print!(x, g(y), z)` or `print!(x, g(y, z))` -``` - -## 腳本 - -Erg 代碼稱為腳本。可以以文件格式(.er)保存和運行腳本。 - -## 註釋 - -及更高版本將作為註釋忽略。當你想要解釋代碼的意圖,或者想要暫時禁用代碼時,可以使用此選項。 - - -```erg -# コメント -## `#`以降は改行されるまで無視されるので、`#`は何個あってもOK -#[ -複數行コメント -対応する`]#`のところまでずっとコメントとして扱われます -]# -``` - -## 表達式,分隔符 - -腳本是一系列表達式(expression)。表達式是一個可以計算和評估的東西,在 Erg 中幾乎所有的東西都是表達式。使用分隔符-換行符或分號-分隔每個表達式。 Erg 腳本基本上是從左到右、從上到下進行評估的。 - - -```erg -n = 1 # 代入式 -f(1, 2) # 関數適用式 -1 + 1 # 演算子適用式 -f(1, 2); 1 + 1 -``` - -有一個稱為即時塊的功能,它使用塊中最後計算的表達式作為變量的值,如下所示。這與無參數函數不同,它不使用。請注意,方塊只在現場評估一次。 - - -```erg -i = - x = 1 - x + 1 -assert i == 2 -``` - -這不能通過分號()來實現。 - - -```erg -i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses -``` - -## 縮進 - -Erg 使用與 Python 相同的縮進來表示塊。觸發塊開始的運算符(特殊格式)有五種:,(其他運算符不是,但也會生成縮進)。它們各自的含義將在後面介紹。 - - -```erg -f x, y = - x + y - -for! 0..9, i => - print! i - -for! 0..9, i => - print! i; print! i - -ans = match x: - 0 -> "zero" - _: 0..9 -> "1 dight" - _: 10..99 -> "2 dights" - _ -> "unknown" -``` - -如果一行太長,可以使用在中間換行。 - - -```erg -# this does not means `x + y + z` but means `x; +y; +z` -x -+ y -+ z - -# this means `x + y + z` -x \ -+ y \ -+ z -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/01_literal.md b/doc/zh_TW/syntax/01_literal.md deleted file mode 100644 index 5a0e8efc..00000000 --- a/doc/zh_TW/syntax/01_literal.md +++ /dev/null @@ -1,165 +0,0 @@ -# Literal - -## 基本文字 - -### 整數文字(Int Literal) - - -```erg -0, -0, 1, -1, 2, -2, 3, -3, ... -``` - -### 有理數文字(Ratio Literal) - - -```erg -0.00, -0.0, 0.1, 400.104, ... -``` - -如果文字中的整數或小數部分為,則可以省略。 - - -```erg -assert 1.0 == 1. -assert 0.5 == .5 -``` - -> :這個名為的函數用於指示相等。 -以下文檔可能會使用來表示結果相等。 - -### 字符串文字(Str Literal) - -可以使用 Unicode 表示的任何字符串。與 Python 不同的是,不能進行標定。如果要在字符串中使用,請使用。 - - -```erg -"", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "السَّلَامُ عَلَيْكُمْ", ... -``` - -使用將表達式填充到字符串中。這稱為字符串插值。如果要輸出本身,請輸入。 - - -```erg -assert "1 + 1 is 2" == "{1} + {1} is {1+1}" -s = "1+1" -assert "\{1+1}\" == "\{{s}\}" -``` - -### 指數文字(Exponential Literal) - -這是在學術計算中經常使用的指數表示法的文字。它將成為類型為的實例。用於表示非常大/非常小的數字。與 Python 相同。 - - -```erg -1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ... -``` - - -```erg -assert 1e-10 == 0.0000000001 -``` - -## 文字的組合(複合文字) - -在文檔中,這些文字都有單獨的說明,有關詳細信息,請參閱。 - -### 數組文字(./10_array.md) - - -```erg -[], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ... -``` - -### 字典文字(./11_dict.md) - - -```erg -{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ... -``` - -### 元組文字(./12_tuple.md) - - -```erg -(), (1, 2, 3), (1, "hello", True), ... -``` - -### 記錄文字(./13_record.md) - - -```erg -{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ... -``` - -### 集文字(./14_set.md) - - -```erg -{}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ... -``` - -與文字不同,刪除重複元素。 - - -```erg -assert {1, 2, 1} == {1, 2} -``` - -### 看起來像文字但不像文字的東西 - -## 真偽對象(Boolean Object) - - -```erg -True, False -``` - -### None 對象 - - -```erg -None -``` - -## 範圍對象(Range Object) - - -```erg -assert 0..5 == {1, 2, 3, 4, 5} -assert 0..10 in 5 -assert 0..<10 notin 10 -assert 0..9 == 0..<10 -``` - -## 浮點對象(Float Object) - - -```erg -assert 0.0f64 == 0 -assert 0.0f32 == 0.0f64 -``` - -對象乘以,即的單位對象。 - -## 複雜對象(Complex Object) - - -```erg -1+2im, 0.4-1.2im, 0im, im -``` - -對象僅通過與的運算組合來表示,是一個虛單位對象。 - -## *-less multiplication - -Erg 可以省略表示乘法的,除非解釋正確。但是,運算符的連接強度設置為大於。 - - -```erg -# same as `assert (1*m) / (1*s) == 1*(m/s)` -assert 1m / 1s == 1 (m/s) -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/02_name.md b/doc/zh_TW/syntax/02_name.md deleted file mode 100644 index 95807647..00000000 --- a/doc/zh_TW/syntax/02_name.md +++ /dev/null @@ -1,169 +0,0 @@ -# 變量 - -變量是代數的一種。 Erg 中的代數-有時也稱為變量(如果正確)-是指命名對象並使其可從代碼中的其他位置使用的功能。 - -變量定義如下。部分稱為變量名(或標識符),稱為賦值運算符,部分稱為賦值。 - - -```erg -n = 1 -``` - -以這種方式定義的隨後可用作表示整數對象的變量。此系統稱為賦值(或綁定)。我們剛才提到了是一個對象。我們將在後面討論對像是什麼,但我們現在應該將其賦值到賦值運算符(例如)的右側。 - -如果要指定變量的類型。類型是指對象所屬的集合,這也將在後面介紹。指定為自然數()。 - - -```erg -n: Nat = 1 -``` - -請注意,與其他語言不同,多重賦值是不可能的。 - - -```erg -# NG -l1 = l2 = [1, 2, 3] # SyntaxError: 多重代入はできません -# OK -l1 = [1, 2, 3] -l2 = l1.clone() -``` - -也不能對變量進行重新賦值。可以使用的功能,即保持可變狀態的功能將在後面討論。 - - -```erg -i = 1 -i = i + 1 # AssignError: cannot assign twice -``` - -你可以在內部範圍內定義具有相同名稱的變量,但它們只是放在上面,而不是破壞性地重寫值。如果返回到外部範圍,則值也將返回。請注意,這與 Python“語句”的作用域不同。這類功能通常稱為陰影。但是,與其他語言的陰影不同,你不能在同一範圍內進行陰影。 - - -```erg -x = 0 -# x = 1 # AssignError: cannot assign twice -if x.is_zero(), do: - x = 1 # 外側のxとは同名の別物 - assert x == 1 -assert x == 0 -``` - -以下乍一看似乎可行,但還是不行。這不是技術限制,而是設計判斷。 - - -```erg -x = 0 -if x.is_zero(), do: - x = x + 1 # NameError: cannot define variables refer to variables with the same name - assert x == 1 -assert x == 0 -``` - -## 常數 - -常數也是代數的一種。如果標識符以大寫字母開頭,則將其視為常量。它被稱為常量,因為它一旦定義就不會改變。部分稱為常量名稱(或標識符)。其他與變量相同。 - - -```erg -N = 0 -if True, do: - N = 1 # AssignError: constants cannot be shadowed - pass() -``` - -常量在定義的範圍之後變得不變。我也不能陰影。由於該性質,常量可用於模式匹配。後面我們會討論模式匹配。 - -你可能希望將常量用於不變的值,如數學常量或有關外部資源的信息。除之外的對象通常是全部大寫字母(所有字符都是大寫的樣式)。 - - -```erg -PI = 3.141592653589793 -URL = "https://example.com" -CHOICES = ["a", "b", "c"] -``` - - -```erg -PI = 3.141592653589793 -match! x: - PI => print! "π" - other => print! "other" -``` - -當為時,上面的代碼輸出。如果將更改為其他數字,則輸出。 - -有些常量是不能賦值的。可變對像等等。可變對像是可以更改其內容的對象,如下所述。這是因為常量只能由常量表達式賦值。我們還將在後面討論常數表達式。 - - -```erg -X = 1 # OK -X = !1 # TypeError: cannot define Int! object as a constant -``` - -## 刪除代數 - -可以使用函數刪除代數。所有依賴於代數(直接引用代數的值)的其他代數都將被刪除。 - - -```erg -x = 1 -y = 2 -Z = 3 -f a = x + a - -assert f(2) == 3 -Del x -Del y, Z - -f(2) # NameError: f is not defined (deleted in line 6) -``` - -但是,只能刪除模塊中定義的代數。不能刪除內置常量,如。 - - -```erg -Del True # TypeError: cannot delete built-in constants -Del print! # TypeError: cannot delete built-in variables -``` - -## Appendix:賦值等價性 - -注意,當時,不一定是。例如有。這是由 IEEE 754 規定的正式浮點數的規格。 - - -```erg -x = Float.NaN -assert x != Float.NaN -assert x != x -``` - -其他,也存在原本就沒有定義等值關係的對象。 - - -```erg -f = x -> x**2 + 2x + 1 -g = x -> (x + 1)**2 -f == g # TypeError: cannot compare function objects - -C = Class {i: Int} -D = Class {i: Int} -C == D # TypeError: cannot compare class objects -``` - -嚴格地說,並不是將右邊值直接代入左邊的識別符。函數對象和類對象的情況下,對對象進行賦予變量名的信息等的“修飾”。但是結構型的情況不受此限制。 - - -```erg -f x = x -print! f # -g x = x + 1 -print! g # - -C = Class {i: Int} -print! C # -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/03_declaration.md b/doc/zh_TW/syntax/03_declaration.md deleted file mode 100644 index 7bb1a7e2..00000000 --- a/doc/zh_TW/syntax/03_declaration.md +++ /dev/null @@ -1,48 +0,0 @@ -# 聲明 - -聲明是指定要使用的變量類型的語法。可以在代碼中的任何地方聲明,但不能只聲明變量。必須始終初始化。賦值後聲明可以檢查類型是否與賦值對象匹配。 - - -```erg -i: Int -# i: Int = 2可以與賦值同時聲明 -i = 2 -i: Num -i: Nat -i: -2..2 -i: {2} -``` - -賦值後聲明類似於類型檢查,但在編譯時進行檢查。運行時使用進行類型檢查可以用“可能是 XX”進行檢查,但編譯時使用進行類型檢查是嚴格的。如果沒有確定是“某某型”,就無法通過檢查,就會出現錯誤。 - - -```erg -i = (-1..10).sample!() -assert i in Nat # 這可能會通過 -i: Int # 這通過了 -i: Nat # 這不起作用(因為 -1 不是 Nat 的元素) -``` - -可以通過兩種方式聲明函數。 - - -```erg -f: (x: Int, y: Int) -> Int -f: (Int, Int) -> Int -``` - -如果顯式聲明參數名稱,則在定義時如果名稱不同,將導致類型錯誤。如果你想給出參數名稱的任意性,可以使用第二種方法聲明它。在這種情況下,類型檢查只顯示方法名稱及其類型。 - - -```erg -T = Trait { - .f = (x: Int, y: Int): Int -} - -C = Class(U, Impl := T) -C.f(a: Int, b: Int): Int = ... # TypeError: `.f` must be type of `(x: Int, y: Int) -> Int`, not `(a: Int, b: Int) -> Int` -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/04_function.md b/doc/zh_TW/syntax/04_function.md deleted file mode 100644 index 3d555b66..00000000 --- a/doc/zh_TW/syntax/04_function.md +++ /dev/null @@ -1,306 +0,0 @@ -# 函數 - -函數是一個塊,它接受參數並對其進行處理,然後將其作為返回值返回。定義如下。 - - -```erg -add x, y = x + y -# or -add(x, y) = x + y -``` - -在定義函數時指定的參數通常稱為偽參數(parameter)。相反,函數調用過程中傳遞的參數稱為實際參數(argument)。是接受作為假參數,然後返回的函數。你可以按如下方式調用(應用)定義的函數。 - - -```erg -add 1, 2 -# or -add(1, 2) -``` - -## 冒號樣式 - -函數的調用方式如下:,但如果實際參數太多,一行太長,則可以使用(冒號)來應用。 - - -```erg -f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4 -``` - - -```erg -f some_long_name_variable_1 + some_long_name_variable_2: - some_long_name_variable_3 * some_long_name_variable_4 -``` - - -```erg -f: - some_long_name_variable_1 + some_long_name_variable_2 - some_long_name_variable_3 * some_long_name_variable_4 -``` - -上面三個代碼都是同一個意思。此樣式在使用函數時也很有用。 - - -```erg -result = if Bool.sample!(): - do: - log "True was chosen" - 1 - do: - log "False was chosen" - 0 -``` - -在之後,不能寫註釋以外的代碼,必須換行。 - -## 關鍵字參數(Keyword Arguments) - -如果定義了具有大量參數的函數,則可能會導致傳遞參數的順序錯誤。在這種情況下,使用關鍵字參數進行調用是安全的。 - - -```erg -f x, y, z, w, v, u: Int = ... -``` - -上面定義的函數有很多參數,並且排列很難懂。我們不應該做這樣的函數,但在使用別人寫的代碼時可能會碰到這樣的代碼。因此,我們使用關鍵字參數。關鍵字參數的名稱優先於順序,因此即使順序不正確,也會將值從名稱傳遞到正確的參數。 - - -```erg -f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3 -``` - -請注意,如果在關鍵字參數和之後立即換行,將被視為冒號應用樣式。 - - -```erg -# means `f(x: y)` -f x: y - -# means `f(x, y)` -f x: - y -``` - -## 默認參數(Default parameters) - -如果一個參數在大多數情況下是固定的,並且你想要省略它,則可以使用默認參數。 - -缺省參數由(or-assign operator)指定。如果未指定,則將賦給。 - - -```erg -math_log x: Ratio, base := math.E = ... - -assert math_log(100, 10) == 2 -assert math_log(100) == math_log(100, math.E) -``` - -請注意,不指定參數和賦值是有區別的。 - - -```erg -p! x := 0 = print! x -p!(2) # 2 -p!() # 0 -p!(None) # None -``` - -也可以與類型和模式一起使用。 - - -```erg -math_log x, base: Ratio := math.E = ... -f [x, y] := [1, 2] = ... -``` - -但是,在缺省參數中,不能調用以下過程或賦值可變對象。 - - -```erg -f x := p! 1 = ... # NG -``` - -此外,不能將剛定義的參數用作傳遞給缺省參數的值。 - - -```erg -f x := 1, y := x = ... # NG -``` - -## 可變長度參數 - -函數將參數作為日誌輸出,可以接收任意數量的參數。 - - -```erg -log "Hello", "World", "!" # Hello World ! -``` - -如果要定義這樣的函數,請將作為參數。這樣,參數就可以作為可變長度數組接收。 - - -```erg -f x: ...Int = - for x, i -> - log i - -# x == [1, 2, 3, 4, 5] -f 1, 2, 3, 4, 5 -``` - -## 多模式函數定義 - - -```erg -fib n: Nat = - match n: - 0 -> 0 - 1 -> 1 - n -> fib(n - 1) + fib(n - 2) -``` - -如果函數的定義正下方出現,如上面所示,則可以重寫如下所示。 - - -```erg -fib 0 = 0 -fib 1 = 1 -fib(n: Nat): Nat = fib(n - 1) + fib(n - 2) -``` - -請注意,多模式函數定義不是所謂的過載(多重定義)。一個函數始終只有一個類型。在上面的示例中,必須與具有相同的類型。此外,與相同,模式匹配從上到下依次進行。 - -如果存在不同類的混合實例,則必須在最後一個定義中指明函數參數類型為 Or。 - - -```erg -f "aa" = ... -f 1 = ... -# `f x = ...` is invalid -f x: Int or Str = ... -``` - -它還必須具有包容性,如。 - - -```erg -fib 0 = 0 -fib 1 = 1 -# PatternError: pattern of fib's parameter is not exhaustive -``` - -但是,即使在上述情況下,也可以使用下面的顯式指定類型來獲得全面性。 - - -```erg -fib: 0..1 -> 0..1 -fib 0 = 0 -fib 1 = 1 -# OK -``` - -## 遞歸函數 - -遞歸函數是定義中包含自身的函數。 - -作為一個簡單的例子,我們嘗試定義函數來計算階乘。階乘是“乘以所有小於或等於的正數”的計算。 5 的階乘為。 - - -```erg -factorial 0 = 1 -factorial 1 = 1 -factorial(n: Nat): Nat = n * factorial(n - 1) -``` - -首先從階乘定義開始,0 和 1 的階乘都是 1. 按順序計算,2 的階乘為,3 的階乘為,4 的階乘為。如果你仔細觀察這裡,你會發現一個數字 n 的階乘是它前面的數字 n-1 的階乘乘以 n。如果你將其放入代碼中,則會得到。 是遞歸函數,因為的定義包含它自己。 - -注意,如果未指定類型,則會這樣推斷。 - - -```erg -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) -``` - -但是,即使可以推理,也應該明確指定遞歸函數的類型。在上面的示例中,像這樣的代碼是有效的, - - -```erg -factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ... -``` - -,此計算不會停止。如果不仔細定義值的範圍,遞歸函數可能會陷入無限循環。類型還有助於防止接受不想要的值。 - -## 編譯時函數 - -如果函數名以大寫字母開頭,則該函數為編譯時函數。所有用戶定義的編譯時函數的參數都必須是常量,並且必須顯式。編譯函數能做的事情是有限的。在編譯時函數中只能使用常量表達式,即某些運算符(四則運算,比較運算,類型構建運算等)和編譯時函數。賦值的參數也必須是常量表達式。相反,計算可以在編譯時進行。 - - -```erg -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 # ConstantError: this function is not computable at compile time -``` - -編譯時函數通常用於多相類型定義等。 - - -```erg -Option T: Type = T or NoneType -Option: Type -> Type -``` - -## Appendix:比較函數 - -Erg 沒有為函數定義。那是因為函數的結構等價性判定算法一般不存在。 - - -```erg -f = x: Int -> (x + 1)**2 -g = x: Int -> x**2 + 2x + 1 - -assert f == g # TypeError: cannot compare functions -``` - -和總是返回相同的結果,但這是非常困難的。我們得把代數學灌輸給編譯器。因此,Erg 放棄了整個函數比較,也會導致編譯錯誤。這是與 Python 不同的規格,需要注意。 - - -```python -# Python, weird example -f = lambda x: x -assert f == f -assert (lambda x: x) != (lambda x: x) -``` - -## Appendix2:完成() - - -```erg -f x: Object = ... -# will be completed to -f(x: Object) = ... - -f a -# will be completed to -f(a) - -f a, b # TypeError: f() takes 1 positional argument but 2 were given -f(a, b) # TypeError: f() takes 1 positional argument but 2 were given -f((a, b)) # OK -``` - -函數類型實際上是的语法糖。 - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/05_builtin_funcs.md b/doc/zh_TW/syntax/05_builtin_funcs.md deleted file mode 100644 index 5b281cd1..00000000 --- a/doc/zh_TW/syntax/05_builtin_funcs.md +++ /dev/null @@ -1,52 +0,0 @@ -# 內置函數 - -## if - -是一個函數,它可以根據條件改變操作。 - - -```erg -result: Option Int = if! Bool.sample!(), do: - log "True was chosen" - 1 -print! result # None (or 1) -``` - -隨機返回集合的值。如果返回值為 true,則執行。還可以指定當條件為假時如何處理。第二個 do 塊稱為 else 塊。 - - -```erg -result: Nat = if Bool.sample!(): - do: - log "True was chosen" - 1 - do: - log "False was chosen" - 0 -print! result # 1 (or 0) -``` - -如果只執行一行操作,則可以省略縮進。 - - -```erg -result = if Bool.sample!(): - do 1 - do 0 -``` - -## for - -你可以使用來編寫重複的操作。 - - -```erg -match_s(ss: Iterator(Str), pat: Pattern): Option Str = - for ss, s -> - if pat.match(s).is_some(): - break s -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/06_operator.md b/doc/zh_TW/syntax/06_operator.md deleted file mode 100644 index d3314cfd..00000000 --- a/doc/zh_TW/syntax/06_operator.md +++ /dev/null @@ -1,30 +0,0 @@ -# 運算符 - -運算符(操作符)是表示運算的符號。運算符(操作數)位於運算符的右側(左),在 Erg 中它只是一個對象。 - -運算符是一種函數,因此它本身也可以綁定到一級對像中的變量。綁定必須用包圍。對於(和),必須指定(二元運算)/(一元運算)以實現唯一化,因為同時存在一元運算符和二元運算符。 - - -```erg -add = `+` # SyntaxError: specify `_+_` or `+_` -add = `_+_` -assert f(1, 2) == 3 -assert f("a", "b") == "ab" - -g = `*` # OK, this is binary only -assert g(1, 2) == 2 -``` - -但是,請注意,某些稱為特殊格式的運算符不能被綁定。 - - -```erg -def = `=` # SyntaxError: cannot bind `=` operator, this is a special form -# NG: def x, 1 -function = `->` # SyntaxError: cannot bind `->` operator, this is a special form -# NG: function x, x + 1 -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/07_side_effect.md b/doc/zh_TW/syntax/07_side_effect.md deleted file mode 100644 index c3bedc5b..00000000 --- a/doc/zh_TW/syntax/07_side_effect.md +++ /dev/null @@ -1,123 +0,0 @@ -# 副作用和過程 - -到目前為止,我一直沒有解釋中的含義,現在我終於明白了它的含義。這個!直截了當地表示此對像是具有“副作用”的“過程”。過程對函數產生了一種稱為“副作用”的效果。 - - -```erg -f x = print! x # EffectError: functions cannot be assigned objects with side effects -# hint: change the name to 'f!' -``` - -上面的代碼是編譯錯誤。因為你在函數中使用過程。在這種情況下,必須將其定義為過程。 - - -```erg -p! x = print! x -``` - -,,...是代表過程的典型變量名稱。以這種方式定義的過程也不能在函數中使用,因此副作用是完全隔離的。 - -## 方法 - -每個函數和過程都有一個方法。函數方法僅保留的不變引用,過程方法保留的可變引用。 是一個特殊參數,在方法上下文中是指調用的對象本身。引用的不能指定給任何其他變量。 - - -```erg -C. - method ref self = - x = self # OwnershipError: cannot move out 'self' - x -``` - -該方法還可以剝奪的所有權。該方法的定義不包括。 - - -```erg -n = 1 -s = n.into(Str) # '1' -n # ValueError: n was moved by .into (line 2) -``` - -始終只能有一個過程方法具有可變引用。此外,當可變參照被取走時,將無法從原始對象獲取參照。從這個意義上說,會對產生副作用。 - -但是,請注意,可以從可變參照生成(不變/可變)參照。這允許你在過程方法中遞歸或。 - - -```erg -T -> T # OK (move) -T -> Ref T # OK -T => Ref! T # OK (only once) -Ref T -> T # NG -Ref T -> Ref T # OK -Ref T => Ref! T # NG -Ref! T -> T # NG -Ref! T -> Ref T # OK -Ref! T => Ref! T # OK -``` - -## Appendix:嚴格定義副作用 - -代碼有沒有副作用的規則並不是馬上就能理解的。在理解之前,建議先將其定義為函數,然後在出現錯誤時將其定義為過程。但是,對於那些想要掌握語言嚴格規範的人來說,下面我們會更詳細地介紹副作用。 - -首先,請注意,返回值的等價性與 Erg 中的副作用無關。對於任何,都有一個過程(例如,總是返回),也有一個函數是。 - -前一個示例是,後一個示例是以下函數。 - - -```erg -nan _ = Float.NaN -assert nan(1) != nan(1) -``` - -也有一些對象無法進行等價判定,例如類或函數。 - - -```erg -T = Structural {i = Int} -U = Structural {i = Int} -assert T == U - -C = Class {i = Int} -D = Class {i = Int} -assert C == D # TypeError: cannot compare classes -``` - -回到正題上來。 “副作用”在 Erg 中的確切定義是, - -* 訪問外部可變信息 - -中選擇所需的牆類型。外部通常是指外部範圍。 “外部”不包括 Erg 無法接觸的計算機資源或運行前/運行後信息。 “訪問”不僅包括寫入,還包括讀取。 - -以過程為例。 看似沒有重寫任何變量。但是,如果這是一個函數,那麼外部變量可以用這樣的代碼重寫。 - - -```erg -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 -``` - -模塊是為相機產品提供 API 的外部庫,是 OCR(光學字符識別)的庫。直接副作用是由引起的,但顯然,這些信息是從洩露的。因此,在性質上不能是函數。 - -然而,當你在函數中臨時檢查值時,你可能不希望將附加到相關函數中。在這種情況下,可以使用函數在執行整個代碼後顯示值。這不會傳播副作用。 - - -```erg -log "this will be printed after execution" -print! "this will be printed immediately" -# this will be printed immediately -# this will be printed after execution -``` - -換句話說,如果程序沒有反饋,即任何外部對像都不能使用該信息,則信息的“洩露”本身可能是允許的。不被“傳播”就行了。 - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/08_procedure.md b/doc/zh_TW/syntax/08_procedure.md deleted file mode 100644 index 4a2ca07a..00000000 --- a/doc/zh_TW/syntax/08_procedure.md +++ /dev/null @@ -1,12 +0,0 @@ -# 過程 - -處理可變對象時需要過程,但如果變量對像是參數,則不一定是過程。 - - -```erg -peek_str s: Str! = log s -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/09_builtin_procs.md b/doc/zh_TW/syntax/09_builtin_procs.md deleted file mode 100644 index f6eda744..00000000 --- a/doc/zh_TW/syntax/09_builtin_procs.md +++ /dev/null @@ -1,13 +0,0 @@ -# 內置過程 - -## id! - -返回對象的唯一標識號。在純 Erg 語義中,結構相同的對象之間沒有差異,但實際上,對像在內存中的位置是不同的。返回表示此位置的數字。 - - -```erg -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/10_array.md b/doc/zh_TW/syntax/10_array.md deleted file mode 100644 index 33e7e557..00000000 --- a/doc/zh_TW/syntax/10_array.md +++ /dev/null @@ -1,56 +0,0 @@ -# 排列 - -數組是最基本的。集合是可以在內部包含多個對象的對象。 - - -```erg -a = [1, 2, 3] -a: [Int; 3] # 型指定: セミコロンの後の數字は要素數 -# 要素數がわからない場合は省略可能 -a: [Int] - -mut_a = [!1, !2, !3] -mut_a[0].inc!() -assert mut_a == [2, 2, 3] -``` - -通常,數組不能包含不同類型的對象。 - - -```erg -[1, "a"] # TypeError: 1st element is Int, but 2nd element is Str -``` - -但是,這種顯式類型可以避免限制。 - - -```erg -[1, "a"]: [Int or Str] -``` - -## 切片 - -數組還可以同時檢索多個值。我們管這個叫切片。 - - -```erg -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] -``` - -切片獲得的對像是數組的(不可變)引用。 - - -```erg -print! Typeof l[1..2] # Ref [Int; 4] -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/11_tuple.md b/doc/zh_TW/syntax/11_tuple.md deleted file mode 100644 index 96f03ab0..00000000 --- a/doc/zh_TW/syntax/11_tuple.md +++ /dev/null @@ -1,125 +0,0 @@ -# 元 - -元組類似於數組,但可以包含不同類型的對象。這樣的收藏稱為非等質收藏。與此相對,等質集合包括數組和集合。 - - -```erg -t = (1, True, "a") -(i, b, s) = t -assert(i == 1 and b == True and s == "a") -``` - -元組可以以的形式檢索第 n 個元素。請注意,與 Python 不同,它不是。這是因為元組元素的訪問更接近於屬性,而不是方法(數組中的是方法)(編譯時檢查元素是否存在,類型可以根據 n 而變化)。 - - -```erg -assert t.0 == 1 -assert t.1 == True -assert t.2 == "a" -``` - -不嵌套時,括號是可選的。 - - -```erg -t = 1, True, "a" -i, b, s = t -``` - -元組可以包含不同類型的對象,但不能包含數組之類的小版本。 - - -```erg -t: ({1}, {2}, {3}) = (1, 2, 3) -(1, 2, 3).iter().map(x -> x + 1) # TypeError: type ({1}, {2}, {3}) has no method `.iter()` -# すべて同じ型の場合配列と同じように`(T; n)`で表せるが、これでもイテレーションは出來ない -t: (Int; 3) = (1, 2, 3) -assert (Int; 3) == (Int, Int, Int) -``` - -但是,非等質集合(如元組)可以通過上傳、Intersection 等轉換為等質集合(如數組)。這叫做等質化。 - - -```erg -(Int, Bool, Str) can be [T; 3] | T :> Int, T :> Bool, T :> Str -``` - - -```erg -t: (Int, Bool, Str) = (1, True, "a") # non-homogenous -a: [Int or Bool or Str; 3] = [1, True, "a"] # homogenous -_a: [Show; 3] = [1, True, "a"] # homogenous -_a.iter().map(x -> log x) # OK -t.try_into([Show; 3])?.iter().map(x -> log x) # OK -``` - -## 單位 - -具有 0 個元素的元組稱為單元。單位是一個值,但也指其類型本身。 - - -```erg -unit = () -(): () -``` - -單元是所有元素 0 元組的超類。 - - -```erg -() > (Int; 0) -() > (Str; 0) -``` - -此對象的用途包括參數、沒有返回值的過程等。 Erg 子例程必須具有參數和返回值。但是,在某些情況下,例如在過程中,可能會產生副作用,但沒有有意義的參數返回值。在這種情況下,單位作為“沒有意義的,形式上的值”來使用。 - - -```erg -# ↓ 実はこの括弧はユニット -p!() = - # `print!`は意味のある値を返さない - print! "Hello, world!" -p!: () => () -``` - -但是,Python 在這種情況下更傾向於使用而不是單位。在 Erg 中,如果一開始就確定不返回有意義的值(如過程),則返回;如果操作失敗,可能一無所獲(如元素檢索),則返回。 - -## 參數和元組 - -實際上,Erg 的所有對像都是一個參數,一個返回值。具有 N 個參數的子程序僅接受“一個具有 N 個元素的元組”作為參數。 - - -```erg -# f x = ...は暗黙にf(x) = ...とみなされる -f x = x -assert f(1) == 1 -f(1, 2, 3) # ArgumentError: f takes 1 positional argument but 3 were given -# 可変個の引數を受け取る -g x: Int, ...y: Int = y -assert (2, 3) == g 1, 2, 3 -``` - -這將解釋函數的類型。 - - -```erg -assert f in T: {(T,) -> T | T} -assert g in {(Int, ...(Int; N)) -> (Int; N) | N: Nat} -``` - -準確地說,函數的輸入不是元組,而是具有默認屬性的命名元組。這是一個特殊的元組,只能作為函數的參數使用,可以像記錄一樣命名並具有缺省值。 - - -```erg -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) -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/12_dict.md b/doc/zh_TW/syntax/12_dict.md deleted file mode 100644 index 96e4b68e..00000000 --- a/doc/zh_TW/syntax/12_dict.md +++ /dev/null @@ -1,71 +0,0 @@ -# Dict - -Dict 是一個包含鍵值對的集合。 - - -```erg -ids = {"Alice": 145, "Bob": 214, "Charlie": 301} -assert ids["Alice"] == 145 -``` - -如果密鑰為 Hash,則該密鑰可以不是字符串。 - - -```erg -# rangeオブジェクトをキーにするのは非推奨(スライスと混同される) -r = {1..3: "1~3", 4..6: "4~6", 7..9: "7~9"} -assert r[1..3] == "1~3" -l = {[]: "empty", [1]: "1"} -assert l[[]] == "empty" -``` - -順序對迪奇並不重要。也不能有重複的元素。在這一點上,Dict 與相似。 Dict 也可以說是一個有價值的 Set。 - - -```erg -{"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214} -``` - -從 Dict 文字生成 Dict 時,將檢查是否存在重複的鍵。如果存在重複項,則會導致編譯錯誤。 - - -```erg -{"Alice": 145, "Alice": 1} # KeyError: Duplicate key "Alice" -``` - -使用生成空 Dict。請注意,表示空數組。 - - -```erg -mut_dict = !{:} -mut_dict.insert! "Alice", 145 -mut_dict.insert! "Bob", 214 -assert mut_dict["Alice"] == 145 -``` - -## Heterogeneous Dict - -鍵值的類型可以不是單一的,這樣的字典稱為。 - - -```erg -d: {Str: Int, Int: Str} = {”a”: 1, 1: “a”} -assert d[”a”] == 1 -assert d[1] == “a” -``` - -但是,不能將相同類型的值應用於不同類型的鍵,也不能將不同類型的值應用於不同類型的鍵。在這些情況下,請改用 Or 類型(Union)。 - - -```erg -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} -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/13_record.md b/doc/zh_TW/syntax/13_record.md deleted file mode 100644 index aa8d34c2..00000000 --- a/doc/zh_TW/syntax/13_record.md +++ /dev/null @@ -1,198 +0,0 @@ -# 記錄 - -記錄是一個集合,它具有通過鍵訪問的 Dict 和在編譯時檢查訪問的元組的性質。如果你使用過 JavaScript,請將其視為對象文字符號(更高級)。 - - -```erg -john = {.name = "John"; .age = 21} - -assert john.name == "John" -assert john.age == 21 -assert john in {.name = Str; .age = Nat} -john["name"] # Error: john is not subscribable -``` - -和部分稱為屬性,部分稱為屬性值。 - -它與 JavaScript 對象文字的區別在於不能以字符串形式訪問。也就是說,屬性不僅僅是字符串。這可能是因為它在編譯時決定對值的訪問,也可能是因為字典和記錄是不同的。也就是說,是 Dict,是記錄。那麼,詞典和記錄該如何區分使用呢?通常建議使用記錄。記錄具有以下優點:編譯時檢查元素是否存在,並且可以指定。可見性規範相當於 public/private 規範,例如在 Java 語言中。有關詳細信息,請參見。 - - -```erg -a = {x = 1; .y = x + 1} -a.x # AttributeError: x is private -# Hint: declare as `.x` -assert a.y == 2 -``` - -對於熟悉 JavaScript 的人來說,上面的例子可能很奇怪,但如果簡單地聲明,則外部無法訪問,如果加上,則可以通過訪問。 - -還可以顯式指定屬性的類型。 - - -```erg -anonymous = { - .name: Option! Str = !None - .age = 20 -} -anonymous.name.set! "John" -``` - -記錄也可以有方法。 - - -```erg -o = { - .i = !0 - .inc! ref! self = self.i.inc!() -} - -assert o.i == 0 -o.inc!() -assert o.i == 1 -``` - -關於記錄有一個值得注意的語法。當記錄的所有屬性值都是類(結構類型不允許)時,記錄本身將其屬性視為請求屬性。這種類型稱為記錄類型。有關詳細信息,請參閱記錄部分。 - - -```erg -# レコード -john = {.name = "John"} -# レコード型 -john: {.name = Str} -Named = {.name = Str} -john: Named - -greet! n: Named = - print! "Hello, I am {n.name}" -greet! john # "Hello, I am John" - -print! Named.name # Str -``` - -## 分解記錄 - -可以按如下方式分解記錄。 - - -```erg -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})" -``` - -此外,如果記錄具有與屬性同名的變量,則可以將或省略為,將省略為。但是,如果只有一個屬性,則必須使用將其與集合區分開來。 - - -```erg -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 -``` - -此語法可用於分解記錄並將其賦給變量。 - - -```erg -# same as `{x = x; y = y} = xy` -{x; y} = xy -assert x == 1 -assert y == 2 -# same as `{.a = a; .b = b} = ab` -{a; b} = ab -assert a == 1 -assert b == 2 -``` - -## 空記錄 - -空記錄由表示。與 Unit 一樣,空記錄也是其類本身。 - - -```erg -empty_record = {=} -empty_record: {=} -# Object: Type = {=} -empty_record: Object -empty_record: Structural {=} -{x = 3; y = 5}: Structural {=} -``` - -空記錄不同於空 Dict或空集。尤其要注意它與的含義正好相反(在 Python 中,是一個空字典,而在 Erg 中,它是)。作為枚舉類型,是空類型,不包含任何元素。類型是對其進行的類化。相反,記錄類中的沒有請求實例屬性,因此所有對像都是它的元素。是此別名。 (修補程序)具有非常基本的提供方法,如。 - - -```erg -AnyPatch = Patch Structural {=} - .__sizeof__ self = ... - .clone self = ... - ... -Never = Class {} -``` - -請注意,沒有其他類型和類在結構上與,類型等效,如果用戶定義類型時在右邊指定,則會出錯。這可以防止將轉換為的錯誤。此外,如果定義組合結果為的類型(例如),則會發出警告,將其簡單地定義為。 - -## 即時塊 - -Erg 還有一個語法叫即時塊,它只是返回最後評估的值。不能保留屬性。 - - -```erg -x = - x = 1 - y = x + 1 - y ** 3 -assert x == 8 - -y = - .x = 1 # SyntaxError: cannot define an attribute in an entity block -``` - -## 數據類 - -如果嘗試單獨實現方法,則必須直接在實例中定義原始記錄(由記錄文本生成的記錄)。這效率很低,而且隨著屬性數量的增加,錯誤顯示等很難看到,也很難使用。 - - -```erg -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 -# TypeError: + is not implemented for {name = Str; age = Int; .greet! = Ref(Self).() => None; inc_age! = Ref!(Self).() => None}, Int -``` - -因此,在這種情況下,我們將繼承記錄類。此類類稱為數據類。我們將在部分詳細討論這一點。 - - -```erg -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 -# TypeError: + is not implemented for Person, Int -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/14_set.md b/doc/zh_TW/syntax/14_set.md deleted file mode 100644 index 66a36c46..00000000 --- a/doc/zh_TW/syntax/14_set.md +++ /dev/null @@ -1,50 +0,0 @@ -# 集 - -集代表一個集合,在數據結構上是重複的、沒有順序的數組。 - - -```erg -assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3} -assert {1, 2} == {1, 1, 2} # 重複は自動で削除される -assert {1, 2} == {2, 1} -``` - -集合可以進行集合運算。 - - -```erg -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} -``` - -佈景是一個等質的收藏。要使不同類中的對象共存,必須使它們相等。 - - -```erg -s: {Int or Str} = {"a", 1, "b", -1} -``` - -## 設置為類型 - -套也可以當作一種類型。這些類型稱為。 - - -```erg -i: {1, 2, 3} = 1 -assert i in {1, 2, 3} -``` - -集的元素將變為類型元素。需要注意的是,佈景本身是不一樣的。 - - -```erg -mut_set = {1, 2, 3}.into {Int; !3} -mut_set.insert!(4) -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/15_type.md b/doc/zh_TW/syntax/15_type.md deleted file mode 100644 index 2f08bdda..00000000 --- a/doc/zh_TW/syntax/15_type.md +++ /dev/null @@ -1,7 +0,0 @@ -# 類型 - -類型在 Erg 中是一個非常重要的功能,因此我們提供了。請看那邊。 - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/16_iterator.md b/doc/zh_TW/syntax/16_iterator.md deleted file mode 100644 index d5c9fe04..00000000 --- a/doc/zh_TW/syntax/16_iterator.md +++ /dev/null @@ -1,91 +0,0 @@ -# 迭 - -迭代器是用於檢索容器元素的對象。 - - -```erg -for! 0..9, i => - print! i -``` - -此代碼輸出 0 到 9 之間的數字。將每個數字(=Int 對象)賦給,並執行以下操作(=):這種重複執行稱為。 - -現在,我們來看一下過程的類型簽名。 - - -```erg -for!: |T: Type, I <: Iterable T| (I, T => None) => None -``` - -第一個參數似乎接受類型為的對象。 - -是具有屬性和方法的請求方法類型。 - - -```erg -Iterable T = Trait { - .Iterator = {Iterator} - .iter = Self(T).() -> Self.Iterator T -} -``` - -屬性類型是所謂的設置卡印(卡印在中描述)。 - - -```erg -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() # -``` - -和都是實現的類,它們的存在只是為了賦予小版本功能。這種設計模式稱為伴隨類。而修補程序是小版本功能的核心。 只需要一個方法,實際上提供了幾十個方法。 只需實現方法即可使用的實現方法。由於這種便利性,標準庫實現了許多迭代器。 - - -```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 -``` - -提供一個接口的類型,如,在本例中為)是靜態調度,但可以統一處理,這種類型稱為伴隨類適配器。 - ---- - -1這個模式似乎沒有統一的名字,但在 Rust 中被稱為,並以此為參照命名。 - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/17_mutability.md b/doc/zh_TW/syntax/17_mutability.md deleted file mode 100644 index b62f159b..00000000 --- a/doc/zh_TW/syntax/17_mutability.md +++ /dev/null @@ -1,92 +0,0 @@ -# Mutability - -正如我們已經看到的,Erg 中的所有變量都是不變的。但是 Erg 的對像有一個可變性的概念。以下代碼為示例。 - - -```erg -a = [1, 2, 3] -a = a + [4, 5, 6] -print! a # [1, 2, 3, 4, 5, 6] -``` - -上面的代碼實際上是 Erg 無法實現的。因為不能再賦值。這個代碼可以運行。 - - -```erg -b = ![1, 2, 3] -b.concat! [4, 5, 6] -print! b # [1, 2, 3, 4, 5, 6] -``` - -雖然最終的結果看起來是一樣的,但其含義卻大相徑庭。是表示數組的變量,但第一行和第二行所指向的對像不同。只是名稱相同,但內容不同。 - - -```erg -a = [1, 2, 3] -print! id! a # 0x000002A798DFE940 -_a = a + [4, 5, 6] -print! id! _a # 0x000002A798DFE980 -``` - -過程返回對象所在內存中的地址。 - -是的“動態”數組。對象的內容會發生變化,但變量指向相同的內容。 - - -```erg -b = [1,2,3].into [Int; !3] -print! id! b # 0x000002A798DFE220 -b.concat! [4, 5, 6] -print! id! b # 0x000002A798DFE220 -``` - - -```erg -i = !0 -if! True: - do! i.inc!() # or i.add!(1) - do pass -print! i # 1 -``` - -是一個特殊的運算符,稱為。返回變量的不可變對象。帶有的對象的行為可以自定義。 - - -```erg -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 -``` - -## 常數 - -與變量不同,常量在所有作用域中指向相同的內容。常量由運算符聲明。 - - -```erg -PI = 3.141592653589 -match! x: - PI => print! "this is pi" -``` - -常量在全局以下的所有範圍內都是相同的,不能被覆蓋。因此,不能通過進行重新定義。此限制允許你在模式匹配中使用它。在模式匹配中使用是因為它們是常數。此外,常量始終指向不變對象。類型(如)不能是常量。所有內置類型都是常量,因為它們應該在編譯時確定。也可以生成非常量類型,但不能用於指定類型,只能作為記錄使用。反過來說,類型也可以說是編譯時內容已確定的記錄。 - -## Variable, Name, Identifier, Symbol - -現在,我們來整理一下 Erg 中有關變量的術語。 - -“變量”(Variable)是一種為對象命名(Name)並允許其重複使用的機制(或指該名稱)。標識符(Identifier)是用於指定變量的語法元素。符號是表示名稱的語法元素和標記。 - -只有不是符號的字符才是符號,符號是運算符,但不是符號。例如,是標識符和符號。 也是一個標識符,但它不是一個符號。 是符號。即使沒有與任何對象關聯,仍然是 Symbol 和 Identifier,但不是 Variable。形式為的標識符稱為字段存取器。此外,形式的標識符稱為下標存取器。 - -變量和標識符之間的區別,如果說 Erg 語法理論意義上的變量,那麼這兩個變量實際上是相同的。變量和標識符不等效的語言包括 C 語言。在 C 語言中,類型或函數不能賦給變量。 int,main 是標識符,但不是變量(嚴格來說,它可能是可賦值的,但有限制)。但在 Erg 中,“一切都是物體”。函數和類型,甚至運算符都可以賦給變量。 - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/18_ownership.md b/doc/zh_TW/syntax/18_ownership.md deleted file mode 100644 index 593217cc..00000000 --- a/doc/zh_TW/syntax/18_ownership.md +++ /dev/null @@ -1,103 +0,0 @@ -# 所有權制度 - -由於 Erg 是以 Python 為主機語言的語言,因此管理內存的方式依賴於 Python 的處理系統。然而,從語義上講,Erg 的內存管理與 Python 的內存管理不同。顯著的區別體現在所有權制度和禁止循環引用。 - -## 所有權 - -Erg 有一個所有權系統受到Rust的影響。 Rust 的所有權系統通常被稱為晦澀難懂,但 Erg 的所有權系統被簡化為直觀。 Erg 擁有的所有權,一旦失去所有權,就無法查看該對象。 - - -```erg -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 # error: v was moved -print! w # [1, 2, 3, 4] -``` - -例如,在將對像傳遞到子例程時會發生所有權移動。如果你希望在傳遞後仍擁有所有權,則必須複製(cloning)、凍結(freeze)或借用(borrowing)。但是,如下文所述,可以藉用的場合有限。 - -## 複製 - -複製對象並轉移其所有權。通過將方法應用於實際參數來完成此操作。複製的對象與原始對象完全相同,但它們彼此獨立,不受更改的影響。 - -複製相當於 Python 的深度副本,因為要重新創建整個相同的對象,所以與凍結和借用相比,通常計算和內存成本更高。需要復制對象的子例程稱為使用參數子例程。 - - -```erg -capitalize s: Str! = - s.capitalize!() - s - -s1 = !"hello" -s2 = capitalize s1.clone() -log s2, s1 # !"HELLO hello" -``` - -## 凍結 - -利用可變對象可以從多個位置引用,將可變對象轉換為不變對象。這叫凍結。凍結可用於創建可變陣列的迭代器。變量數組無法直接創建迭代器,因此將其轉換為不變數組。如果不想破壞數組,請使用 [方法] (./type/mut.md)等。 - - -```erg -# イテレータが出す値の合計を計算する -sum|T <: Add + HasUnit| i: Iterator T = ... - -x = [1, 2, 3].into [Int; !3] -x.push!(4) -i = x.iter() # TypeError: [Int; !4] has no method `iter` -y = x.freeze() -i = y.iter() -assert sum(i) == 10 -y # この後もyは觸れられる -``` - -## 借用 - -借用比複製和凍結成本更低。在以下簡單情況下,可以藉用。 - - -```erg -peek_str ref(s: Str!) = - log s - -s = !"hello" -peek_str s -``` - -對於原始對象,借用的值稱為。你可以將引用“轉借”給另一個子例程,但不能消費,因為它只是藉用。 - - -```erg -steal_str ref(s: Str!) = - # log関數は引數を借用するだけなので、又貸しできる - log s - # discard関數は引數を消費するので、エラー - discard s # OwnershipError: cannot consume a borrowed value - # hint: use `clone` method -``` - - -```erg -steal_str ref(s: Str!) = - # これもダメ(=は右辺を消費する) - x = s # OwnershipError: cannot consume a borrowed value - x -``` - -Erg 引用比 Rust 具有更強的約束。引用是第一級語言對象,但不能顯式生成,只能通過/指定實際參數的傳遞方式。這意味著你不能將引用合併到數組中,也不能創建以引用為屬性的類。 - -儘管如此,這種限制在沒有參照的語言中本來就是理所當然的規範,並沒有那麼不方便。 - -## 循環引用 - -Erg 的設計目的是防止意外發生內存洩漏,當內存檢查器檢測到循環引用時,它會發出錯誤消息。在大多數情況下,可以使用弱引用來解決此錯誤。但是,由於這無法生成具有循環結構的對象(如循環圖),因此我們計劃實現一個 API,該 API 可以生成循環引用作為 unsafe 操作。 - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/19_visibility.md b/doc/zh_TW/syntax/19_visibility.md deleted file mode 100644 index 1d85abb1..00000000 --- a/doc/zh_TW/syntax/19_visibility.md +++ /dev/null @@ -1,199 +0,0 @@ -# 可見性(Visibility) - -Erg 中的變量具有的概念。我們看到的所有變量都稱為。這是一個外界不可見的變量。例如,在模塊中定義的私有變量不能被另一個模塊引用。 - - -```erg -# foo.er -x = "this is an invisible variable" -``` - - -```erg -# bar.er -foo = import "foo" -foo.x # AttributeError: Module 'foo' has no attribute 'x' ('x' is private) -``` - -與此相對,也有,這是可從外部參照的。公共變量定義為。 - - -```erg -# foo.er -.x = "this is a visible variable" -``` - - -```erg -# bar.er -foo = import "foo" -assert foo.x == "this is a visible variable" -``` - -你不需要為私有變量指定任何內容,但也可以指定或(例如,)以表明它是私有的。模塊也可以是。 - - -```erg -::x = "this is a invisible variable" -assert ::x == x -assert self::x == ::x -assert module::x == ::x -``` - -在簡單的順序執行上下文中,私有變量幾乎等同於局部變量。從內部範圍可以參照。 - - -```erg -::x = "this is a private variable" -y = - x + 1 # 正確にはmodule::x -``` - -你可以使用來區分作用域中的同名變量。在左側指定要引用的變量的範圍。對於頂級,指定。如果未指定,則引用最內部的變量,就像在正常情況下一樣。 - - -```erg -::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 -``` - -對於未命名子程序的範圍,指定其範圍。 - - -```erg -x = 0 -f = x -> - log module::x, self::x -f 1 # 0 1 -``` - -還負責訪問專用實例屬性。 - - -```erg -x = 0 -C = Class {x = Int} -C. - # トップレベルのxが參照される(module::xにするようwarningが出る) - f1 self = x - # インスタンス屬性のxが參照される - f2 self = self::x -``` - -## 外部模塊中的可見性 - -在模塊中定義的類實際上也可以從外部模塊定義方法。 - - -```erg -# foo.er -.Foo = Class() -``` - - -```erg -# bar.er -{Foo; ...} = import "foo" - -Foo:: - private self = pass -Foo. - public self = self::private() - -.f() = - foo = Foo.new() - foo.public() - foo::private() # AttributeError -``` - -但是,這兩種方法只能在模塊中使用。只有在定義模塊中,類的方法才能引用外部定義的私有方法。公開方法在類之外公開,但不在模塊之外公開。 - - -```erg -# baz.er -{Foo; ...} = import "foo" - -foo = Foo.new() -foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defined in module 'bar') -``` - -此外,不能為要 Re-export 的類型定義方法。這是為了防止導入模塊導致方法丟失或找到的混淆。 - - -```erg -# bar.er -{.Foo; ...} = import "foo" - -.Foo:: - private self = pass # Error -.Foo. - public self = self::private() # Error -``` - -如果要這樣做,請定義。 - - -```erg -# bar.er -{Foo; ...} = import "foo" - -FooImpl = Patch Foo -FooImpl :=: - private self = pass -FooImpl. - public self = self::private() -``` - - -```erg -# baz.er -{Foo; ...} = import "foo" -{FooImpl; ...} = import "bar" - -foo = Foo.new() -foo.public() -``` - -## 受限制的公共變量 - -變量的可見性並不只有完全的公開或非公開。也可以有限制地發布。 - - -```erg -# foo.er -.record = { - .a = { - .(.record)x = 0 - .(module)y = 0 - .z = 0 - } - _ = .a.x # OK - _ = .a.y # OK - _ = .a.z # OK -} - -_ = .record.a.x # VisibilityError -_ = .record.a.y # OK -_ = .record.a.z # OK -``` - - -```erg -foo = import "foo" -_ = foo.record.a.x # VisibilityError -_ = foo.record.a.y # VisibilityError -_ = foo.record.a.z # OK -``` - -

- Previous | Next -

\ 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 deleted file mode 100644 index 5d861f95..00000000 --- a/doc/zh_TW/syntax/20_naming_rule.md +++ /dev/null @@ -1,52 +0,0 @@ -# 命名規則 - -如果要將變量用作常量表達式,則必須以大寫字母開頭。兩個以上的字符可以是小寫的。 - - -```erg -i: Option Type = Int -match i: - t: Type -> log "type" - None -> log "None" -``` - -具有副作用的對象始終以結尾。過程和過程方法,以及變量類型。但是,類型本身不是可變類型。 - - -```erg -# Callable == Func or Proc -c: Callable = print! -match c: - p! -> log "proc" #`:Proc` 可以省略,因為它是不言自明的 - f -> log "func" -``` - -如果你想要將屬性公開到外部,請首先使用進行定義。如果未在開始時添加,則不公開。不能在同一範圍內共存,以避免混淆。 - - -```erg -o = {x = 1; .x = 2} # SyntaxError: private and public variables with the same name cannot coexist -``` - -## 文字標識符(Literal Identifiers) - -可以通過將字符串括在單引號(‘’)中來避免上述規則。也就是說,過程對像也可以賦值,而不使用。但是,即使值是常量表達式,也不會將其視為常量。這種用單引號括起來的字符串標識符稱為文字標識符。它用於調用其他語言的 API(FFI),如 Python。 - - -```erg -bar! = pyimport("foo").'bar' -``` - -如果標識符對 Erg 也有效,則不需要用‘’括起來。 - -此外,由於文字標識符可以包含符號和空格,因此通常不能用作標識符的字符串可以用作標識符。 - - -```erg -'∂/∂t' y -'test 1: pass x to y'() -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/21_lambda.md b/doc/zh_TW/syntax/21_lambda.md deleted file mode 100644 index 2ca47413..00000000 --- a/doc/zh_TW/syntax/21_lambda.md +++ /dev/null @@ -1,102 +0,0 @@ -# 匿名函數(anonymous function) - -匿名函數是一種語法,用於在不命名的情況下生成函數對象。 - - -```erg -# `->`は無名関數演算子 -# 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 -``` - -如果只有一個參數,則可以省略。 - - -```erg -assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4] -assert ((i, j) -> [i, j])(1, 2) == [1, 2] -``` - -在下面的情況下,它是,而不是在左邊只有一個參數。將多個參數視為單個元組。 - - -```erg -for 0..9, i: Int -> - ... -``` - -在未命名函數中,由於空格而存在語法差異。 - - -```erg -# この場合は`T(() -> Int)`と解釈される -i: T () -> Int -# この場合は(U()) -> Intと解釈される -k: U() -> Int -``` - -不帶參數也可以使用匿名函數。 - - -```erg -# `=>`は無名プロシージャ演算子 -p! = () => print! "`p!` was called" -# `() ->`, `() =>`には`do`, `do!`という糖衣構文がある -# p! = do! print! "`p!` was called" -p!() # `p!` was called -``` - -無參數函數可用於延遲初始化。 - - -```erg -time = import "time" -date = import "datetime" -now = if! True: - do!: - time.sleep! 1000 - date.now!() - do date.new("1970", "1", "1", "00", "00") -``` - -還可以進行打字和模式匹配。因此,函數幾乎是通過無名函數的力量來實現的。函數參數中的無名函數將從上到下依次嘗試。所以,上面的需要描述特殊情況,越往下越需要描述一般情況。如果順序錯誤(盡可能),編譯器將發出警告。 - - -```erg -n = (Complex or Ratio or Int).sample!() -i = match n: - PI -> PI # 定數PIに等しい場合 - (i: 1..10) -> i # 1~10のIntの場合 - (i: Int) -> i # Intの場合 - (c: Complex) -> c.real() # Complexの場合。 Int < Complexだが、フォールバックできる - _ -> panic "cannot convert to Int" # 以上のいずれにも該當しない場合。 matchは全パターンを網羅していなくてはならない -``` - -錯誤處理也通常使用或。 - - -```erg -res: ParseResult Int -match res: - i: Int -> i - err: Error -> panic err.msg - -res2: Result Int, Error -match res2: - ok: Not Error -> log Typeof ok - err: Error -> panic err.msg -``` - -## 無名多相關數 - - -```erg -# same as id|T| x: T = x -id = |T| x: T -> x -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/22_subroutine.md b/doc/zh_TW/syntax/22_subroutine.md deleted file mode 100644 index 1ab1aa7c..00000000 --- a/doc/zh_TW/syntax/22_subroutine.md +++ /dev/null @@ -1,65 +0,0 @@ -# Subroutine signatures - -## Func - - -```erg -some_func(x: T, y: U) -> V -some_func: (T, U) -> V -``` - -## Proc - - -```erg -some_proc!(x: T, y: U) => V -some_proc!: (T, U) => V -``` - -## Func Method - -不能從外部指定方法類型。 - - -```erg -.some_method(self, x: T, y: U) => () -# Self.(T, U) => ()はselfの所有権を奪う -.some_method: Ref(Self).(T, U) => () -``` - -## Proc Method (dependent) - -下面,假定類型採用類型參數。如果從外部指定,請使用類型變量。 - - -```erg -T!: Nat -> Type -# ~>は適用前後の型引數の狀態を示す(このときselfは可変參照でなくてはならない) -T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => () -``` - -請注意,的類型為。類型參數轉換()不適用於沒有的方法,即應用後將被剝奪所有權。 - -所有權被剝奪的情況如下。 - - -```erg -# Nを使わないなら_で省略可 -# .some_method!: |N, X: Nat| T!(N).({X}) => T!(N+X) -.some_method!|N, X: Nat|(self(N), X: Nat) => T!(N+X) -``` - -## Operator - -用括起來,可以像定義常規函數一樣定義函數。可以將等中置字母運算符括起來,將其定義為中置運算符。 - - -```erg -and(x, y, z) = x and y and z -`_+_`(x: Foo, y: Foo) = x.a + y.a -`-_`(x: Foo) = Foo.new(-x.a) -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/23_closure.md b/doc/zh_TW/syntax/23_closure.md deleted file mode 100644 index 375eb459..00000000 --- a/doc/zh_TW/syntax/23_closure.md +++ /dev/null @@ -1,99 +0,0 @@ -# 封閉 - -Erg 子例程具有一個名為“閉包”的功能,用於捕獲外部變量。 - - -```erg -outer = 1 -f x = outer + x -assert f(1) == 2 -``` - -可以捕捉可變對象,也可以捕捉不變對象。 - - -```erg -sum = !0 -for! 1..10, i => - sum.add! i -assert sum == 45 - -p! x = - sum.add! x -p!(1) -assert sum == 46 -``` - -但需要注意的是,函數無法捕獲可變對象。如果可以在函數中引用可變對象,則可以編寫如下所示的代碼。 - - -```erg -# !!! 這個代碼實際上給出了一個錯誤!!! -i = !0 -f x = i + x -assert f 1 == 1 -i.add! 1 -assert f 1 == 2 -``` - -函數應該為相同的參數返回相同的值,但假設已被破壞。請注意,是在調用時首次計算的。 - -如果需要函數定義時可變對象的內容,則調用。 - - -```erg -i = !0 -immut_i = i.clone().freeze() -f x = immut_i + x -assert f 1 == 1 -i.add! 1 -assert f 1 == 1 -``` - -## 避免可變狀態,函數編程 - - -```erg -# 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 建議使用更簡單的寫法。使用局部化使用函數的狀態的樣式,而不是使用子例程和可變對象來維護狀態。這稱為函數型編程。 - - -```erg -# Functional style -sum = (1..10).sum() -assert sum == 45 -``` - -上面的代碼與剛才的結果完全相同,但我們可以看到它要簡單得多。 - -除了求和之外,還可以使用函數執行更多操作。 是迭代器方法,它為每個小版本執行參數。存儲結果的計數器的初始值由指定,然後存儲在中。 - - -```erg -# start with 0, result will -sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i) -assert sum == 45 -``` - -Erg 的設計是為了使用不變的對象進行編程,從而提供自然簡潔的描述。 - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/24_module.md b/doc/zh_TW/syntax/24_module.md deleted file mode 100644 index 428dd179..00000000 --- a/doc/zh_TW/syntax/24_module.md +++ /dev/null @@ -1,47 +0,0 @@ -# 模塊 - -Erg 可以將文件本身視為一條記錄。我們稱之為模塊。 - - -```erg: foo.er -# foo.er -.i = 1 -``` - - -```erg -# 定義 foo 模塊和定義這條記錄幾乎一樣 -foo = {.i = 1} -``` - - -```erg: bar.er -# bar.er -foo = import "foo" -print! foo # -assert foo.i == 1 -``` - -模塊化也是一種記錄類型,因此可以進行分解賦值。 - - -```erg -{sin; cos; ...} = import "math" -``` - -## 模塊可見性 - - -```console -└─┬ ./src - ├─ lib.er - ├─ foo.er - ├─ bar.er - └─┬ bar - ├─ baz.er - └─ qux.er -``` - -

- Previous | Next -

\ 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 deleted file mode 100644 index eb944a02..00000000 --- a/doc/zh_TW/syntax/25_object_system.md +++ /dev/null @@ -1,77 +0,0 @@ -# 對象 - -可以分配給變量的所有數據。類具有以下屬性。 - -* :返回對象的(非富)字符串表示法 -* :返回對象的大小(包括堆保留量) -* :返回對象屬性的列表 -* :返回對象的散列值 -* :檢索並返回對象的屬性 -* :生成並返回對象的克隆(在內存中有獨立實體) -* :返回對象的副本(在內存中指向相同的對象) - -## 記錄 - -以記錄文字()生成的對象。此對象具有基本方法,如。 - - -```erg -obj = {.x = 1} -assert obj.x == 1 - -obj2 = {...x; .y = 2} -assert obj2.x == 1 and obj2.y == 2 -``` - -## 屬性 - -與對象相關聯的對象。特別是將其自身()作為隱式第一參數的子程序屬性稱為方法(method)。 - - -```erg -# private_attrには`.`がないことに注意 -record = {.public_attr = j; private_attr = 2; .method = self -> self.i + 1} -record.public_attr == 2 -record.private_attr # AttributeError: private_attr is private -assert record.method() == 3 -``` - -## 元素 - -屬於特定類型的對象(其中.g.是類型的元素)。所有對像都至少是類型的元素。有時稱為實例(Instance),特別是類的元素。 - -## 子程序 - -表示作為函數或過程實例的對象(包括方法)。表示子例程的類是。通常,實現的對象稱為(可調用對象)。 - -## Callable(可調用對象) - -實現的對象。也是的超類。 - -## 類型 - -定義請求屬性並使對象公用的對象。 “多相類型”(Polymorphic Type)和“單相類型”(Monomorphic Type)。典型的單相類型有,等,多相類型有等。此外,定義用於更改對象狀態的方法的類型稱為“可變類型”(Mutable type),並且必須將變量屬性標記為(.g.動態數組:)。 - -## 類 - -具有和方法的類型。實現基於類的面向對象。 - -## 函數(函數,映射) - -一個子例程,它對外部變量(靜態變量除外)具有 read 權限,但對外部變量沒有讀/寫權限。即不會對外界產生副作用。 Erg 函數(Function)的定義與 Python 的定義不同,因為它不允許產生副作用。 - -## 過程 - -它對外部變量具有讀取和權限,對靜態變量具有讀/寫權限,並且允許使用所有子例程。會對外界產生副作用。 - -## 方法 - -將隱式作為第一個參數的子程序。它不同於簡單的函數/過程。 - -## 實體 - -非子程序和類型的對象。單相實體(如和)也稱為值對象,多相實體()也稱為容器對象。 - -

- Previous | Next -

\ 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 deleted file mode 100644 index 9924c37d..00000000 --- a/doc/zh_TW/syntax/26_pattern_matching.md +++ /dev/null @@ -1,203 +0,0 @@ -# 模式匹配,可辯駁性 - -## Erg 中可用的模式 - -### 變量模式 - - -```erg -# basic assignment -i = 1 -# with type -i: Int = 1 -# with anonymous type -i: {1, 2, 3} = 2 - -# function -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] -``` - -### 文字模式 - - -```erg -# もし`i`がコンパイル時に1と判斷できない場合は、TypeErrorが発生する。 -# `_: {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 -``` - -### 常數模式 - - -```erg -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" -``` - -### 篩子模式 - - -```erg -# この2つは同じ -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 -``` - -### 銷毀(通配符)模式 - - -```erg -_ = 1 -_: Int = 1 -zero _ = 0 -right(_, r) = r -``` - -### 可變長度模式 - -與下面介紹的元組/數組/記錄模式結合使用。 - - -```erg -[i, ...j] = [1, 2, 3, 4] -assert j == [2, 3, 4] -first|T|(fst: T, ...rest: T) = fst -assert first(1, 2, 3) == 1 -``` - -### 元組圖案 - - -```erg -(i, j) = (1, 2) -((k, l), _) = ((1, 2), (3, 4)) -# ネストしていないなら()を省略可能(1, 2は(1, 2)として扱われる) -m, n = 1, 2 - -f(x, y) = ... -``` - -### 數組模式 - - -```erg -[i, j] = [1, 2] -[[k, l], _] = [[1, 2], [3, 4]] - -length [] = 0 -length [_, ...rest] = 1 + length rest -``` - -#### 記錄模式 - - -```erg -record = {i = 1; j = 2; k = 3} -{j; ...} = record # i, k will be freed - -{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} = ... -``` - -### 數據類模式 - - -```erg -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 - _ -> ... -``` - -### 枚舉模式 - -※實際上是單純的列舉型 - - -```erg -match x: - i: {1, 2} -> "one or two: {i}" - _ -> "other" -``` - -### 範圍模式 - -※實際上是單純的區間型 - - -```erg -# 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 -> ... -``` - -### 不是模式的東西,不能被模式化的東西 - -模式可以是唯一的。在這一點上,模式匹配不同於常規條件分支。 - -條件指定不唯一。例如,如果確定數字是否為偶數,則是正統的,但也可以寫為。不唯一的格式不能明確表示是否正常工作,也不能明確表示是否等同於其他條件。 - -#### 設置 - -沒有佈景圖案。這是因為集合無法唯一地提取元素。可以用迭代器取出,但不保證順序。 - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/27_comprehension.md b/doc/zh_TW/syntax/27_comprehension.md deleted file mode 100644 index 6c2b720b..00000000 --- a/doc/zh_TW/syntax/27_comprehension.md +++ /dev/null @@ -1,65 +0,0 @@ -# Comprehension - -你可以用創建數組,用創建集,用創建 Dict。 - -用分隔的節中,最初的部分稱為佈局節(配置節),第 2 部分稱為綁定節(綁定節),第 3 部分稱為保護節(條件節)。保護子句是可選的,但不能省略綁定子句,並且保護子句不能位於綁定子句之前。 - -內包表示法示例 - - -```erg -# 佈局子句是 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)] -``` - - -```erg -# 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)] -``` - -## 篩子型 - -與內涵表記相似的還有篩子型。篩子類型是以的形式創建的類型(枚舉類型)。對於篩子類型,名稱只能是一個,不能指定佈局(但可以處理多個值,例如元組類型),而 Predicate 只能是編譯時計算的常量表達式。 - - -```erg -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} -``` - -

- Previous | Next -

\ 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 deleted file mode 100644 index 5076a9b8..00000000 --- a/doc/zh_TW/syntax/28_spread_syntax.md +++ /dev/null @@ -1,45 +0,0 @@ -# 展開分配 - -在分解賦值中,如果在變量之前放置,則所有剩餘元素都可以擴展到該變量。這稱為部署賦值。 - - -```erg -[x, ...y] = [1, 2, 3] -assert x == 1 -assert y == [2, 3] -x, ...y = (1, 2, 3) -assert x == 1 -assert y == (2, 3) -``` - -## 提取分配 - -如果後沒有寫任何內容,則忽略其餘元素並進行賦值。這種類型的展開賦值特別稱為抽取賦值。提取賦值是一種有用的語法,用於將模塊或記錄中的特定屬性本地化。 - - -```erg -{sin; cos; tan; ..} = import "math" -``` - -然後,可以在本地使用。 - -記錄也可以這樣做。 - - -```erg -record = {x = 1; y = 2} -{x; y; ...} = record -``` - -如果要全部展開,請使用。這就是 OCaml 等所說的。 - - -```erg -record = {x = 1; y = 2} -{*} = record -assert x == 1 and y == 2 -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/29_decorator.md b/doc/zh_TW/syntax/29_decorator.md deleted file mode 100644 index 7d39975f..00000000 --- a/doc/zh_TW/syntax/29_decorator.md +++ /dev/null @@ -1,124 +0,0 @@ -# 裝飾器(修飾符) - -裝飾器用於將特定的狀態和行為添加到類型和函數中,或將其顯式。裝飾師的語法如下。 - - -```erg -@deco -X = ... -``` - -裝飾器可以有多個,除非衝突。 - -裝飾器不是一個特殊的對象,它的實體只是一個參數函數。裝飾器等效於以下偽代碼。 - - -```erg -X = ... -X = deco(X) -``` - -因為 Erg 不能重新賦值變量,所以上面的代碼不能通過。對於簡單的變量,這與相同,但對於即時塊和子程序,這是不可能的,因此需要一個裝飾器。 - - -```erg -@deco -f x = - y = ... - x + y - -# コードが橫長になるのを防ぐこともできる -@LongNameDeco1 -@LongNameDeco2 -C = Class ... -``` - -下面介紹一些頻出的嵌入式裝飾器。 - -## Inheritable - -指示所定義的類型是可繼承類。如果將參數指定為,則外部模塊類可以繼承這些參數。默認為,不能從外部繼承。 - -## Final - -使方法不可覆蓋。將類附加到類後,它將成為不可繼承類,但這沒有意義,因為這是缺省類。 - -## Override - -用於覆蓋屬性。缺省情況下,Erg 會在嘗試定義與基類相同的屬性時出錯。 - -## Impl - -指示要實現自變量的特寫。 - - -```erg -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::} -``` - -## Attach - -指定默認情況下隨托盤一起提供的附件曲面片。這樣,你就可以重現與 Rust 的trait相同的行為。 - - -```erg -# 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 -``` - -這將在從其他模塊導入托盤時自動應用附件修補程序。 - - -```erg -# 本來IntIsBinAdd, OddIsBinAddも同時にインポートする必要があるが、アタッチメントパッチなら省略可 -{BinAdd; ...} = import "foo" - -assert Int.AddO == Int -assert Odd.AddO == Even -``` - -在內部,我們只是使用trait的方法將其連接起來。如果發生衝突,可以使用trait的方法將其移除。 - - -```erg -@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 -``` - -## Deprecated - -表示變量規範已過時。 - -## Test - -指示測試子程序。測試子例程使用命令執行。 - -

- Previous | Next -

\ 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 deleted file mode 100644 index bf036273..00000000 --- a/doc/zh_TW/syntax/30_error_handling.md +++ /dev/null @@ -1,106 +0,0 @@ -# 錯誤處理系統 - -主要使用 Result 類型。在 Erg 中,如果丟棄 Error 類型的對象(不在頂層),則會發生錯誤。 - -## 異常,與 Python 的互操作 - -Erg 沒有異常機制(Exception)。導入 Python 函數時 - -* 返回類型 -* 類型(可能導致運行時錯誤) - -的兩個選項,在中默認為後者。如果要作為前者導入,請在中指定)。 - -## 異常和結果類型 - -類型表示可能出現錯誤的值。使用處理錯誤在某些方面優於異常機制。首先,從類型定義可以看出子程序可能會出錯,在實際使用時也一目了然。 - - -```python -# Python -try: - x = foo().bar() - y = baz() - qux() -except e: - print(e) -``` - -在上面的示例中,僅此代碼並不知道異常是從哪個函數調度的。即使追溯到函數定義,也很難確定該函數是否會出現異常。 - - -```erg -# Erg -try!: - do!: - x = foo!()?.bar() - y = baz!() - qux!()? - e => - print! e -``` - -相反,在本示例中,和可以生成錯誤。確切地說,也可能是類型,但在使用中值時,你必須執行此操作。 - -使用類型的好處遠不止這些。類型也是線程安全的。這意味著錯誤信息可以在並行執行期間(很容易)傳遞。 - -## Context - -/類型不會產生副作用,因此它不具有與異常不同的諸如發送位置之類的信息(上下文),但可以使用方法將信息添加到對象。 方法是使用對象本身來創建新的對象的方法。它是可鏈接的,可以有多個上下文。 - - -```erg -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 ... -``` - -注意,屬性(如)不是次要屬性,因此不是 context,不能覆蓋最初生成的屬性。 - -## 棧跟踪 - -類型由於其方便性,在其他語言中也被廣泛採用,但與異常機制相比,其缺點是錯誤的來源變得更難理解。因此,在 Erg 中,使對象具有屬性,模擬地再現了異常機制那樣的棧跟踪。 是調用對象的數組。每當 Error 對象(包括所致)時,它的調用子例程將加載到中。如果在環境中,它將死機並顯示回溯。 - - -```erg -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 還存在一個名為的機制來處理不可恢復的錯誤。不可恢復的錯誤可能是由外部因素引起的錯誤,例如軟/硬件故障,致命到無法繼續執行代碼的程度,或者是程序編寫者不想要的錯誤。如果發生這種情況,由於程序員的努力無法使其恢復正常系統,因此當場終止程序。這叫做“恐慌”。 - -使用函數執行死機。 - - -```erg -panic "something went wrong!" -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/31_pipeline.md b/doc/zh_TW/syntax/31_pipeline.md deleted file mode 100644 index ea8514d2..00000000 --- a/doc/zh_TW/syntax/31_pipeline.md +++ /dev/null @@ -1,32 +0,0 @@ -# 流水線運算符 - -按如下方式使用管線運算符。 - - -```erg -assert f(g(x)) == (x |> g |> f) -assert f(g(x, y)) == ((x, y) |> g |> f) -``` - -這意味著你可以將的順序更改為。也可以對方法使用管線運算符。對於方法,更改為。雖然它看起來只是增加了,但由於耦合強度較低,可能會減少的量。 - - -```erg -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) -# または -__evens = 1..100 \ - .iter() \ - .filter i -> i % 2 == 0 \ - .collect Array -``` - -

- Previous | Next -

\ 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 deleted file mode 100644 index 4750706e..00000000 --- a/doc/zh_TW/syntax/32_integration_with_Python.md +++ /dev/null @@ -1,87 +0,0 @@ -# 與 Python 合作 - -## 導出到 Python - -編譯 Erg 腳本將生成一個.pyc 文件,你可以將其作為一個模塊導入 Python。但是,在 Erg 端設置為私有的變量不能從 Python 訪問。 - - -```erg -# 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) # AttributeError: -``` - -## 從 Python 導入 - -默認情況下,從 Python 引入的所有對像都是類型。長此以往,我們也無法進行比較,所以我們需要進行類型的篩選。 - -## 標準庫類型 - -Python 標準庫中的所有 API 都由 Erg 開發團隊指定類型。 - - -```erg -time = pyimport "time" -time.sleep! 1 -``` - -## 指定用戶腳本類型 - -創建一個文件,為 Python 的模塊創建類型。 Python 端的 type hint 不是 100% 的保證,因此將被忽略。 - - -```python -# foo.py -X = ... -def bar(x): - ... -def baz(): - ... -``` - - -```erg -# foo.d.er -foo = pyimport "foo" -.X = declare foo.'X', Int -.bar = declare foo.'bar', Int -> Int -.baz! = declare foo.'baz', () => Int -``` - - -```erg -foo = pyimport "foo" -assert foo.bar(1) in Int -``` - -它通過在運行時執行類型檢查來保證類型安全性。函數的工作原理大致如下。 - - -```erg -declare|S: Subroutine| sub!: S, T = - # 実は、=>はブロックの副作用がなければ関數にキャストできる - x => - assert x in T.Input - y = sub!(x) - assert y in T.Output - y -``` - -這是一個運行時開銷,因此計劃在 Erg 類型系統上對 Python 腳本進行靜態類型分析。 - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/33_package_system.md b/doc/zh_TW/syntax/33_package_system.md deleted file mode 100644 index e7ecd528..00000000 --- a/doc/zh_TW/syntax/33_package_system.md +++ /dev/null @@ -1,83 +0,0 @@ -# 包裝系統 - -Erg 軟件包大致可以分為 app 軟件包(應用程序)和 lib 軟件包(庫)。 app 包的入口點是。執行中定義的函數。 lib 包的入口點是。導入包相當於導入。 - -軟件包有一個稱為模塊的子結構。在 Erg 中,模塊是 Erg 文件或由 Erg 文件組成的目錄。外部 Erg 文件/目錄可以作為模塊對象進行操作。 - -要將目錄識別為模塊,必須在目錄中放置文件。它類似於 Python 中的,但與不同,它位於目錄之外。 - -例如,請考慮以下目錄配置。 - - -```console -└─┬ ./src - ├─ app.er - ├─ foo.er - ├─ bar.er - └─┬ bar - ├─ baz.er - └─ qux.er -``` - -允許你導入模塊和模塊。由於存在文件,目錄可以識別為模塊。 模塊是由文件組成的模塊,模塊是由目錄組成的模塊。 模塊還具有模塊。該模塊僅是模塊的屬性,可通過訪問。 - - -```erg -# app.er -foo = import "foo" -bar = import "bar" -baz = bar.baz -# or `baz = import "bar/baz"` - -main args = - ... -``` - -請注意,用於訪問子模塊的分隔符為。這是因為文件名可能類似於。不建議使用這樣的文件名。因為在 Erg 中,的前綴是有意義的。例如,測試模塊。以結尾的文件是(白盒)測試模塊,在執行測試時執行以裝飾的子程序。 - - -```console -└─┬ ./src - ├─ app.er - ├─ foo.er - └─ foo.test.er -``` - - -```erg -# app.er -foo = import "foo" - -main args = - ... -``` - -此外,以結尾的文件是專用模塊,只能從同一目錄中的模塊訪問。 - - -```console -└─┬ - ├─ foo.er - ├─ bar.er - └─┬ bar - ├─ baz.private.er - └─ qux.er -``` - - -```erg -# foo.er -bar = import "bar" -bar.qux -bar.baz # AttributeError: module 'baz' is private -``` - - -```erg -# qux.er -baz = import "baz" -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/34_generator.md b/doc/zh_TW/syntax/34_generator.md deleted file mode 100644 index 567b8087..00000000 --- a/doc/zh_TW/syntax/34_generator.md +++ /dev/null @@ -1,37 +0,0 @@ -# 發電機 - -生成器是在塊中使用過程的特殊過程。 - - -```erg -g!() = - yield! 1 - yield! 2 - yield! 3 -``` - -是在子例程塊中定義的過程,它調用。它返回的返回值類似於,但它保存塊在該時刻的執行狀態,並在再次調用時繼續執行。生成器既是過程又是迭代器。 Python 生成器是生成迭代器的函數,而 Erg 直接迭代。過程本身通常不是可變對象(沒有),但生成器是可變的,因為它可以在每次執行時更改其內容。 - - -```erg -# Generator! < Proc -g!: Generator!((), Int) -assert g!() == 1 -assert g!() == 2 -assert g!() == 3 -``` - -可以按如下方式定義 Python 樣式生成器。 - - -```erg -make_g() = () => - yield! 1 - yield! 2 - yield! 3 -make_g: () => Generator!((), Int) -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/SUMMARY.md b/doc/zh_TW/syntax/SUMMARY.md deleted file mode 100644 index 774c354b..00000000 --- a/doc/zh_TW/syntax/SUMMARY.md +++ /dev/null @@ -1,69 +0,0 @@ -# Summary - -- [Basics](./00_basic.md) -- [Literal](./01_literal.md) -- [Name](02_name.md) -- [Declaration](./03_declaration.md) -- [Function](./04_function.md) -- [Builtin Functions](./05_builtin_funcs.md) -- [Operator](./06_operator.md) -- [Side Effect](./07_side_effect.md) -- [Procedure](./08_procedure.md) -- [Builtin Procedures](./09_builtin_procs.md) -- [Array](./10_array.md) -- [Tuple](./11_tuple.md) -- [Dict](./12_dict.md) -- [Record](./13_record.md) -- [Set](./14_set.md) -- [Type](./15_type.md) - - [Type System](./type/01_type_system.md) - - [Basics](./type/02_basic.md) - - [Trait](./type/03_trait.md) - - [Class](./type/04_class.md) - - [Inheritance](./type/05_inheritance.md) - - [NST vs SST](./type/06_nst_vs_sst.md) - - [Patch](./type/07_patch.md) - - [Value Type](./type/08_value.md) - - [Attributive Type](./type/09_attributive.md) - - [Interval Type](./type/10_interval.md) - - [Enum Type](./type/11_enum.md) - - [Refinement Type](./type/12_refinement.md) - - [Algebraic Type](./type/13_algebraic.md) - - [Dependent Type](./type/14_dependent.md) - - [Quantified Type](./type/15_quantified.md) - - [Subtyping](./type/16_subtyping.md) - - [Type Casting](./type/17_type_casting.md) - - [Mutable Type](./type/18_mut.md) - - [Advanced](./type/advanced.md) - - [Default Parameter](./type/advanced/default_param.md) - - [Type Erasure](./type/advanced/erasure.md) - - [Existential](./type/advanced/existential.md) - - [GADTs](./type/advanced/GADTs.md) - - [Keyword Parameters](./type/advanced/keyword_param.md) - - [Kind](./type/advanced/kind.md) - - [Marker Trait](./type/advanced/marker_trait.md) - - [Mutable Struct](./type/advanced/mut_struct.md) - - [Phantom Type](./type/advanced/phantom.md) - - [Projection Type](./type/advanced/projection.md) - - [Quantified Dependent Type](./type/advanced/quantified_dependent.md) - - [Shared](./type/advanced/shared.md) -- [Iterator](./16_iterator.md) -- [Mutability](./17_mutability.md) -- [Ownership](./18_ownership.md) -- [Visibility](./19_visibility.md) -- [Naming Rule](20_naming_rule.md) -- [Lambda](./21_lambda.md) -- [Subroutine](./22_subroutine.md) -- [Closure](./23_closure.md) -- [Module](./24_module.md) -- [Object System](./25_object_system.md) -- [Pattern Matching](./26_pattern_matching.md) -- [Comprehension](./27_comprehension.md) -- [Spread Syntax](./28_spread_syntax.md) -- [Decorator](./29_decorator.md) -- [Error Handling](./30_error_handling.md) -- [Pipeline](./31_pipeline.md) -- [Integration With Python](./32_integration_with_python.md) -- [Package System](./33_package_system.md) -- [Generator](./34_generator.md) -- [Index](./indexes.md) diff --git a/doc/zh_TW/syntax/container_ownership.md b/doc/zh_TW/syntax/container_ownership.md deleted file mode 100644 index ff8463fe..00000000 --- a/doc/zh_TW/syntax/container_ownership.md +++ /dev/null @@ -1,42 +0,0 @@ -# Subscript(下標訪問) - -不同於常規方法。 - - -```erg -a = [!1, !2] -a[0].inc!() -assert a == [2, 2] -``` - -請記住,不能在子例程的返回值中指定引用。在這裡,的類型顯然應該是的類型取決於上下文)。因此,實際上是與相同的特殊語法的一部分。不像 Python,你不能過載。方法也不能再現行為。 - - -```erg -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!() -``` - -此外,也可以剝奪所有權,但元素並不會因此而發生轉移。 - - -```erg -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/zh_TW/syntax/grammar.txt b/doc/zh_TW/syntax/grammar.txt deleted file mode 100644 index d9dbbb2a..00000000 --- a/doc/zh_TW/syntax/grammar.txt +++ /dev/null @@ -1,88 +0,0 @@ -# The Grammar of Erg (ver 0.1.0, provisional) -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)* diff --git a/doc/zh_TW/syntax/indexes.md b/doc/zh_TW/syntax/indexes.md deleted file mode 100644 index 1a8dc93a..00000000 --- a/doc/zh_TW/syntax/indexes.md +++ /dev/null @@ -1,452 +0,0 @@ -# 指數 - -有關不在此索引中的 API,請參閱 [此處](../API/index.md)。 -有關術語,請參見 [此處](../dev_guide/terms.md)。 - -## 象徵 - -* ! - * !-type → [可變類型](./type/mut.md) -* [#](./00_basic.md/#comment) -*$ -*% -* & - * && -* ′(單引號) -* () -* * - * [*-less 乘法](./01_literal.md/#less-multiplication) -* + (前綴) - * +_ → + (前綴) -* + (中綴) -* , -* −(前綴) - * −_ → − (前綴) -* −(中綴) - * 減號;> -* . → [可見性] -* / -* : - * :: → [可見性] -* ; -* < - * <: - * << - * <= -* = - * == - * => -* > - *>> - * >= -* ? -* @ -* [] -* \ -* ^ - * ^^ -* _ - * _+_ → +(中綴) - * _-_ → −(中綴) -*`` -* {} - * {} 類型 -* {:} -* {=} - * {=} 類型 -* | - * || -* ~ - -## 字母 - -### 一個 - -* [代數類型] -* [和] -* [和] -* [斷言] -* [屬性] - -###B - -* [根據] -* [布爾] - -### C - -* [班級] - -###D - -*已棄用 -* [清楚的] - -###E - -* [枚舉類型] -*[方程式] -*[爾格] - -###F - -*[為了] - -###G - -###H - -### 我 - -*[如果] -* [進口] -* [在] -* [詮釋] - -###J - -###K - -### 大號 - -* let-polymorphism → [rank 1 多態性] -* [日誌] - -###M - -* [匹配] - -###N - -*[納特] -* 絕不 -*沒有任何 -*沒有任何 -*[不是] -* [不是] - -###O - -* [選項] -* [或者] -* [或者] -*[訂購] - -###P - -* 恐慌 -* [打印! ](./../API/procs.md#print) -*[Python] - -### Q - -### R - -* 參考 -* 參考! -* [結果] -* [根對象] - -### S - -* 自己 -* [自我](./type/special.md) -* [副作用](./07_side_effect.md) -* [力量] - -### T - -* 特質 -* [真的] -* [類型] -* [類型] - -### U - -### V - -### W - -* [儘管! ] - -### X - -### Y - -### Z - -## 一行 - -* [斷言] -* 值對象 -* [附件補丁](./29_decorator.md#attach) -* Ad-hoc 多態性 → [無重載](./type/overloading.md) -* 屬性 → [屬性] -* 稀有度 -* [依賴類型](./type/dependent_type.md) -* 不可變 → [不可變] -* 參數 → [參數] -* 實例 -* [即時塊](./00_basic.md#表達式分隔符) -* 指數 -* [縮進](./00_basic.md#indent) -* 別名 -* 錯誤 - * [錯誤處理] -* [運算符](./06_operator.md) - * [運算符綁定強度] -* 覆蓋 -* [不重載](./type/overloading.md) -* 越位規則 → [縮進](./00_basic.md#indent) -* [目的] - * 面向對象 -* 操作數 → [操作數](./06_operator.md) -* 運算符 → [運算符](./06_operator.md) - -##嘉線 - -* [種類](./type/advanced/kind.md) -* [可見性] -* [類型] - * [類型規格] - * [類型擦除](./type/advanced/erasure.md) - * [類型推斷] - * [類型註釋](./type/conv_type.md) - * [類型參數] - * [類型添加](./type/advanced/erasure.md) - * [類型變量](./type/type_variable.md) - * [類型約束] -* [警衛] -* 封裝 -* [多變的] - * [可變對象] - * [多變的] - * [變量參考] - * [變量數組] - * [可變參數] -* [函數](./04_function.md) - * [函數式編程] (./23_scope.md#Avoiding mutable state 函數式編程) -* 基本類型 -* 簽 - * [命名類型] → [類](./type/04_class.md) - * [報喜] - * [名義子類型](./type/05_nst_vs_sst.md) -*捕獲→[關閉] -* [協變] -* [關鍵字參數] -* 空集 → [{}] -* 部分 - * [間隔類型](./type/11_interval.md) - * 區間運算符 -* 內置 - * [內置型] - * [內置函數](./05_builtin_funcs.md) - * [內置程序](./09_builtin_procs.md) -* [類](./type/04_class.md) -* [關閉] -* [全局變量] -* [克隆] -* [繼承](./type/07_inheritance.md) -* 高樓層 - * [高級種類](./type/advanced/kind.md) - * 高階類型 - * 高階函數 -* [公共變量] -* [結構亞型] -* ~~反向引用~~ → [反向引用] -* [複製] -* 評論 -* [集合](./10_array.md) -* 冒號 → [:] -* [構造函數](./type/04_class.md) -* 容器 -* 編譯器 -* [編譯時計算](./04_function.md#compile-time函數) -* 逗號 → [,] - -## sa線 - -* 遞歸 - * 遞歸 - * [遞歸函數](./04_function.md#遞歸函數) -* 下標 → [索引] -* [子類型多態性](./type/overloading.md) -* 子程序 -* [參考] (./18_memory_management.md# 借用) - * 參考對象 - * [引用計數(RC)](./18_memory_management.md#內存管理) - * 引用相等 → [副作用](./07_side_effect.md) -* [標識符](./02_variable.md/# 賦值) -* 簽名 - * 類型簽名 -* [字典](./11_dict.md) -* [自然數] → [Nat] -* 泛型 → [通用類型] -* 發電機 -* [投影類型] -* 借用 → [參考](./18_memory_management.md#Borrow) -* [陰影] (./02_name.md# 變量) -* 物種 → [種類](./type/advanced/kind.md) -* [套裝] → [套裝] -* 謂詞 - * [謂詞函數] -* 條件分支 -* [所有權] -* 布爾 → [布爾] -* 單身人士 -* [符號] → [標識符](./02_name.md) - * [符號化] -* [腳本](./00_basic.md# 腳本) -* 範圍 -* 擴展運算符 → [擴展賦值] -* [切片](./10_array.md#slice) -* 控製字符 -* [整數] → [整數] -* [設置](./12_set.md) -* 分號 → [;] -* [聲明](./03_declaration.md) -* 全名 - * 通用類型 → [多態類型](./type/quantified.md) - * 封閉式通用 - * 打開通用 - * 通用函數 → 多相關函數 - * 通用量化 -* 前綴運算符 -* 相互遞歸 -* 下標 → [索引] -* [屬性] - * [屬性子類型] - -## 塔線 - -* [代數](./02_name.md) - * [代數類型](./type/13_algebraic.md) - * 代數數據類型 -* [賦值](./02_variable.md/#assignment) -* 多 - * [多重繼承](./type/07_inheritance.md/#禁止多重繼承) - * 多重賦值 - * 重載 → [不重載] -* 多相 - * [多態類型](./type/quantified.md) - * 多相關係數 -* 多態 → [多態] -*鴨子打字 -* [元組](./11_tuple.md) -* 單相 - * 單相 - * 單相型 - * 單相關係數 -* [延遲初始化] -* 提取任務 -* 抽象語法樹 → [AST] -* 中綴運算符 -* [常數](./02_name.md/#constant) - * [常量類型](./type/advanced/const.md) - * [常量表達式](./type/advanced/const.md) -*[定義] -* 提供的屬性 -* [申請] -* [裝飾器](./29_decorator.md) -* 析構函數 -* 程序 → [程序](./08_procedure.md) -* [默認參數](./04_function.md/#default arguments default-parameters) -* 擴張 - * [擴展運算符] - * [擴展分配] -* [特殊格式](./../API/special.md) -* 匿名函數 → [匿名函數](./20_lambda.md) -* 點運算符 (`.`) → [屬性參考] -* 頂部 - * 頂部類型 → [結構對象] - * 頂級 → [對象] -* [特質](./type/03_trait.md) - -## 沒有一行 - -* [理解](./27_comprehension.md) -* ~~中綴運算符~~ → [中綴運算符] -* [命名空間] - -## 是一行 - -* [數組](./10_array.md) -* [派生類型](./type/variances.md/#用戶定義的類型變體) -* [模式(匹配)](./26_pattern_matching.md) -* [包](./33_package_s系統.md) -* Hashmap → [字典](./11_dict.md) -* [補丁](./type/07_patch.md) -* 公共變量 → [公共變量](./19_visibility.md) -* 參數 → [參數](./04_function.md) -* [參數多態](./type/overloading.md) -* [逆變](./type/advanced/variance.md) -* 相比 - * [比較運算符] - * [可比類型] -* [私有變量](./19_visibility.md) -* 標準 - * 標準輸出 - * 標準輸入 - * 標準庫 -* [副作用](./07_side_effect.md) -* 複數 → [複數] -* [浮動] → [浮動] -* 私有變量 → [私有變量] -* 布爾代數 → [布爾] -* [程序](./08_procedure.md) -* [參數](./04_function.md) -* 部分輸入 → [子輸入] -* [不可變] - * [不可變對象] - * [不可變類型] - * [不可變引用] -* [篩子類型](./type/12_refinement.md) -* [堵塞] -* 解構賦值 -* [變量](./02_variable.md) -* 底部 - * 底部類型 → [{}] - * 底層 → [從不] -* [多態性] - -## 馬線 - -* ~~ 前綴運算符 ~~ → 前綴運算符 -* [標記類型](./type/advanced/marker_trait.md) -* [匿名函數](./21_lambda.md) -* 可變 → [可變] -* [移動] -* 方法 -* 元字符 -* [模塊](./24_module.md) -* [字符串] → [字符串] - * [字符串插值](./01_literal.md/#str 字面量) -* 返回值 - -## 或行 - -* [幽靈類型](./type/advanced/phantom.md) -* 請求屬性 -* [元素] -* [稱呼] - -## 拉線 - -* [圖書館] -* Lambda 表達式 → [匿名函數](./20_lambda.md) -* 排名 - * [Rank 2 多態性](./type/advanced/rank2type.md) -* [文字](./01_literal.md) - * [文字標識符](./18_naming_rule.md/#literal identifier) -* [量化](./type/quantified.md) -* [佈局](./type/mut.md) -* [枚舉](./type/10_enum.md) -* [記錄](./12_record.md) - * [記錄類型] - * 記錄多態 → [列多態] -* [列多態] -* [局部變量](./19_visibility.md) - -## 線 - -* 通配符 \ No newline at end of file diff --git a/doc/zh_TW/syntax/quick_tour.md b/doc/zh_TW/syntax/quick_tour.md deleted file mode 100644 index 2a69a835..00000000 --- a/doc/zh_TW/syntax/quick_tour.md +++ /dev/null @@ -1,287 +0,0 @@ -# Quick Tour - -下面的文檔旨在讓初學者也能理解。對於已經掌握 Python,Rust,Haskell 等語言的人來說,這可能有點多餘。 - -因此,下面將概述性地介紹 Erg 的語法。沒有特別提到的部分可以認為和 Python 一樣。 - -## 變量,常量 - -變量定義為。與 Haskell 一樣,一旦定義變量,就無法重寫。但是,你可以在另一個範圍內進行陰影。 - - -```erg -i = 0 -if True: - i = 1 -assert i == 0 -``` - -以大寫字母開頭的是常量。只有編譯時可以計算的內容才可以是常量。此外,常量在定義後的所有作用域中都是相同的。 - - -```erg -PI = 3.141592653589793 -match random.random!(0..10): - PI: - log "You get PI, it's a miracle!" -``` - -## 聲明 - -與 Python 不同,你只能先聲明變量類型。當然,聲明類型必須與實際賦值的對像類型兼容。 - - -```erg -i: Int -i = 10 -``` - -## 函數 - -你可以像 Haskell 一樣定義它。 - - -```erg -fib 0 = 0 -fib 1 = 1 -fib n = fib(n - 1) + fib(n - 2) -``` - -可以按如下方式定義未命名函數。 - - -```erg -i -> i + 1 -assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4] -``` - -## 運算符 - -Erg 自己的運算符如下所示。 - -### 變量運算符(!) - -就像 Ocaml 的。 - - -```erg -i = !0 -i.update! x -> x + 1 -assert i == 1 -``` - -## 過程 - -有副作用的子程序稱為過程,並帶有。 - - -```erg -print! 1 # 1 -``` - -## 類屬函數(多相關數) - - -```erg -id|T|(x: T): T = x -id(1): Int -id("a"): Str -``` - -## 記錄 - -你可以使用 ML 語言中的記錄(或 JS 中的對象文字)。 - - -```erg -p = {x = 1; y = 2} -``` - -## 所有權 - -Erg 擁有可變對象(使用運算符可變的對象)的所有權,不能從多個位置重寫。 - - -```erg -i = !0 -j = i -assert j == 0 -i # MoveError -``` - -相反,你可以從多個位置引用不變對象。 - -## 可見性 - -如果在變量的前面加上,則該變量將成為公共變量,並且可以被外部模塊引用。 - - -```erg -# foo.er -.x = 1 -y = 1 -``` - - -```erg -foo = import "foo" -assert foo.x == 1 -foo.y # VisibilityError -``` - -## 模式匹配 - -### 變量模式 - - -```erg -# basic assignment -i = 1 -# with type -i: Int = 1 -# function -fn x = x + 1 -fn: Int -> Int = x -> x + 1 -``` - -### 文字模式 - - -```erg -# if `i` cannot be determined to be 1 at compile time, TypeError occurs. -# short hand of `_: {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 -``` - -### 常數模式 - - -```erg -PI = 3.141592653589793 -E = 2.718281828459045 -num = PI -name = match num: - PI -> "pi" - E -> "e" - _ -> "unnamed" -``` - -### 銷毀(通配符)模式 - - -```erg -_ = 1 -_: Int = 1 -right(_, r) = r -``` - -### 可變長度模式 - -與後述的元組/數組/記錄模式組合使用。 - - -```erg -[i, ...j] = [1, 2, 3, 4] -assert j == [2, 3, 4] -first|T|(fst: T, ...rest: T) = fst -assert first(1, 2, 3) == 1 -``` - -### 元組圖案 - - -```erg -(i, j) = (1, 2) -((k, l), _) = ((1, 2), (3, 4)) -# ネストしていないなら()を省略可能(1, 2は(1, 2)として扱われる) -m, n = 1, 2 -``` - -### 數組模式 - - -```erg -length [] = 0 -length [_, ...rest] = 1 + length rest -``` - -#### 記錄模式 - - -```erg -{sin; cos; tan; ...} = import "math" -{*} = import "math" # import all - -person = {name = "John Smith"; age = 20} -age = match person: - {name = "Alice"; _} -> 7 - {_; age} -> age -``` - -### 數據類模式 - - -```erg -Point = Inherit {x = Int; y = Int} -p = Point::{x = 1; y = 2} -Point::{x; y} = p -``` - -## 內涵記載 - - -```erg -odds = [i | i <- 1..100; i % 2 == 0] -``` - -## 類 - -Erg 不支持多級和多級繼承。 - -## trait - -與 Rust 的trait類似,但更接近原意,可以合成和分離,屬性和方法是對等的。也不涉及實施。 - - -```erg -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. - ... -``` - -## 補丁 - -你可以為類和trait提供實現。 - -## 篩子型 - -可以在謂詞表達式中限制類型。 - - -```erg -Nat = {I: Int | I >= 0} -``` - -## 包含值的參數化(從屬) - - -```erg -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 deleted file mode 100644 index c6b1980f..00000000 --- a/doc/zh_TW/syntax/type/01_type_system.md +++ /dev/null @@ -1,224 +0,0 @@ -# Erg 類類型系統 - -下面是 Erg 類型系統的簡要說明。其他部分將介紹更多信息。 - -## 定義方法 - -Erg 的獨特之處在於,(常規)變量、函數(子程序)和類型(卡印度)的定義沒有太大的語法差異。所有這些都是根據常規變量和函數定義的語法定義的。 - - -```erg -f i: Int = i + 1 -f # -f(1) # 2 -f.method self = ... # SyntaxError: cannot define a method to a subroutine - -T I: Int = {...} -T # -T(1) # Type T(1) -T.method self = ... -D = Class {private = Int; .public = Int} -D # -o1 = {private = 1; .public = 2} # o1はどのクラスにも屬さないオブジェクト -o2 = D.new {private = 1; .public = 2} # o2はDのインスタンス -o2 = D.new {.public = 2} # InitializationError: class 'D' requires attribute 'private'(: Int) but not defined -``` - -## 分類 - -Erg 中的所有對像都已輸入。最高類型是,它實現了等(它們不是請求方法,也不能覆蓋這些屬性)。 Erg 類型系統採用結構子類型(Structural subtyping,SST)。系統輸入的類型稱為“結構類型”(Structural type)。有三種結構類型: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 | - -也可以使用 Nominal subtyping(Nominal subtyping,NST),將 SST 類型轉換為 NST 類型稱為“類型記名”(Nominalization)。這種類型稱為“記名類型”(Nominal type)。在 Erg 中,記名類型為類和trait。如果只是一個類/任務,則通常指的是記錄類/記錄任務。 - -| | Type | Abstraction | Subtyping procedure | -| --- | -------------- | ---------------- | ------------------- | -| NST | NominalType | Trait | Inheritance | -| SST | StructuralType | Structural Trait | (Implicit) | - -表示整個記名類型的類型()和整個結構類型的類型()是整個類型的類型()的子類型。 - -Erg 可以將參數(類型參數)傳遞給類型定義。具有類型參數的,等稱為多項卡印。它們本身不是類型,但通過應用參數成為類型。此外,沒有參數的類型稱為簡單類型(標量類型)。 - -類型可以被視為一個集合,也存在包含關係。例如,包含等,包含。所有類的上級類為,所有類型的下級類為。我們將在後面討論這一點。 - -## 型 - -像這樣的類型以為參數,返回類型,即類型的函數(理論上也稱為類型)。像這樣的類型被特別稱為多相類型,而本身被稱為 1 項卡印度。 - -參數和返回類型已知的函數類型將顯示為。如果要指定類型相同的 2 自變量函數整體,可以指定;如果要指定 N 自變量函數整體,可以指定。但是,由於類型沒有關於參數數量或類型的信息,因此調用時所有返回值都是類型。 - -類型應表示為,依此類推。此外,類型實例的名稱必須以結尾。 - -類型是一個函數/過程,它將其所屬的對象指定為第一個參數(作為引用)。對於依賴關係,你還可以在應用方法後指定自己的類型。這意味著你可以指定類型的方法,例如。 - -Erg 數組(Array)就是 Python 的列表。是包含三個類型對象的數組類。 - -> :既是類型又是值,因此可以這樣使用。 -> -> `` `erg -> Types = (Int, Str, Bool) -> -> for! Types, T => -> print! T -> # Int Str Bool -> a: Types = (1, "aaa", True) -> ``` - - -```erg -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) -``` - -帶有的類型允許對象的內部結構重寫。例如,類是一個動態數組。要從類型對像生成類型對象,請使用一元運算符。 - - -```erg -i: Int! = !1 -i.update! i -> i + 1 -assert i == 2 -arr = [1, 2, 3] -arr.push! 4 # ImplError: -mut_arr = [1, 2, 3].into [Int; !3] -mut_arr.push! 4 -assert mut_arr == [1, 2, 3, 4] -``` - -## 類型定義 - -類型定義如下。 - - -```erg -Point2D = {.x = Int; .y = Int} -``` - -如果省略,例如,則它將成為類型中使用的私有變量。但這也是請求屬性。類型本身也有屬性,因為類型也是對象。這些屬性稱為類型屬性。類也稱為類屬性。 - -## 類型類、數據類型(等效) - -如前所述,Erg 中的“類型”大致是指一組對象。以下是要求(中置運算符)的類型的定義。 是一個所謂的類型參數,它包含實現的類型(類),如。在其他語言中,類型參數具有特殊的符號(通用、模板等),但在 Erg 中,類型參數的定義方式與常規參數的定義方式相同。類型參數也可以不是類型對象。例如,序列類型是的语法糖。如果類型實現被覆蓋,則用戶必須顯式選擇。 - - -```erg -Add R = Trait { - .AddO = Type - .`_+_` = Self.(R) -> Self.AddO -} -``` - -.是 Add.的縮寫。前綴運算符.是類型為的方法。 - - -```erg -Num = Add and Sub and Mul and Eq -NumImpl = Patch Num -NumImpl. - `+_`(self): Self = self - ... -``` - -多相類型可以像函數一樣處理。單相化,例如(在許多情況下,即使未指定,也會使用實際參數進行推理)。 - - -```erg -1 + 1 -`_+_` 1, 1 -Nat.`_+_` 1, 1 -Int.`_+_` 1, 1 -``` - -最上面的四行返回相同的結果(確切地說,最下面的行返回),但通常使用最上面的行。 - -```Ratio.`_+_`(1, 1)```とすると、エラーにはならず`2.0`が返ります。 -これは、`Int <: Ratio`であるために`1`が`Ratio`にダウンキャストされるからです。 -しかしこれはキャストされません。 - -```erg -i = 1 -if i: # TypeError: i: Int cannot cast to Bool, use Int.is_zero() instead. - log "a" - log "b" -``` - -這是因為()。轉換到子類型通常需要驗證。 - -## 類型推理系統 - -Erg 採用靜態烤鴨打字,幾乎不需要明確指定類型。 - - -```erg -f x, y = x + y -``` - -對於上面的代碼,將自動推斷具有的類型,即。 Erg 首先推論最小的類型。如果,則推論為;如果,則推論為。最小化後,類型將不斷增大,直到找到實現。對於,由於是具有實現的最小類型,因此將單相化為不匹配,因此將單相化為。如果不是子類型或上類型關係,則從濃度(實例數)較低(如果是多相類型,則參數更少)開始嘗試。 是作為等部分類型的枚舉類型。枚舉類型等可以命名為請求/實現方法。在可以訪問該類型的命名空間中,滿足請求的對象可以使用實現方法。 - - -```erg -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 -``` - -以下代碼可能是(儘管是內置定義的)。如代碼中所示,下面是一個類型的示例,該類型實際上可以重寫。 - - -```erg -Binary! = Patch {0, 1}!Binary!. - switch! ref! self = match! self: - 0 => self = 1 - 1 => self = 0 - -b = !1 -b.switch!() -print! b # => 0 -``` - -## 結構(未命名) - - -```erg -Binary = {0, 1} -``` - -在上面的代碼中,是元素的類型,其中是元素的類型。也可以說是既有又有類型的子類型。像這樣的對象本身就是一個類型,可以像上面那樣代入變量使用,也可以不代入變量使用。這種類型稱為結構類型。與類(記名型)對比,強調作為後者使用時,也稱為無名型。像這樣的結構類型稱為枚舉類型,其他類型包括區間類型和記錄類型。 - -### 類型同一性 - -不能像下面這樣指定。被解釋為指的是不同的東西。例如,都是,但不能相加。 - - -```erg -add l: Add, r: Add = - l + r # TypeError: there is no implementation of `_+_`: |T, U <: Add| (T, U) -> -``` - -此外,下面的和不能被視為同一類型。但是,類型被視為匹配。 - - -```erg -... |R1; R2; O; A <: Add(R1, O); B <: Add(R2, O)| -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/type/02_basic.md b/doc/zh_TW/syntax/type/02_basic.md deleted file mode 100644 index 9e1eec51..00000000 --- a/doc/zh_TW/syntax/type/02_basic.md +++ /dev/null @@ -1,170 +0,0 @@ -# 類型的基本語法 - -## 類型指定 - -Erg 在之後指定變量類型,如下所示。也可以在賦值的同時進行。 - - -```erg -i: Int # 聲明從現在開始使用的變量 i 為 Int 類型 -i: Int = 1 -j = 1 # type specification can be omitted -``` - -也可以為常規表達式指定類型。 - - -```erg -i = 1: Int -f([1, "a"]: [Int or Str]) -``` - -對於簡單變量賦值,大多數類型都是可選的。類型在定義子例程和類型時比簡單變量更有用。 - - -```erg -# 參數類型說明 -f x, y: Array Int = ... -T X, Y: Array Int = ... -``` - -注意,在上述情況下,都是。 - - -```erg -# 大寫變量值必須是常量表達式 -f X: Int = X -``` - -或者,如果你不完全需要類型參數信息,則可以使用將其省略。 - - -```erg -g v: [T; _] = ... -``` - -但是,請注意,如果在指定類型的位置指定,則意味著。 - - -```erg -f x: _, y: Int = x + y # TypeError: + is not implemented between Object and Int -``` - -## 子類型指定 - -除了使用(類型聲明運算符)指定類型與表達式之間的關係外,Erg 還使用(子類型聲明運算符)指定類型之間的關係。 的左邊只能是類。使用等比較結構類型。 - -它通常用於子程序或類型定義,而不是簡單的變量。 - - -```erg -# 部分輸入參數 -f X <: T = ... - -# 請求屬性子類型(要求 .Iterator 屬性是 Iterator 類型的子類型) -Iterable T = Trait { - .Iterator = {Iterator} # == {I | I <: Iterator} - .iter = Self.() -> Self.Iterator T - ... -} -``` - -還可以在定義類時指定子類型,以靜態方式檢查類是否為指定類型的子類型。 - - -```erg -# C 類是 Show 的子類型 -C = Class Object, Impl=Show -C.show self = ... # Show請求屬性 -``` - -也可以僅在特定情況下指定子類型。 - - -```erg -K T: Eq -K Int <: Show and Eq -K T = Class Object -K(T). - `==` self, other = ... -K(Int). - show self = ... -``` - -建議在實現結構類型時使用子類型。由於結構部分類型的特性,在實現請求屬性時,即使存在錯誤的拼貼或類型指定,也不會出現錯誤。 - - -```erg -C = Class Object -C.shoe self = ... # Show 由於 Typo 沒有實現(它只是被認為是一種獨特的方法) -``` - -## 屬性定義 - -只能在模塊中為托盤和類定義屬性。 - - -```erg -C = Class() -C.pub_attr = "this is public" -C::private_attr = "this is private" - -c = C.new() -assert c.pub_attr == "this is public" -``` - -在或後換行並縮進的語法稱為批量定義(batch definition)。 - - -```erg -C = Class() -C.pub1 = ... -C.pub2 = ... -C::priv1 = ... -C::priv2 = ... -# is equivalent to -C = Class() -C. - pub1 = ... - pub2 = ... -C:: - priv1 = ... - priv2 = ... -``` - -## 鋸齒 - -可以為類型指定別名(別名)。這使你可以將長類型(如記錄類型)表示為短類型。 - - -```erg -Id = Int -Point3D = {x = Int; y = Int; z = Int} -IorS = Int or Str -Vector = Array Int -``` - -此外,在錯誤顯示過程中,編譯器應盡可能使用複雜類型(在上面的示例中,不是第一種類型的右邊類型)的別名。 - -但是,每個模塊最多只能有一個別名,如果有多個別名,則會出現 warning。這意味著具有不同目的的類型應重新定義為不同的類型。它還可以防止將別名附加到已有別名的類型。 - - -```erg -Id = Int -UserId = Int # TypeWarning: duplicate aliases: Id and UserId - -Ids = Array Id -Ints = Array Int # TypeWarning: duplicate aliases: Isd and Ints - -IorS = Int or Str -IorSorB = IorS or Bool -IorSorB_ = Int or Str or Bool # TypeWarning: duplicate aliases: IorSorB and IorSorB_ - -Point2D = {x = Int; y = Int} -Point3D = {...Point2D; z = Int} -Point = {x = Int; y = Int; z = Int} # TypeWarning: duplicate aliases: Point3D and Point -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/type/03_trait.md b/doc/zh_TW/syntax/type/03_trait.md deleted file mode 100644 index 721d341e..00000000 --- a/doc/zh_TW/syntax/type/03_trait.md +++ /dev/null @@ -1,193 +0,0 @@ -# TRAIT - -TRAIT 是一種記名類型,它將類型屬性請求添加到記錄類型中。它類似於 Python 中的抽象基類(Abstract Base Class,ABC),但具有代數運算能力。 - - -```erg -Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int} -``` - -TRAIT不區分屬性和方法。 - -請注意,TRAIT只能進行聲明,而不能進行實現(實現是通過以下稱為修補程序的功能實現的)。你可以檢查 TRAIT 是否在類中以子類型實現。 - - -```erg -Point2D <: Norm -Point2D = Class {.x = Int; .y = Int} -Point2D.norm self = self.x**2 + self.y**2 -``` - -未實現請求屬性將導致錯誤。 - - -```erg -Point2D <: Norm # TypeError: Point2D is not a subtype of Norm -Point2D = Class {.x = Int; .y = Int} -``` - -與結構類型一樣,Trait 可以應用合併,替換和排除操作(e.g.)。這種方式形成的TRAIT稱為即時TRAIT。 - - -```erg -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 也是一種類型,因此也可以用於常規類型指定。 - - -```erg -points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)] -assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25] -``` - -## TRAIT包容 - -擴展運算符允許你定義一個包含高級類型的 TRAIT 的 TRAIT。這稱為TRAIT的。在下面的示例中,包含。這對應於類中的繼承(Inheritance),但不同於繼承,可以通過組合來指定多個基本類型。根據排除一部分的TRAIT也OK。 - - -```erg -Add R = Trait { - .AddO = Type - .`_+_` = Self.(R) -> Self.AddO -} -ClosedAdd = Subsume Add(Self) -Sub R = Trait { - .SubO = Type - .`_-_` = Self.(R) -> O -} -ClosedSub = Subsume Sub(Self) -ClosedAddSub = Subsume ClosedAdd and ClosedSub -``` - -## 結構TRAIT - -TRAIT可以結構化。 - - -```erg -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) -``` - -記名任務不能只是實現請求方法,必須顯式聲明實現。不能用於類型的參數,因為在下面的示例中沒有明確的實現聲明。它必須是。 - - -```erg -Add = Trait { - .`_+_` = Self.(Self) -> Self -} -# |A <: Add|は省略できる -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) # TypeError: C is not subclass of Add -# hint: inherit or patch 'Add' -``` - -結構TRAIT可以沒有這種實現的聲明,但替代推理不起作用。使用時必須指定類型。 - -## 依賴項 - -TRAIT可以採取自變量。這與依賴關係相同。 - - -```erg -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"] -``` - -## TRAIT中的覆蓋 - -派生的 TRAIT 可以覆蓋基礎 TRAIT 的類型定義。在這種情況下,要覆蓋的方法類型必須是基礎方法類型的子類型。 - - -```erg -# `Self.(R) -> O`は`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 重複任務 - -實際的,的定義是這樣的。 - - -```erg -Add R = Trait { - .Output = Type - .`_+_` = Self.(R) -> .Output -} -Sub R = Trait { - .Output = Type - .`_-_` = Self.(R) -> .Output -} -Mul R = Trait { - .Output = Type - .`*` = Self.(R) -> .Output -} -``` - -名為的變量具有重複的名稱。如果要同時實現多個托盤,請指定。 - - -```erg -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 在使用時通常是類型推理的,但也可以通過使用顯式類型來解決。 - - -```erg -print! P.Output # TypeError: ambiguous type resolution -print! P|<: Mul(Int)|.Output # -``` - -## Appendix:Rust 與TRAIT的區別 - -Erg 的TRAIT忠於提出的TRAIT。為了能夠進行代數運算,TRAIT沒有實現,設計了必要時打補丁的設計。 - -

- Previous | Next -

\ 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 deleted file mode 100644 index c682d8a3..00000000 --- a/doc/zh_TW/syntax/type/04_class.md +++ /dev/null @@ -1,285 +0,0 @@ -# Class - -Erg 中的類通常可以生成其自身的元素(實例)。下面是一個簡單類的示例。 - - -```erg -Person = Class {.name = Str; .age = Nat} -# .newが定義されなかった場合、自動で`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 -``` - -給出的類型(通常為記錄)稱為要求類型(在本例中為)。可以在中生成實例。 只是一條記錄,但它通過轉換為實例。生成此類實例的子例程稱為構造函數。上面的類定義了方法,以便可以省略字段名等。 - -請注意,如下所示不換行定義會導致語法錯誤。 - - -```erg -Person.new name, age = ... # SyntaxError: cannot define attributes directly on an object -``` - -> :這是最近添加的規範,在以後的文檔中可能不受保護。如果發現就報告。 - -## 實例屬性、類屬性 - -在 Python 和其他語言中,很多情況下都是在塊端定義實例屬性,如下所示,這種寫法在 Erg 中是另外一個意思,需要注意。 - - -```python -# Python -class Person: - name: str - age: int -``` - - -```erg -# Ergでこの書き方はクラス屬性の宣言を意味する(インスタンス屬性ではない) -Person = Class() -Person. - name: Str - age: Int -``` - - -```erg -# 上のPythonコードに対応するErgコード -Person = Class { - .name = Str - .age = Nat -} -``` - -元素屬性(在記錄中定義的屬性)和類型屬性(在類中特別稱為實例屬性/類屬性)是完全不同的。類型屬性是類型本身所具有的屬性。類型的要素在自身中沒有目標屬性時參照類型屬性。要素屬性是要素直接具有的固有屬性。為什麼要做這樣的劃分?如果全部都是要素屬性,則在生成對象時需要復制、初始化所有屬性,這是因為效率低下。另外,這樣分開的話,“這個屬性是共用的”“這個屬性是分開擁有的”等作用就會明確。 - -用下面的例子來說明。由於這一屬性在所有實例中都是共通的,所以作為類屬性更為自然。但是,由於這一屬性應該是各個實例各自持有的,所以應該是實例屬性。 - - -```erg -Person = Class {name = Str} -Person:: - species = "human" -Person. - describe() = - log "species: {species}" - greet self = - log "Hello, My name is {self::name}." - -Person.describe() # species: human -Person.greet() # TypeError: unbound method Person.greet needs an argument - -john = Person.new {name = "John"} -john.describe() # species: human -john.greet() # Hello, My name is John. - -alice = Person.new {name = "Alice"} -alice.describe() # species: human -alice.greet() # Hello, My name is Alice. -``` - -順便一提,如果實例屬性和類型屬性中存在同名、同類型的屬性,就會出現編譯錯誤。這是為了避免混亂。 - - -```erg -C = Class {.i = Int} -C. - i = 1 # AttributeError: `.i` is already defined in instance fields -``` - -## Class, Type - -請注意,類類型與不同。只有一個類可以從中生成。可以使用獲取對象所屬的類。與此相對,有無數個類型。例如,。但是,最小的類型可以是一個,在這種情況下是。可以通過獲取對象的類型。這是一個編譯時函數,顧名思義,它是在編譯時計算的。除了類方法外,對像還可以使用修補程序方法。 Erg 不能添加類方法,但可以使用進行擴展。 - -也可以繼承現有的類(對於類)。 表示繼承。左邊的類型稱為派生類,右邊的參數類型稱為基類。 - - -```erg -MyStr = Inherit Str -# other: StrとしておけばMyStrでもOK -MyStr. - `-` self, other: Str = self.replace other, "" - -abc = MyStr.new("abc") -# ここの比較はアップキャストが入る -assert abc - "b" == "ac" -``` - -與 Python 不同,定義的 Erg 類缺省為(不可繼承)。要使其可繼承,必須為類指定裝飾器。 是可繼承類之一。 - - -```erg -MyStr = Inherit Str # OK -MyStr2 = Inherit MyStr # NG - -@Inheritable -InheritableMyStr = Inherit Str -MyStr3 = Inherit InheritableMyStr # OK -``` - -和在實際應用中大致等效。一般使用後者。 - -類的等價機制不同於類型。類型根據結構確定等價性。 - - -```erg -Person = {.name = Str; .age = Nat} -Human = {.name = Str; .age = Nat} - -assert Person == Human -``` - -類沒有定義等價關係。 - - -```erg -Person = Class {.name = Str; .age = Nat} -Human = Class {.name = Str; .age = Nat} - -Person == Human # TypeError: cannot compare classes -``` - -## 與結構類型的區別 - -類是一種可以生成自己元素的類型,但這並不是一個嚴格的描述。因為實際上,記錄類型 + 修補程序也可以做到這一點。 - - -```erg -Person = {.name = Str; .age = Nat} -PersonImpl = Patch Person -PersonImpl. - new name, age = {.name; .age} - -john = Person.new("John Smith", 25) -``` - -使用類有四個好處。一是檢查構造函數的合法性,二是性能高,三是可以使用記名部分類型 (NST),四是可以繼承和覆蓋。 - -我們已經看到記錄類型 + 修補程序也可以定義構造函數(類似),但這當然不是合法的構造函數。因為你可以返回一個自稱但完全不相關的對象。對於類,將靜態檢查是否生成滿足要求的對象。 - -~ - -類類型檢查只需查看對象的屬性即可完成。因此,檢查對像是否屬於該類型的速度較快。 - -~ - -Erg 在類中提供了 NST。 NST 的優點包括強健性。在編寫大型程序時,對象的結構仍然會偶然匹配。 - - -```erg -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!" -``` - -雖然和的結構完全相同,但允許動物打招呼和人類吠叫顯然是無稽之談。且不說後者,讓前者不適用更安全,因為前者是不可能的。在這種情況下,最好使用類。 - - -```erg -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() # TypeError: `Person` object has no method `.bark` -``` - -另一個特徵是,通過修補程序添加的類型屬性是虛擬的,而不是作為實體保存在要實現的類中。也就是說,和是與兼容的類型可以訪問(在編譯時綁定)的對象,而不是在中定義的對象。相反,類屬性由類自己維護。因此,結構相同但不具有繼承關係的類無法訪問。 - - -```erg -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 # -{i = Int}.bar # TypeError: Record({i = Int}) has no method `.bar` -C.bar # TypeError: C has no method `.bar` -print! {i = 1}.bar # -print! C.new({i = 1}).bar # -``` - -## 與數據類的區別 - -類可以是通過請求記錄的常規類,也可以是繼承記錄()的數據類。數據類繼承了記錄的功能,可以分解賦值,缺省情況下實現。相反,如果你想定義自己的等價關係和格式顯示,則可以使用常規類。 - - -```erg -C = Class {i = Int} -c = C.new {i = 1} -d = C.new {i = 2} -print! c # -c == d # TypeError: `==` is not implemented for `C` - -D = Inherit {i = Int} -e = D::{i = 1} # e = D.new {i = 1}と同じ -f = D::{i = 2} -print! e # D(i = 1) -assert e != f -``` - -## Enum Class - -提供以幫助定義 Or 類型的類。 - - -```erg -X = Class() -Y = Class() -XorY = Enum X, Y -``` - -每種類型都可以按和進行訪問,構造函數可以按進行檢索。是接收類並返回其構造函數的方法。 - - -```erg -x1 = XorY.new X.new() -x2 = XorY.cons(X)() -assert x1 == x2 -``` - -## 包含關係 - -類是需求類型的子類型。你可以使用要求類型的方法(包括修補程序方法)。 - - -```erg -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 -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/type/05_inheritance.md b/doc/zh_TW/syntax/type/05_inheritance.md deleted file mode 100644 index d1712019..00000000 --- a/doc/zh_TW/syntax/type/05_inheritance.md +++ /dev/null @@ -1,248 +0,0 @@ -# 繼承(Inheritance) - -通過繼承,你可以定義一個新類,該新類將添加或特定於現有類。繼承類似於trait中的包容。繼承的類將成為原始類的子類型。 - - -```erg -NewInt = Inherit Int -NewInt. - plus1 self = self + 1 - -assert NewInt.new(1).plus1() == 2 -assert NewInt.new(1) + NewInt.new(1) == 2 -``` - -如果你希望新定義的類是可繼承類,則必須指定裝飾器。 - -可選參數允許你具有其他實例屬性。但是,不能為值類添加實例屬性。 - - -```erg -@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} # TypeError: instance variables cannot be added to a value class -``` - -Erg 中例外的是不能繼承型的設計。因為是絕對不能生成實例的特殊類。 - -## 枚舉類繼承 - -也可以繼承以為類的枚舉類。在這種情況下,你可以通過指定選項參數來刪除任何選項(使用可以選擇多個選項)。仍不能添加。添加選擇的類不是原始類的子類型。 - - -```erg -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 - -# matchの選択肢でc: Complexは現れ得ない -RealNumber = Inherit Number, Excluding: Complex -``` - -同樣,也可以指定。 - - -```erg -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 -``` - -## 覆蓋 - -與修補程序相同,你可以在原始類型中添加新方法,但可以進一步“覆蓋”類。覆蓋稱為覆蓋。覆蓋必須滿足三個條件。首先,默認情況下,覆蓋是錯誤的,因此必須添加裝飾器。此外,覆蓋不能更改方法類型。必須是原始類型的子類型。如果要覆蓋其他方法引用的方法,則必須覆蓋所有引用的方法。 - -為什麼要有這樣的條件呢?這是因為覆蓋不僅可以改變一個方法的行為,還可以影響另一個方法的行為。 - -首先,從第一個條件開始解說。這是為了防止“意外覆蓋”。這意味著必須在裝飾器中顯示,以防止派生類中新定義的方法的名稱碰巧與基類衝突。 - -接下來,我們考慮第二個條件。這是為了保持類型的完整性。派生類是基類的子類型,因此其行為也必須與基類兼容。 - -最後,考慮第三個條件。這個條件是 Erg 特有的,在其他面向對象的語言中並不常見,但這也是為了安全起見。看看沒有這個的時候會發生什麼不好的事情。 - - -```erg -# Bad example -@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!() # InfiniteRecursionWarning: This code falls into an infinite loop - # OverrideError: method `.g` is referenced by `.f` but not overridden -``` - -繼承類覆蓋方法並將處理轉發到。但是,基類的方法將其處理轉發到,從而導致無限循環。 類中是一個沒有問題的方法,但由於被覆蓋而被意外地使用,並被破壞。 - -因此,通常需要重寫所有可能受覆蓋影響的方法。 Erg 將這一規則納入規範。 - - -```erg -# 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!() -``` - -但這一規範並不能完全解決覆蓋問題。編譯器無法檢測覆蓋是否修復了問題。創建派生類的程序員有責任修改替代的影響。應盡可能定義別名方法。 - -### 替換trait(類似於) - -你不能在繼承過程中替換 TRAIT,但有一個示例似乎是這樣做的。 - -例如,(實現)的子類型似乎正在重新實現。 - - -```erg -Int = Class ..., Impl := Add() and ... -``` - -但實際上,中的的縮寫,只是用覆蓋。兩者是不同的trait(,因此)。 - -## 禁止多重繼承 - -Erg 不允許常規類之間的 Intersection、Diff 或 Complement。 - - -```erg -Int and Str # TypeError: cannot unite classes -``` - -此規則不允許繼承多個類,即多重繼承。 - - -```erg -IntAndStr = Inherit Int and Str # SyntaxError: multiple inheritance of classes is not allowed -``` - -但是,可以使用 Python 多重繼承類。 - -## 禁止多層繼承 - -Erg 繼承也禁止多層繼承。也就是說,你不能定義繼承的類,也不能定義繼承的類。但是,繼承的(Inheritable)類除外。 - -此外,Python 多層繼承類仍然可用。 - -## 禁止改寫源屬性 - -Erg 無法重寫源屬性。這有兩個意思。首先,對繼承的類屬性執行更新操作。不僅不能重新賦值,也不能通過方法進行更新。 - -覆蓋與重寫不同,因為它是一種使用更特定的方法進行覆蓋的操作。替代也必須使用兼容類型進行替換。 - - -```erg -@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 - # TypeError: can't update base class variables - @Override - inc_pub! ref! self = self.pub + 1 - # OverrideError: `.inc_pub!` must be subtype of `Self!.() => ()` -``` - -第二種是對從其繼承的(可變)實例屬性執行更新操作。這也是禁止的。只能從基類提供的方法更新基類的實例屬性。無論屬性的可視性如何,都不能直接更新。但是可以讀取。 - - -```erg -@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 - -Inherited! = Inherit Base!: -Inherited!. - # OK - add2_pub! ref! self = - self.inc_pub!() - self.inc_pub!() - # NG, `Child` cannot touch `self.pub` and `self::pri` - add2_pub! ref! self = - self.pub.update! p -> p + 2 -``` - -最後,Erg 只能繼承添加新屬性和覆蓋基類方法。 - -## 繼承用法 - -如果正確使用,繼承是一個強大的功能,但另一方面,它也有一個缺點,即類之間的依賴關係容易變得複雜,特別是在使用多重繼承和多層繼承時,這種趨勢更為明顯。依賴項的複雜性可能會降低代碼的可維護性。 Erg 禁止多重繼承和多層繼承是為了降低這種風險,而引入類修補功能是為了在繼承“添加功能”的同時減少依賴關係的複雜性。 - -那麼反過來應該用繼承的地方在哪裡呢?一個指標是如果“想要基類的語義亞型”。 Erg 由類型系統自動確定子類型的一部分(如果 Int 大於或等於 e.g.0,則為 Nat)。但是,例如,僅依靠 Erg 類型系統來創建“表示有效電子郵件地址的字符串類型”是很困難的。應該對普通字符串進行驗證。然後,我們希望為驗證通過的字符串對象添加一個“保證書”。這相當於向下轉換到繼承類。將下鑄為與驗證字符串是否為正確的電子郵件地址格式一一對應。 - - -```erg -ValidMailAddressStr = Inherit Str -ValidMailAddressStr. - init s: Str = - validate s # mail-address validation - Self.new s - -s1 = "invalid mail address" -s2 = "foo@gmail.com" -_ = ValidMailAddressStr.init s1 # panic: invalid mail address -valid = ValidMailAddressStr.init s2 -valid: ValidMailAddressStr # assurance that it is in the correct email address format -``` - -另一個指標是“記名的多相 = 想實現多態”的情況。例如,下面定義的過程接受任何類型為的對象。但顯然,應用類型對像是錯誤的。因此,我們將參數類型設置為類。在這種情況下,只有對象和繼承它的類對像作為參數。這樣更保守,不用承擔不必要的更多責任。 - - -```erg -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 # Hello, my name is Max. -structural_greet! john # Hello, my name is John. -greet! alice # Hello, my name is Alice. -greet! max # TypeError: -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/type/06_nst_vs_sst.md b/doc/zh_TW/syntax/type/06_nst_vs_sst.md deleted file mode 100644 index f53a5a5f..00000000 --- a/doc/zh_TW/syntax/type/06_nst_vs_sst.md +++ /dev/null @@ -1,43 +0,0 @@ -# 記名的部分型 vs.構造的部分型 - - -```erg -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 中編碼。 - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/type/07_patch.md b/doc/zh_TW/syntax/type/07_patch.md deleted file mode 100644 index abc426ba..00000000 --- a/doc/zh_TW/syntax/type/07_patch.md +++ /dev/null @@ -1,223 +0,0 @@ -# Patch - -Erg 不允許修改現有類型類。不能在類中定義額外的方法,而是專門化(specialization,將聲明為多相的類型單相化並定義專用方法的功能。C++ 等也不能使用。但是,在許多情況下,你希望將功能添加到現有類型類中,而修補程序就是實現這一目標的方法。 - - -```erg -StrReverse = Patch Str -StrReverse. - reverse self = self.iter().rev().collect(Str) - -assert "abc".reverse() == "cba" -``` - -修補程序的名稱最好是要添加的主要功能的直接描述。這樣,要修補的類型()的對象就可以使用修補方法()。實際上,不是方法,而是添加到中的方法。 - -但是,修補程序方法的優先級低於記名(類)方法,因此不能覆蓋(覆蓋)現有類的方法。 - - -```erg -StrangeInt = Patch Int -StrangeInt. - `_+_` = Int.`_-_` # AssignError: .`_+_` is already defined in Int -``` - -如果要覆蓋,必須繼承類。但是,建議你定義一個具有不同名稱的方法,而不是覆蓋它。因為覆蓋有一些安全限制,不是那麼容易做到的。 - - -```erg -StrangeInt = Inherit Int -StrangeInt. - # オーバーライドするメソッドにはOverrideデコレータを付與する必要がある - # さらに、Int.`_+_`に依存するIntのメソッドすべてをオーバーライドする必要がある - @Override - `_+_` = Super.`_-_` # OverrideError: Int.`_+_` is referenced by ..., so these method must also be overridden -``` - -## 選擇修補程序 - -可以為一種類型定義多個曲面片,也可以將它們組合在一起。 - - -```erg -# 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 -``` - - -```erg -{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" -``` - -如果可以定義多個修補程序,某些修補程序可能會導致重複的實現。 - - -```erg -# foo.er - -StrReverse = Patch(Str) -StrReverse. - reverse self = ... -# more efficient implementation -StrReverseMk2 = Patch(Str) -StrReverseMk2. - reverse self = ... - -"hello".reverse() # PatchSelectionError: multiple choices of `.reverse`: StrReverse, StrReverseMk2 -``` - -在這種情況下,可以使用相關函數格式而不是方法格式來實現唯一性。 - - -```erg -assert StrReverseMk2.reverse("hello") == "olleh" -``` - -也可以通過選擇性導入來實現唯一性。 - - -```erg -{StrReverseMk2; ...} = import "foo" - -assert StrReverseMk2.reverse("hello") == "olleh" -``` - -## 粘合面片(Glue Patch) - -修補程序還可以關聯類型。將關聯起來。這些面片稱為“粘合面片”(Glue Patch)。由於是一個內置類型,因此用戶需要一個粘合貼片來改裝托盤。 - - -```erg -Reverse = Trait { - .reverse = Self.() -> Self -} - -StrReverse = Patch Str, Impl := Reverse -StrReverse. - reverse self = - self.iter().rev().collect(Str) -``` - -只能為一對類型和托盤定義一個粘合曲面片。這是因為,如果多個粘合貼片同時“可見”,則無法唯一確定選擇哪個實現。但是,你可以在切換到其他範圍(模塊)時替換修補程序。 - - -```erg -NumericStr = Inherit Str -NumericStr. - ... - -NumStrRev = Patch NumericStr, Impl := Reverse -NumStrRev. - ... -# DuplicatePatchError: NumericStr is already associated with `Reverse` -# hint: `Str` (superclass of `NumericStr`) is associated with `Reverse` by `StrReverse` -``` - -## Appendix:Rust 與trait的關係 - -Erg 修補程序相當於 Rust 的 impl 塊(後置)。 - - -```rust -// Rust -trait Reverse { - fn reverse(self) -> Self; -} - -impl Reverse for String { - fn reverse(self) -> Self { - self.chars().rev().collect() - } -} -``` - -可以說,Rust Traitt 是 Erg Traitt 和補丁的功能的結合。這樣說來,Rust 的trait聽起來更方便,其實也不盡然。 - - -```erg -# Erg -Reverse = Trait { - .reverse = Self.() -> Self -} - -StrReverse = Patch(Str, Impl := Reverse) -StrReverse. - reverse self = - self.iter().rev().collect(Str) -``` - -Erg 將 impl 塊對象化為修補程序,以便在從其他模塊導入時進行選擇性導入。此外,還允許在外部結構中實現外部托盤。此外,由於結構類型的不同,也不需要 dyn trait 和 impl trait 語法。 - - -```erg -# 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() -} -``` - -## 全稱補丁 - -你可以為特定類型定義修補程序,也可以為“常規函數類型”等定義修補程序。在這種情況下,將想要給出自由度的項作為參數(在下面的情況下為)。以這種方式定義的曲面片稱為全稱曲面片。正如你所看到的,全稱修補程序是一個返回修補程序的函數,但它本身也可以被視為修補程序。 - - -```erg -FnType T: Type = Patch(T -> T) -FnType(T). - type = T - -assert (Int -> Int).type == Int -``` - -## 結構補丁 - -此外,還可以為滿足某一結構的所有類型定義修補程序。但是,它的優先級低於記名修補程序和類方法。 - -在定義結構修補程序時,請仔細設計,因為擴展可能會導致不成立,如下所示。 - - -```erg -# これは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: -``` - -

- Previous | Next -

\ No newline at end of file diff --git a/doc/zh_TW/syntax/type/08_value.md b/doc/zh_TW/syntax/type/08_value.md deleted file mode 100644 index 1298ed20..00000000 --- a/doc/zh_TW/syntax/type/08_value.md +++ /dev/null @@ -1,38 +0,0 @@ -# 值類型(Value types) - -值類型是 Erg 內置類型中可以進行編譯時評估的類型,具體如下所示。 - - -```erg -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, _) -) -``` - -值類型的對象常量和編譯時子例程稱為常量表達式。 - - -```erg -1, 1.0, 1+2im, True, None, "aaa", [1, 2, 3], Fib(12) -``` - -需要注意子程序。子程序可能是值類型,也可能不是。雖然每個子例程的實體都是一個指針,並且都是一個值,但在編譯時,在常量上下文中使用非子例程並沒有什麼意義,因此它不是一個值類型。 - -以後可能會添加一些類型,這些類型被歸類為值類型。 - ---- - -1Erg 中的值類型一詞與其他語言中的定義不同。在純 Erg 語義學中,內存的概念不存在,因為它被放置在堆棧中,所以它是一種值類型,或者因為它是一個指針,所以它不是一種值類型,這些說法是不正確的。從根本上說,值類型是類型或其子類型。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/09_attributive.md b/doc/zh_TW/syntax/type/09_attributive.md deleted file mode 100644 index 0a833803..00000000 --- a/doc/zh_TW/syntax/type/09_attributive.md +++ /dev/null @@ -1,7 +0,0 @@ -# 屬性類型(Attributive Type) - -屬性類型是包含記錄和數據類、修補程序、模塊等的類型。屬於屬性類型的類型不是值類型。 - -## 記錄類型合併 - -合併的記錄類型可以展平。例如,等於。 \ 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 deleted file mode 100644 index dd672739..00000000 --- a/doc/zh_TW/syntax/type/10_interval.md +++ /dev/null @@ -1,39 +0,0 @@ -# Interval Type - -對象最基本的用法是用作迭代器。 - - -```erg -for! 0..9, i => - print! i -``` - -請注意,與 Python 不同,最後一個數字是包含的。 - -但是,這並不是對象的唯一用途。也可以作為模具使用。這些類型稱為“區間類型”(Interval type)。 - - -```erg -i: 0..10 = 2 -``` - -類型與等效,類型與等效。 也可以寫成表示類型的任何實例。 - -也可以用作迭代器,因此可以按相反的順序指定,如,但不能反轉的方向。 - - -```erg -a = 0..10 # OK -b = 0..<10 # OK -c = 10..0 # OK -d = 10<..0 # Syntax error -e = 10..<0 # Syntax error -f = 10<..<0 # Syntax error -``` - -範圍運算符(range operator)也可以用於非數字類型,只要它們是不變的。 - - -```erg -Alphabet = "A".."z" -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/11_enum.md b/doc/zh_TW/syntax/type/11_enum.md deleted file mode 100644 index aa876cbe..00000000 --- a/doc/zh_TW/syntax/type/11_enum.md +++ /dev/null @@ -1,86 +0,0 @@ -# 枚舉類型 - -“枚舉類型”(Enum type)由 Set 生成。雖然枚舉類型可以保持不變,但可以通過類化或定義修補程序來定義其他方法。枚舉部分類型系統稱為枚舉部分類型。 - - -```erg -Bool = {True, False} -Status = {"ok", "error"} -``` - -因為被重寫為,所以在元素有限的情況下,枚舉類型和區間類型本質上是等價的。 - - -```erg -Binary! = Class {0, 1}!. - invert! ref! self = - if! self == 0: - do! - self.set! 1 - do! - self.set! 0 - -b = Binary!.new !0 -b.invert!() -``` - -順便一提,Erg 的枚舉類型是一個包含其他語言中常見的枚舉類型的概念。 - - -```rust -// Rust -enum Status { Ok, Error } -``` - - -```erg -# Erg -Status = {"Ok", "Error"} -``` - -它與 Rust 的區別在於它採用了結構子類型 (SST)。 - - -```rust -// StatusとExtraStatusの間にはなんの関係もない -enum Status { Ok, Error } -enum ExtraStatus { Ok, Error, Unknown } - -// メソッドを実裝可能 -impl Status { - // ... -} -impl ExtraStatus { - // ... -} -``` - - -```erg -# Status > ExtraStatusであり、Statusの要素はExtraStatusのメソッドを使える -Status = Trait {"Ok", "Error"} - # ... -ExtraStatus = Trait {"Ok", "Error", "Unknown"} - # ... -``` - -還可以使用 patching 添加方法。 - -如果要顯式顯示包含關係,或者要向現有 Enum 類型添加選項,請使用運算符。 - - -```erg -ExtraStatus = Status or {"Unknown"} -``` - -元素所屬的所有類都相同的枚舉類型稱為“等質”(homogenous)枚舉類型。缺省情況下,要求類型相同的枚舉類型的類可以被視為元素所屬類的子類。如果你不想這樣做,則最好是包裝類。 - - -```erg -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() # TypeError -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/12_refinement.md b/doc/zh_TW/syntax/type/12_refinement.md deleted file mode 100644 index e0107967..00000000 --- a/doc/zh_TW/syntax/type/12_refinement.md +++ /dev/null @@ -1,75 +0,0 @@ -# 篩子類型(Refinement Type) - -Refinement type 是受謂詞表達式約束的類型。枚舉型和區間型是篩子型的一種。 - -篩型的標準形式是。這意味著它是以滿足為元素的類型。只有可用於篩型。 - - -```erg -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,請用或分隔。 是相同的意思。 - -的元素是。因為它是一種將現有類型的一部分作為要素的類型,就像在篩子上一樣,所以被稱為篩子類型。 - -稱為(左側)謂詞表達式。它不返回與賦值表達式相同的有意義的值,並且只能在左邊放置模式。也就是說,等式不能用作篩子謂詞表達式。這一點不同於右邊表達式的謂詞表達式。 - - -```erg -{X: Int | X**2 - 5X + 6 == 0} # SyntaxError: the predicate form is invalid. Only names can be on the left-hand side -``` - -如果你知道二次方程的解法,你應該可以預測,上面的篩子類型將等同於。然而,Erg 編譯器幾乎沒有代數學知識,因此無法解決右邊的謂詞表達式。 - -## Smart Cast - -定義是很好的,但如果這樣,除了文字以外,似乎很難使用它。要將常規對像中的奇數提升到,即將下鑄到,必須通過構造函數。對於篩子類型,常規構造函數可能會死機,有些輔助構造函數返回類型。 - - -```erg -i = Odd.new (0..10).sample!() -i: Odd # or Panic -``` - -也可以在中用作類型說明。 - - -```erg -# i: 0..10 -i = (0..10).sample!() -match i: - o: Odd -> - log "i: Odd" - n: Nat -> # 0..10 < Nat - log "i: Nat" -``` - -然而,由於 Erg 當前不是,因此不能進行諸如之類的次要判斷。 - -## 列舉型、區間型和篩型 - -之前介紹的枚舉型和區間型,是篩子型的糖衣句法。將脫糖為,將脫糖為。 - - -```erg -{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} -``` - -## 篩子模式 - -可以被重寫為(常數模式),可以被重寫為。 - - -```erg -# メソッド.mは長さ3以上の配列に定義される -Array(T, N | N >= 3) - .m(&self) = ... -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/13_algebraic.md b/doc/zh_TW/syntax/type/13_algebraic.md deleted file mode 100644 index fde83734..00000000 --- a/doc/zh_TW/syntax/type/13_algebraic.md +++ /dev/null @@ -1,82 +0,0 @@ -# Algebraic type(代數類型) - -代數運算類型是指將類型視為代數並進行運算而產生的類型。代數類型處理的操作包括 Union、Intersection、Diff 和 Complement。常規類只能是 Union,其他操作都是類型錯誤。 - -## Union - -在 Union 型中,關於型可以給出多個可能性。顧名思義,它由運算符生成。典型的 Union 是類型。 類型是的 patch type,主要表示可能失敗的值。 - - -```erg -IntOrStr = Int or Str -assert dict.get("some key") in (Int or NoneType) - -# 暗黙に`T != NoneType`となる -Option T = T or NoneType -``` - -## Intersection - -Intersection 類型是通過操作組合類型而得到的。 - - -```erg -Num = Add and Sub and Mul and Eq -``` - -如上所述,無法通過操作將常規類組合在一起。實例屬於唯一的類。 - -## Diff - -Diff 類型是通過運算得到的。作為接近英文的表記,比較好,但由於並列比較好,所以建議只使用。 - - -```erg -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} -``` - -## Complement - -Complement 是通過運算得到的,但它是一元運算。 類型是的縮寫符號。 類型的 Intersection 等效於 Diff,類型的 Diff 等效於 Intersection。但不建議這樣的寫法。 - - -```erg -# the simplest definition of the non-zero number type -NonZero = Not {0} -# deprecated styles -{True} == Bool and not {False} # 1 == 2 + - 1 -Bool == {True} not not {False} # 2 == 1 - -1 -``` - -## 真實代數類型 - -代數運算類型包括可簡化的表觀代數運算類型和不能進一步簡化的“真代數運算類型”。其他“表觀代數類型”包括 Enum 和 Interval 類型,以及和記錄類型。因為它們可以簡化,所以它們不是真正的代數運算類型,如果用來指定類型,就會出現 Warning。要消除警告,必須簡化或定義類型。 - - -```erg -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 # TypeWarning: {1, 2} or {3, 4} can be simplified to {1, 2, 3, 4} -p: {x = Int, ...} and {y = Int; ...} = {x = 1; y = 2; z = 3} -# TypeWaring: {x = Int, ...} and {y = Int; ...} can be simplified to {x = Int; y = Int; ...} - -Point1D = {x = Int; ...} -Point2D = Point1D and {y = Int; ...} # == {x = Int; y = Int; ...} -q: Point2D = {x = 1; y = 2; z = 3} -``` - -真正的代數類型包括類型和類型。類之間的等類型為類型。 - - -```erg -assert Int or Str == Or(Int, Str) -assert Int and Marker == And(Int, Marker) -``` - -Diff 和 Complement 類型不是真正的代數運算類型,因為它們總是可以簡化。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/14_dependent.md b/doc/zh_TW/syntax/type/14_dependent.md deleted file mode 100644 index d5b8afe0..00000000 --- a/doc/zh_TW/syntax/type/14_dependent.md +++ /dev/null @@ -1,76 +0,0 @@ -# 依賴關係 - -依賴性可以說是 Erg 最大的特點。依賴關係是一種以值為參數的類型。通常的多相型只能將型作為自變量,但放鬆了其限制,就可以說是依存型。 - -依賴關係可以是()。該類型不僅取決於內容的類型,而且取決於內容的數量包含類型為的對象。 - - -```erg -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] -``` - -如果在函數參數中傳遞的類型對象與返回類型相關聯,請使用。 - - -```erg -narray: |N: Nat| {N} -> [{N}; N] -narray(N: Nat): [N; N] = [N; N] -assert narray(3) == [3, 3, 3] -``` - -定義依賴關係類型時,所有類型參數必須為常量。 - -依賴關係本身也存在於現有語言中,但 Erg 允許你定義依賴關係的過程方法。 - - -```erg -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 -``` - -可以通過應用方法來轉換可變依賴類型參數。轉換規範在中進行。 - - -```erg -# `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!() # TypeError: VM!(!"stopped", 1) doesn't have .stop!() -# hint: VM!(!"running", 1) has .stop!() -``` - -也可以通過合併或繼承現有類型來創建依賴類型。 - - -```erg -MyArray(T, N) = Inherit [T; N] - -# .arrayと連動してself: Self(T, N)の型が変わる -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 deleted file mode 100644 index 7d7ab552..00000000 --- a/doc/zh_TW/syntax/type/15_quantified.md +++ /dev/null @@ -1,288 +0,0 @@ -# 類型變量,量化 - -類型變量是用於指定子例程參數類型的變量,並指示其類型是可選的(非單相)。首先,作為引入類型變量的動機,讓我們考慮返回輸入的函數。 - - -```erg -id x: Int = x -``` - -雖然為類型定義了一個按原樣返回輸入的函數,但該函數顯然可以為任何類型定義。讓我們使用來表示最大的類。 - - -```erg -id x: Object = x - -i = id 1 -s = id "foo" -b = id True -``` - -你現在可以接受任何類型,但有一個問題。返回類型將擴展為。如果輸入是類型,則返回類型;如果輸入是類型,則返回類型。 - - -```erg -print! id 1 # -id(1) + 1 # TypeError: cannot add `Object` and `Int` -``` - -若要確保輸入類型與返回類型相同,請使用。類型變量在(類型變量列表)中聲明。 - - -```erg -id|T: Type| x: T = x -assert id(1) == 1 -assert id("foo") == "foo" -assert id(True) == True -``` - -我們在函數中稱為。雖然有細微差別,但它們相當於其他語言中稱為通用的功能。然後,全稱量化函數稱為。定義多相關數就像為所有類型定義相同形式的函數一樣(由於 Erg 禁止重載,所以下面的代碼實際上是不可能寫的)。 - - -```erg -id|T: Type| x: T = x -# pseudo code -# == -id x: Int = x -id x: Str = x -id x: Bool = x -id x: Ratio = x -id x: NoneType = x -... -``` - -此外,類型變量用於指定類型,因此可以推斷為類型。因此,可以簡單地省略為。此外,如果你可以推理非類型對象,如),則可以省略它。 - -另外,如果任何類型太大,也可以給出限制。約束也有好處,例如,子類型規範允許你使用特定的方法。 - - -```erg -# T <: Add -# => TはAddのサブクラス -# => 加算ができる -add|T <: Add| l: T, r: T = l + r -``` - -在此示例中,必須是類型的子類,並且實際賦值的必須與類型相同。在這種情況下,是指。因為沒有定義的相加,所以彈。 - -也可以這樣打字。 - - -```erg -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 -``` - -如果註釋列表變長,最好預先聲明。 - - -```erg -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 -``` - -與許多具有通用語言的語言不同,所有聲明的類型變量必須在偽參數列表(部分)或其他類型變量的參數中使用。這是 Erg 語言設計提出的要求,即所有類型變量都可以從實際參數中推理。因此,不能推理的信息(如返回類型)是從實際參數傳遞的。 Erg 可以從實際參數中傳遞類型。 - - -```erg -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] -``` - -類型變量只能在之間聲明。但是,聲明之後,直到脫離範圍為止,可以在任意場所使用。 - - -```erg -f|X|(x: X): () = - y: X = x.clone() - log X.__name__ - log X - -f 1 -# Int -# -``` - -使用時也可以顯式單相化,如下所示。 - - -```erg -f: Int -> Int = id|Int| -``` - -在這種情況下,指定的類型優先於實際參數類型(否則將導致實際參數類型錯誤的類型錯誤)。也就是說,如果實際傳遞的對象可以轉換為指定的類型,則會進行轉換,否則會導致編譯錯誤。 - - -```erg -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") # TypeError: id|Int| is type `Int -> Int` but got Str -``` - -當這個語法與內含符號擊球時,必須用括起來。 - - -```erg -# {id|Int| x | x <- 1..10}だと{id | ...}だと解釈される -{(id|Int| x) | x <- 1..10} -``` - -不能聲明與已有類型同名的類型變量。這是因為類型變量都是常量。 - - -```erg -I: Type -# ↓ invalid type variable, already exists -f|I: Type| ... = ... -``` - -## 方法定義中的類型參數 - -缺省情況下,左側的類型參數被視為綁定變量。 - - -```erg -K(T: Type, N: Nat) = ... -K(T, N). - foo(x) = ... -``` - -如果使用不同的類型變量名稱,則會發出警告。 - - -```erg -K(T: Type, N: Nat) = ... -K(U, M). # Warning: K's type variable names are 'T' and 'N' - foo(x) = ... -``` - -常量在定義後的所有命名空間中都是相同的,因此也不能用於類型變量名稱。 - - -```erg -N = 1 -K(N: Nat) = ... # NameError: N is already defined - -L(M: Nat) = ... -# M == N == 1のときのみ定義される -L(N). - foo(self, x) = ... -# 任意のM: Natに対して定義される -L(M). - .bar(self, x) = ... -``` - -雖然不能為每個類型參數定義多個參數,但可以定義同名的方法,因為沒有指定類型參數的從屬類型(非原始卡印)和已指定類型參數的從屬類型(原始卡印)沒有關係。 - - -```erg -K(I: Int) = ... -K. - # Kは真の型(原子カインド)ではないので、メソッドを定義できない - # これはメソッドではない(スタティックメソッドに近い) - foo(x) = ... -K(0). - foo(self, x): Nat = ... -``` - -## 全稱型 - -在上一章中定義的函數可以是任何類型。那麼,“函數本身的類型”是什麼呢? - - -```erg -print! classof(id) # |T: Type| T -> T -``` - -得到了的類型。這被稱為,相當於 ML 中以形式提供的類型,Haskell 中以形式提供的類型。為什麼要加上“閉合”這個形容詞,後面會講到。 - -封閉的全稱類型是有限制的,只能將子程序類型全稱化,即只能將其置於左側子句中。但這已經足夠了。在 Erg 中,子程序是最基本的控制結構,因此當“想要處理任意 X”時,即“想要能夠處理任意 X 的子程序”。所以,全稱型和多相關數型是一個意思。以後基本上把這種類型稱為多相關數類型。 - -與無名函數一樣,多相關數類型具有類型變量名稱的任意性,但它們都是等值的。 - - -```erg -assert (|T: Type| T -> T) == (|U: Type| U -> U) -``` - -在 Lambda 計算中,當α等值時,等號成立。由於類型運算存在一些限制,因此始終可以確定等價性(除非考慮終止性)。 - -## 多相關數類型的部分類型 - -多相關數類型可以是任何函數類型。這意味著它與任何函數類型具有子類型關係。讓我們來詳細了解一下這種關係。 - -這樣的“類型變量在左邊定義並在右邊使用的類型”稱為。與此相對,等“類型變量在右邊定義和使用的類型”稱為。 - -打開了的全稱型,成為同形的全部的“真的型”的超級型。相反,封閉的全稱類型是所有相同類型的“真實類型”的子類型。 - - -```erg -(|T: Type| T -> T) < (Int -> Int) < (T -> T) -``` - -最好記住關閉的小/打開的大。但怎麼會。為了更好地理解每一個實例。 - - -```erg -# 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 - -# 多相関數をそのまま返す -id_poly_fn(f2: (|T| T -> T)): (|T| T -> T) = f -# id_poly_fn(id) == id -id_poly_fn(iid) # TypeError - -# Int型関數をそのまま返す -id_int_fn(f3: Int -> Int): (Int -> Int) = f -# id_int_fn(id) == id|Int| -# id_int_fn(iid) == iid -``` - -類型的可以賦給類型的參數,因此可以認為是。相反,類型的不能賦給類型的參數,但它是,因為它可以賦給類型的參數。因此,確實是。 - -## 全稱和依賴關係 - -依存型和全稱型(多相關數型)有什麼關係,有什麼不同呢?依賴類型是一種採用參數的類型,而全稱類型是一種為參數提供任意性的類型(在要全稱的子程序中)。 - -重要的是,封閉的全稱類型本身沒有類型參數。例如,多相關數類型是取多相關數的類型,其定義是封閉的。不能使用該類型參數定義方法等。 - -在 Erg 中,類型本身也是一個值,因此採用參數的類型(例如函數類型)也必須是一個依賴類型。也就是說,多相關數類型既是全稱類型,也是依存類型。 - - -```erg -PolyFn = Patch(|T| T -> T) -PolyFn. - type self = T # NameError: cannot find 'T' -DepFn T = Patch(T -> T) -DepFn. - type self = - log "by DepFn" - T - -assert (Int -> Int).type() == Int # by DepFn -assert DepFn(Int).type() == Int # by DepFn -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/16_subtyping.md b/doc/zh_TW/syntax/type/16_subtyping.md deleted file mode 100644 index 7b2779ad..00000000 --- a/doc/zh_TW/syntax/type/16_subtyping.md +++ /dev/null @@ -1,80 +0,0 @@ -# 部分定型 - -在 Erg 中,可以使用比較運算符和來確定類之間的包含關係。 - - -```erg -Nat < Int -Int < Object -1.._ < Nat -{1, 2} > {1} -{=} > {x = Int} -{I: Int | I >= 1} < {I: Int | I >= 0} -``` - -請注意,它與運算符的含義不同。它聲明左側類是右側類型的子類型,並且僅在編譯時有意義。 - - -```erg -C <: T # T: StructuralType -f|D <: E| ... - -assert F < G -``` - -對於多相類型的子類型規範,例如,也可以指定。 - -## 結構類型,類類型關係 - -結構類型是用於實現結構定型的類型,如果結構相同,則將其視為相同的對象。 - - -```erg -T = Structural {i = Int} -U = Structural {i = Int} - -assert T == U -t: T = {i = 1} -assert t in T -assert t in U -``` - -相反,類是用於實現記名類型的類型,不能在結構上比較類型和實例。 - - -```erg -C = Class {i = Int} -D = Class {i = Int} - -assert C == D # TypeError: cannot compare classes -c = C.new {i = 1} -assert c in C -assert not c in D -``` - -## 子程序的局部類型 - -子程序的參數和返回值只採用單個類。也就是說,不能將結構型和trait作為函數的類型直接指定。必須使用子類型指定將其指定為“作為該類型子類型的單個類”。 - - -```erg -# OK -f1 x, y: Int = x + y -# NG -f2 x, y: Add = x + y -# OK -# Aは何らかの具體的なクラス -f3 x, y: A = x + y -``` - -子程序的類型推論也遵循這個規則。當子程序中的變量中有未明示類型時,編譯器首先檢查該變量是否為某個類的實例,如果不是,則從作用域中的trait中尋找適合的變量。即使這樣也找不到的話,就成為編譯錯誤。這個錯誤可以通過使用結構型來消除,但是推論無名型有可能是程序員不想要的結果,所以設計成程序員明確地用來指定。 - -## 上傳類 - - -```erg -i: Int -i as (Int or Str) -i as (1..10) -i as {I: Int | I >= 0} -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/17_type_casting.md b/doc/zh_TW/syntax/type/17_type_casting.md deleted file mode 100644 index d2bb27b3..00000000 --- a/doc/zh_TW/syntax/type/17_type_casting.md +++ /dev/null @@ -1,74 +0,0 @@ -# cast - -## 上投 - -Python 沒有 cast 的概念,因為它採用烤鴨打字的語言。不需要上播,基本上也沒有下播。但是,由於 Erg 是靜態輸入的,因此可能需要強制轉換。一個簡單的例子是。 Erg 的語言規範沒有定義(Int,Ratio),即 Int( <:Add(Ratio,Ratio))的運算。這是因為將 1 上傳到 Ratio 的實例 1.0。 - -~~Erg 擴展字節碼將類型信息添加到 BINARY_ADD 中,其中類型信息為 Ratio-Ratio。在這種情況下,BINARY_ADD 指令將轉換 Int,因此不會插入指定轉換的特殊指令。因此,例如,如果在子類中覆蓋了某個方法,但將父項指定為類型,則會強制類型(type coercion)並在父項方法中執行(在編譯時進行名稱限定以引用父項方法)。編譯器只執行強制類型驗證和名稱限定。運行時不會強制轉換對象(當前)。可能會實現強制轉換指令以進行執行優化。 ~~ - - -```erg -@Inheritable -Parent = Class() -Parent. - greet!() = print! "Hello from Parent" - -Child = Inherit Parent -Child. - # オーバーライドする際にはOverrideデコレータが必要 - @Override - greet!() = print! "Hello from Child" - -greet! p: Parent = p.greet!() - -parent = Parent.new() -child = Child.new() - -greet! parent # "Hello from Parent" -greet! child # "Hello from Parent" -``` - -此行為不會導致與 Python 的不兼容。 Python 最初不為變量指定類型,因此所有變量都以類型變量輸入。由於類型變量選擇最小匹配類型,因此如果 Erg 不指定類型,則會實現與 Python 相同的行為。 - - -```erg -@Inheritable -Parent = Class() -Parent. - greet!() = print! "Hello from Parent" - -Child = Inherit Parent -Child. - greet!() = print! "Hello from Child" - -greet! some = some.greet!() - -parent = Parent.new() -child = Child.new() - -greet! parent # "Hello from Parent" -greet! child # "Hello from Child" -``` - -對於具有繼承關係的類型,和是自動實現的,你也可以使用它們。 - - -```erg -assert 1 == 1.0 -assert Ratio.from(1) == 1.0 -assert 1.into() == 1.0 -``` - -## 下鑄 - -降播通常是不安全的,轉換方式也不是顯而易見的,而是通過實現來實現。 - - -```erg -IntTryFromFloat = Patch Int -IntTryFromFloat. - try_from r: Float = - if r.ceil() == r: - then: r.ceil() - else: Error "conversion failed" -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/18_mut.md b/doc/zh_TW/syntax/type/18_mut.md deleted file mode 100644 index 04fc609c..00000000 --- a/doc/zh_TW/syntax/type/18_mut.md +++ /dev/null @@ -1,168 +0,0 @@ -# 可變類型(Mutable Type) - -> :本節中的信息過時,並且包含一些錯誤。 - -缺省情況下,Erg 將所有類型設置為不可變類型,即不能更新內部狀態。但你當然可以定義可變類型。變量類型聲明為。 - - -```erg -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 -``` - -確切地說,以可變類型或包含可變類型的複雜類型為基本類型的類型必須在類型名稱後加上。沒有的類型也可以存在於同一命名空間中,並被視為不同的類型。在上面的示例中,屬性是可變的,而屬性是不變的。如果有一個屬性是可變的,則整個屬性都是可變的。 - -變量類型可以定義用於重寫實例的過程方法,但具有過程方法並不一定意味著它是變量類型。例如,數組類型實現了隨機選擇元素的方法,當然這不會對數組進行破壞性更改。 - -可變對象的破壞性操作主要通過方法進行。方法是一個高級過程,它通過將函數應用到來更新它。 - - -```erg -i = !1 -i.update! old -> old + 1 -assert i == 2 -``` - -方法只會將舊內容替換為新值。這是。 - - -```erg -i = !1 -i.set! 2 -assert i == 2 -``` - -方法在不更改值的情況下執行操作。 - - -```erg -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) -``` - -在多相不變類型中,假定類型的類型參數隱式不變。 - - -```erg -# ImmutType < Type -K T: ImmutType = Class ... -K! T: Type = Class ... -``` - -在標準庫中,可變類型通常基於不變類型。但是,類型和類型在語言上沒有特殊的關聯,不需要這樣配置。 - -請注意,有幾種類型的對象可變性。下面我們將討論內置集合類型的不可變/可變類型的含義。 - - -```erg -# 配列型 -## 不変型(immutable types) -[T; N] # 可変操作は実行できない -## 可変型(mutable types) -[T!; N] # 中身を1つずつ変更できる -[T; !N] # 可変長、中身は変更不能だが要素の追加・削除で実質変更可能 -[!T; N] # 中身は不変オブジェクトだが、型を変えたものに差し替え可能(型を変えないという操作で実質差し替え可能) -[!T; !N] # 型、長さを変更可能 -[T!; !N] # 中身、長さを変更可能 -[!T!; N] # 中身、型を変更可能 -[!T!; !N] # ありとあらゆる可変操作を実行できる -``` - -當然,你沒有必要把所有這些都背下來,熟練使用。對於可變數組類型,只需在想要可變的部分加上,在實際應用中,四個可以覆蓋大多數情況。 - -這些排列類型是语法糖,實際類型如下: - - -```erg -# 実際は4種類の型 -[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) -``` - -另外,可以更改類型就是這樣的意思。 - - -```erg -a = [1, 2, 3].into [!Nat; 3] -a.map!(_ -> "a") -a: [!Str; 3] -``` - -其他收藏類型也是如此。 - - -```erg -# タプル型 -## 不変型(immutable types) -(T, U) # 要素數不変、中身を変更できない -## 可変型(mutable types) -(T!, U) # 要素數不変、最初の要素は変更できる -(T, U)! # 要素數不変、中身を差し替えられる -... -``` - - -```erg -# セット型 -## 不変型(immutable types) -{T; N} # 不変要素數、中身を変更できない -## 可変型(mutable types) -{T!; N} # 不変要素數、中身を(1つずつ)変更できる -{T; N}! # 可変要素數、中身は変更不能だが、要素の追加削除で実質可能、中の型を変更可能 -{T!; N}! # 可変要素數、中身も変更できる -... -``` - - -```erg -# 辭書型 -## 不変型(immutable types) -{K: V} # 不変長、中身を変更できない -## 可変型(mutable types) -{K: V!} # 不変長、値を(1つずつ)変更できる -{K: V}! # 可変長、中身を変更できないが、要素の追加削除で実質可能、中の型も変更可能 -... -``` - - -```erg -# レコード型 -## 不変型(immutable types) -{x = Int; y = Str} # 中身を変更できない -## 可変型(mutable types) -{x = Int!; y = Str} # xの値を変更できる -{x = Int; y = Str}! # {x = Int; y = Str}のインスタンスならば何でも差し替えられる -... -``` - -當時,僅為的類型稱為簡單結構類型。簡單結構類型(語義上)也可以稱為沒有內部結構的類型。數組,元組,集,字典和記錄類型並非都是簡單結構類型,而 Int 和篩選類型則是簡單結構類型。 - - -```erg -# 篩型 -## 列挙型 -{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}! # 上と全く同じ型、だが上の記法が推奨される -``` - -根據以上說明,可變類型不僅包括自身可變的類型,也包括內部具有的類型可變的類型。類型(如和)是內部變量類型,其內部對像是可變的,而實例本身並不是可變的。 - -對於具有內部結構的類型,可以改變整個對象。它還可以進行局部更改。但是,最好將更改權限限制在局部,因此如果只有可以更改,則最好將其設置為。如果類型沒有內部結構,則該實例只是一個可互換的框。方法不能更改類型。 - ---- - -1類型和類型在語言上沒有特殊關係,這是有意設計。如果存在關聯,則會出現一些不便,例如,如果名稱空間中存在類型/,則無法從另一個模塊引入類型/。此外,與不可變類型相比,可變類型並不是唯一的。當定義時,變量子類型可以是 \ 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 deleted file mode 100644 index 38d5c841..00000000 --- a/doc/zh_TW/syntax/type/19_bound.md +++ /dev/null @@ -1,16 +0,0 @@ -# 類型邊界(Type Bound) - -型界是在型指定上添加條件的東西。實現這一功能的功能是保護(保護節)。除了函數簽名、無名函數簽名之外,篩子型也可以使用該功能。監控記述在返回值型之後。 - -## 謂詞表達式(Predicate) - -可以使用返回的表達式(謂詞表達式)指定變量滿足的條件。只能使用和運算符。編譯時函數有可能在今後的版本中被對應。 - - -```erg -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 deleted file mode 100644 index 813d14b8..00000000 --- a/doc/zh_TW/syntax/type/advanced.md +++ /dev/null @@ -1 +0,0 @@ -以後將進一步解說高級型系統。入門的朋友不看所有的條款也沒問題。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/GADTs.md b/doc/zh_TW/syntax/type/advanced/GADTs.md deleted file mode 100644 index f7aa9bf2..00000000 --- a/doc/zh_TW/syntax/type/advanced/GADTs.md +++ /dev/null @@ -1,68 +0,0 @@ -# Generalized Algebraic Data Types,GADTs - -Erg 可以通過對 Or 類型進行類化來創建廣義代數數據類型(GADTs)。 - - -```erg -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() # RuntimeError: "empty list" -``` - -將作為而不是是因為使用時不需要類型。 - - -```erg -i = List.nil() -_: List Int = cons 1, i -``` - -這裡定義的是 GADTs,但它是一個簡單的實現,沒有真正的 GADTs 價值。例如,如果內容為空,上面的方法將導致運行時錯誤,但可以在編譯時執行此檢查。 - - -```erg -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() # TypeError -``` - -在街頭巷尾經常被說明的 GADTs 的例子,是像以上那樣根據類型能判定內容是否為空的列表。 Erg 提供了更精確的定義長度列表的方法。 - - -```erg -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() # TypeError -print! cons(1, nil).head() # 1 -print! nil.head() # TypeError -``` \ 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 deleted file mode 100644 index fc01a53c..00000000 --- a/doc/zh_TW/syntax/type/advanced/_rank2type.md +++ /dev/null @@ -1,142 +0,0 @@ -# rank-2 多相 - -> :此文檔的信息較舊,通常包含錯誤。 - -在 Erg 中,像等可以接受各種類型的函數,即可以定義多相關數。那麼,能接受多相關數的函數能被定義嗎?例如,這樣的函數(請注意,此定義包含錯誤)。 - - -```erg -# 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)) -``` - -請注意,由於和的類型不同,因此無名函數並不是單相化一次就結束的。需要進行兩次單相化。在至今為止說明的型的範疇中,無法對這樣的函數進行定義。因為型變量中沒有範圍的概念。在此暫時離開類型,確認值水平上的範圍概念。 - - -```erg -arr = [1, 2, 3] -arr.map i -> i + 1 -``` - -上述代碼中的和是不同作用域的變量。因此,它們的生存期是不同的(更短)。 - -到目前為止的類型,所有的類型變量的生存期都是相同的。也就是說,,同時被確定,以後必須不變。反過來說,如果可以將看作“內側範圍”中的類型變量,則可以構成函數。為此準備了。 - - -```erg -# 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") -``` - -形式的類型稱為全稱類型(詳細情況請參照)。至今所見的函數是典型的全稱函數 = 多相關數。 - - -```erg -id x = x -id: |T: Type| T -> T -``` - -全稱型與函數型構建子之間具有特殊的結合規則,根據結合方法的不同,類型的意義完全不同。 - -對此,使用單純的 1 自變量函數進行考慮。 - - -```erg -f1: (T -> T) -> Int | T # 接受任何函數並返回 Int 的函數 -f2: (|T: Type| T -> T) -> Int # 接收多相關並返回 Int 的函數 -f3: Int -> (|T: Type| T -> T) # 一個函數,接受一個 Int 並返回一個封閉的通用函數 -f4: |T: Type|(Int -> (T -> T)) # 同上(首選) -``` - -和相同,而卻不同,這似乎很奇怪。實際上試著構成這種類型的函數。 - - -```erg -# 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 -``` - -應用之後,就會發現其中的差異。 - - -```erg -_ = 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 -``` - -開放的多相關數型特別稱為。任意函數類型有無限個可能性,如,,...等。與此相對,關閉的多相關數類型(返回與參數類型相同的對象)只有一種。這種類型特別稱為。換句話說,可以向傳遞等的 =是多相關數,但是可以向傳遞的只有等 =是多相關數。但是,像這樣的函數的類型明顯與通常的類型不同,需要能夠很好地處理這些的新概念。這就是套路的“檔次”。 - -關於等級的定義,首先,未量化的類型,即,等被認為是“等級 0”。 - - -```erg -# KはOptionなどの多項カインド -R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0) -``` - -其次,將等進行一階全稱量化的類型,或者將其包含在返回值類型中的類型作為“等級 1”。此外,將進行二階全稱量化的類型(以等等級 1 類型為自變量的類型),或將其包含在返回值類型中的類型設為“等級 2”。重複上述操作,定義“秩 N”型。另外,等級 N 型包含 N 以下等級的所有類型。因此,多個等級混合的類型的等級與其中最高的等級相同。 - - -```erg -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 -``` - -讓我們來看幾個例子。 - - -```erg - (|T: Type| T -> T) -> (|U: Type| U -> U) -=> R1 -> R1 -=> R1 -> R2 -=> R2 - -Option(|T: Type| T -> T) -=> Option(R1) -=> K(R1) -=> R1 -``` - -根據定義,是等級 2 型。 - - -```erg -tuple_map: - ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) -=> (R1, R0) -> R0 -=> R1 -> R2 -=> R2 -``` - -在 Erg 中,可以處理到等級 2 為止的類型(等級 N 型包含 N 以下等級的所有類型,因此正確地說 Erg 的類型都是等級 2 型)。如果試圖配置更多類型的函數,則會出現錯誤。例如,將多相關數作為多相關數處理的函數都需要指定其他自變量的類型。另外,不能構成這樣的函數。 - - -```erg -# 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)) -``` - -等級 3 以上的類型在理論上不能決定類型推論的事實已知,類型指定破壞了可以省略的 Erg 的性質,因此被排除。儘管如此,實用需求 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 deleted file mode 100644 index ac32598b..00000000 --- a/doc/zh_TW/syntax/type/advanced/default_param.md +++ /dev/null @@ -1,28 +0,0 @@ -# 具有默認參數的函數類型 - -首先,看默認自變量的使用例。 - - -```erg -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 -``` - -之後的自變量為默認自變量。部分定型規則如下。 - - -```erg -((X, y := Y) -> Z) <: (X -> Z) -((X, y := Y, ...) -> Z) <: ((X, ...) -> Z) -``` - -第 1 個意思是,有默認自變量的函數可以與沒有默認自變量的函數同等看待。第 2 個是可以省略任意的默認自變量的意思。 \ 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 deleted file mode 100644 index 666d477c..00000000 --- a/doc/zh_TW/syntax/type/advanced/erasure.md +++ /dev/null @@ -1,45 +0,0 @@ -# 類型擦除(Type erasure) - -類型擦除是指將指定為類型參數,並故意丟棄該信息。類型擦除是許多具有多相類型的語言的一個功能,但根據 Erg 語法,類型自變量擦除可能更準確。 - -最常見的類型清除類型的示例可能是。在編譯數組時,你可能不知道數組的長度。例如,指向命令行參數的類型為。 Erg 編譯器不知道命令行參數的長度,因此必須放棄關於長度的信息。但是,由於已擦除的類型成為未擦除類型的超類型(e.g.),因此可以接收更多對象。 類型的對象當然可以使用類型的方法,但使用後信息將被清除。因為長度可能已經改變了。如果長度不變,則必須用簽名表示。 - - -```erg -# 配列の長さが変わらないことが保証される関數(sortなど) -f: [T; N] -> [T; N] -# されない関數(filterなど) -g: [T; n] -> [T; _] -``` - -如果類型本身使用,則該類型將上傳至。對於非類型的類型參數(例如,Int 和 Bool 類型),是未定義的參數。 - - -```erg -i: _ # i: Object -[_; _] == [Object; _] == Array -``` - -類型擦除不同於類型省略。一旦清除了類型參數信息,則必須再次斷言才能返回該信息。 - - -```erg -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 不能部分省略類型,而是使用高階卡印多相。 - - -```erg -# collect 是一個接收 kind 的高階 kind 方法 -hk = (1..5).iter().map(i -> i * 2).collect(Array) -hk: Array(Int) -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/existential.md b/doc/zh_TW/syntax/type/advanced/existential.md deleted file mode 100644 index bdc1cc36..00000000 --- a/doc/zh_TW/syntax/type/advanced/existential.md +++ /dev/null @@ -1,39 +0,0 @@ -# 存在類型 - -如果有對應於應有盡有的全稱型,那麼自然會有對應於應有盡有的存在型。存在型並不難。只是你沒有這樣的意識,就已經知道了你的存在型。 - - -```erg -T: Trait -f x: T = ... -``` - -上面的trait被用作存在類型。相反,下面的只是trait,是全稱類型。 - - -```erg -f|X <: T| x: X = ... -``` - -事實上,存在類型被全稱類型所取代。那麼為什麼會存在所謂的存在型呢?首先,正如上面所見,存在類型不涉及類型變量,因此可以簡化類型指定。此外,由於可以移除類型變量,因此可以配置全稱類型,使其超過等級 2。 - - -```erg -show_map f: (|T| T -> T), arr: [Show; _] = - arr.map x -> - y = f x - log y - y -``` - -但是,一看就知道,存在型會忘卻、擴大原來的型,所以不想擴大返回值的型等情況下,需要使用全稱型。相反,只作為參數接收而與返回值無關的類型可以用存在類型來描述。 - - -```erg -# id(1): 我希望它是一個 Int -id|T|(x: T): T = x -# |S <: Show|(s: S) -> () 是多餘的 -show(s: Show): () = log s -``` - -順便說一下,類不稱為存在類型。因為預先決定了成為那個要素的對象。存在型是指滿足某一trait的所有類型,實際上不知道要代入什麼類型。 \ 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 deleted file mode 100644 index b3ba4c6e..00000000 --- a/doc/zh_TW/syntax/type/advanced/keyword_param.md +++ /dev/null @@ -1,26 +0,0 @@ -# 關鍵字參數函數類型 - - -```erg -h(f) = f(y: 1, x: 2) -h: |T: Type|((y: Int, x: Int) -> T) -> T -``` - -帶關鍵字自變量函數的部分定型規則如下所示。 - - -```erg -((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) -``` - -這意味著關鍵詞自變量可以刪除或者替換。但是,兩者不能同時進行。也就是說,不能將轉換為。另外,帶有關鍵詞自變量的只在頂級元組內,排列和嵌套的元組中不帶有關鍵詞自變量。 - - -```erg -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 deleted file mode 100644 index cbc76120..00000000 --- a/doc/zh_TW/syntax/type/advanced/kind.md +++ /dev/null @@ -1,157 +0,0 @@ -# kind(Kind) - -Erg 中全部都是定型的。套路本身也不例外。表示“類型的類型”的是。例如,屬於屬於是最簡單的kind。在型理論性的記法中,相對應。 - -在kind這個概念中,實用上重要的是一項以上的kind(多項kind)。 1 項的kind度,例如等屬於它。 1 項kind度表示為等的是特別將類型作為自變量的多項關係。正如這一表記所示,實際上是接受這一類型並返回這一類型的函數。但是,由於該函數不是通常意義上的函數,因此通常被稱為 1 項kind(unary kind)。 - -另外,作為無名函數運算符的本身也可以看作是接收類型並返回類型時的關係。 - -另外,請注意,非原子kind的kind不是套路。就像是數值但不是數值一樣,是類型但不是類型。等有時也被稱為類型構建子。 - - -```erg -assert not Option in Type -assert Option in Type -> Type -``` - -因此,下面的代碼會出現錯誤。在 Erg 中可以定義方法的只有原子kind度,方法的第一自變量以外的地方不能使用這個名字。 - - -```erg -# K is an unary kind -K: Type -> Type -K T = Class ... -K. - foo x = ... # OK,這就像是所謂的靜態方法 - bar self, x = ... # TypeError: cannot define a method to a non-type object -K(T). - baz self, x = ... # OK -``` - -二進製或更高類型的示例是 `{T: U}`(: `(Type, Type) -> Type`), `(T, U, V)`(: `(Type, Type, Type) - > Type `), ... 等等。 - -還有一個零項類型`() -> Type`。這有時等同於類型論中的原子類型,但在 Erg 中有所區別。一個例子是“類”。 - - -```erg -Nil = Class() -``` - -## kind包含關係 - -多項關係之間也有部分型關係,原來部分關係。 - - -```erg -K T = ... -L = Inherit K -L <: K -``` - -也就是說,對於任何,都是,反之亦然。 - - -```erg -∀T. L T <: K T <=> L <: K -``` - -## 高階kind - -還有一種叫做高階kind(higher-order kind)。這是與高階函數相同概念的kind,是接受kind本身的kind。等是高階kind度。嘗試定義屬於高階kind度的對象。 - - -```erg -IntContainerOf K: Type -> Type = K Int -assert IntContainerOf Option == Option Int -assert IntContainerOf Result == Result Int -assert IntContainerOf in (Type -> Type) -> Type -``` - -多項kind度的約束變量通常表示為 K,L,...等(K 是 Kind 的 K)。 - -## 套管 - -在型理論中,有一個叫做記錄的概念。這與 Erg 的記錄基本相同。 - - -```erg -# This is a record, and it corresponds to what is called a record in type theory -{x = 1; y = 2} -``` - -當記錄的值全部為類型時,它被稱為記錄類型,是類型的一種。 - - -```erg -assert {x = 1; y = 2} in {x = Int; y = Int} -``` - -記錄類型用於輸入記錄。善於體諒的人可能會認為,應該有“唱片kind”來定型唱片型。實際上,它是存在的。 - - -```erg -log Typeof {x = Int; y = Int} # {{x = Int; y = Int}} -``` - -像這樣的類型就是唱片kind。這不是特別的記法。它是只以為要素的枚舉型。 - - -```erg -Point = {x = Int; y = Int} -Pointy = {Point} -``` - -記錄kind的重要特性在於,當時,。這從列舉型實際上是篩子型的糖衣句法就可以看出。 - - -```erg -# 通常のオブジェクトでは{c} == {X: T | X == c}だが、 -# 型の場合等號が定義されない場合があるので|T| == {X | X <: T}となる -{Point} == {P | P <: Point} -``` - -型限制中的實際上是的糖衣句法。這種類型的組套即kind一般被稱為組套kind。設定kind也出現在 Iterator 模式中。 - - -```erg -Iterable T = Trait { - .Iterator = {Iterator} - .iter = Self(T).() -> Self.Iterator T -} -``` - -## 多項關係型推理 - - -```erg -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() # どれが選択される? -``` - -在上面的例子中,方法選擇哪個補丁呢?簡單地說,被認為是可以選擇的,但也有可能,包含的原樣,因此任意類型都適用,也是,即相匹配。因此,上面的 4 個補丁都可以作為選擇。 - -在這種情況下,根據以下優先標準選擇補丁。 - -* 任何(e.g.)比優先匹配。 -* 任何(e.g.)比優先匹配。 -* 同樣的標準適用於 3 項以上的kind度。 -* 選擇替換類型變量較少的變量。例如,優先匹配(替換類型變量:T),而不是(替換類型變量:K,T)或(替換類型變量:T,U)。 -* 如果替換數相同,則錯誤為“無法選擇”。 - ---- - -在1型理論的記法中 - -2存在可視性等微妙的差異。 \ 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 deleted file mode 100644 index 45ee62dd..00000000 --- a/doc/zh_TW/syntax/type/advanced/marker_trait.md +++ /dev/null @@ -1,33 +0,0 @@ -# Marker Trait - -標記托盤是沒有要求屬性的托盤。也就是說,不安裝方法就可以 Impl。如果沒有要求屬性的話,似乎就沒有意義了,但是因為登錄了屬於該trait的信息,所以可以使用補丁方法,編譯器進行特別處理。 - -所有標記塊都包含在塊中。標準中提供的是一種標記托盤。 - - -```erg -Light = Subsume Marker -``` - - -```erg -Person = Class {.name = Str; .age = Nat} and Light -``` - - -```erg -M = Subsume Marker - -MarkedInt = Inherit Int, Impl := M - -i = MarkedInt.new(2) -assert i + 1 == 2 -assert i in M -``` - -也可以用自變量來排除標記類。 - - -```erg -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 deleted file mode 100644 index ca40b905..00000000 --- a/doc/zh_TW/syntax/type/advanced/mut_struct.md +++ /dev/null @@ -1,40 +0,0 @@ -# 可變結構類型 - -型是可以插入任意的型對象進行替換的箱型。 - - -```erg -Particle! State: {"base", "excited"}! = Class(..., Impl := Phantom State) -Particle!. - # このメソッドはStateを"base"から"excited"に遷移させる - apply_electric_field!(ref! self("base" ~> "excited"), field: Vector) = ... -``` - -型雖然可以進行數據的替換,但不能改變其結構。如果用更接近現實的程序行為的說法,(堆上的)大小不能變更。這種類型稱為不變結構(可變)類型。 - -實際上,存在不變結構型無法表示的數據結構。例如,可變長度排列。型可以加入任意的對象,但不能替換為型對像等。 - -也就是說,長度不能改變。為了改變長度,必須改變型本身的結構。 - -實現那個的是可變結構(可變)型。 - - -```erg -v = [Str; !0].new() -v.push! "Hello" -v: [Str; !1] -``` - -在可變結構型中,在可變化的類型自變量上添加。在上述情況下,可以將型改為型等。也就是說,可以改變長度。順便一提,型是型的糖衣句法。 - -可變結構型當然也可以用戶定義。但是,需要注意的是,與不變結構型在構成法方面有幾個不同。 - - -```erg -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} -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/newtype.md b/doc/zh_TW/syntax/type/advanced/newtype.md deleted file mode 100644 index 05bca287..00000000 --- a/doc/zh_TW/syntax/type/advanced/newtype.md +++ /dev/null @@ -1,31 +0,0 @@ -# Newtype pattern - -下面是 Rust 常用的 newtype 模式的 Erg 版本。 - -Erg 可以按如下方式定義類型別名,但僅指同一類型。 - - -```erg -UserId = Int -``` - -因此,例如,即使類型的數值是 8 位正數,因為它與類型相同,所以可以輸入 10 或-1. 如果,-1 是可以彈的,但是 8 位數的性質僅用 Erg 的類型系統是不能表現的。 - -再比如設計某個數據庫的系統時,有幾類 ID。隨著 ID 類型的增加,例如用戶 ID,商品 ID,訂單 ID 等,可能會出現錯誤,即向函數傳遞不同類型的 ID。用戶 ID 和商品 ID 等即使在結構上等價,在語義上也是不同的。 - -newtype 模式是這種情況下的理想設計模式。 - - -```erg -UserId = Class {id = Nat} -UserId. - new id: Nat = - assert id.dights().len() == 8, else: "UserId must be a positive number with length 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 位數的先決條件。由於丟失了的所有方法,因此必須重新定義每次所需的運算。如果重新定義的成本不相稱,最好使用繼承。相反,你可能希望使用沒有方法的特性,因此請根據具體情況選擇適當的方法。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/overloading.md b/doc/zh_TW/syntax/type/advanced/overloading.md deleted file mode 100644 index 86080fb5..00000000 --- a/doc/zh_TW/syntax/type/advanced/overloading.md +++ /dev/null @@ -1,91 +0,0 @@ -# 過載 - -Erg 不支持。也就是說,不能對函數卡印進行多重定義(過載)。但是,通過組合trait類和補丁,可以再現過載的行為。可以使用trait而不是trait類,但在這種情況下,安裝的所有類型都成為對象。 - - -```erg -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 -``` - -這種通過接受某一類型的所有亞型而產生的多相稱為。 Erg 中的亞分型多相也包括列多相。 - -如果各型的處理完全相同,也可以寫如下。上面的寫法用於不同類的行為(但返回類型相同)。使用類型參數的多相稱為。參數多相與如下所示的部分型指定並用的情況較多,這種情況下是參數多相和子分型多相的組合技術。 - - -```erg -add1|T <: Int or Str| x: T = x + 1 -assert add1(1) == 2 -assert add1(1.0) == 2.0 -``` - -另外,自變量數不同類型的過載可以用默認自變量再現。 - - -```erg -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 禁止過載而採用亞分 + 參數多相是出於以下原因。 - -首先,被超載的函數的定義是分散的。因此,發生錯誤時很難報告原因所在。另外,通過導入子程序,可能會改變已經定義的子程序的行為。 - - -```erg -{id; ...} = import "foo" -... -id x: Int = x -... -id x: Ratio = x -... -id "str" # TypeError: id is not implemented for Str -# But... where did this error come from? -``` - -其次,與默認參數不匹配。當有默認參數的函數被重載時,存在哪個優先的問題。 - - -```erg -f x: Int = ... -f(x: Int, y := 0) = ... - -f(1) # which is chosen? -``` - -再者,與宣言不相匹配。聲明無法確定指的是哪一個定義。因為沒有包含關係。 - - -```erg -f: Num -> Num -f(x: Int): Ratio = ... -f(x: Ratio): Int = ... -``` - -而且,破壞語法的連貫性。雖然 Erg 禁止變量的再代入,但是過載的語法看起來像是再代入。也不能替換為無名函數。 - - -```erg -# same as `f = x -> body` -f x = body - -# same as... what? -f x: Int = x -f x: Ratio = x -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/phantom.md b/doc/zh_TW/syntax/type/advanced/phantom.md deleted file mode 100644 index 3c6d3c46..00000000 --- a/doc/zh_TW/syntax/type/advanced/phantom.md +++ /dev/null @@ -1,58 +0,0 @@ -# 幽靈類型(Phantom class) - -幽靈型是只為給編譯器註釋而存在的標記trait。作為幽靈型的使用方法,來看清單的構成。 - - -```erg -Nil = Class() -List T, 0 = Inherit Nil -List T, N: Nat = Class {head = T; rest = List(T, N-1)} -``` - -這個代碼是錯誤的。 - - -```erg -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 -hint: use 'Phantom' trait to consume T -``` - -這個錯誤也就是當時不能進行的類型推論。在 Erg 中,類型自變量不能保持未使用狀態。在這種情況下,無論什麼都可以,所以必須在右邊消耗型。如果大小為 0 的類型,例如長度為 0 的元組,則運行時沒有開銷,非常方便。 - - -```erg -Nil T = Class((T; 0)) -List T, 0 = Inherit Nil T -List T, N: Nat = Class {head = T; rest = List(T, N-1)} -``` - -這個代碼通過編譯。但是有點棘手,意圖很難理解,而且除了類型自變量是類型以外,不能使用。 - -這種時候正好是幽靈型。幽靈型是將大小為 0 的型一般化的型。 - - -```erg -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 -``` - -保留類型。但是實際上型的大小為 0,沒有保存型的對象。 - -另外,除了類型以外還可以消耗任意類型自變量。在以下的例子中,保存了這一的子類型對象的類型自變量。這種情況下,也是不出現在對象實體中的哈利波特型變量。 - - -```erg -VM! State: {"stopped", "running"}! = Class(..., Impl := Phantom! State) -VM!("stopped"). - start ref! self("stopped" ~> "running") = - self.do_something!() - self::set_phantom!("running") -``` - -通過方法或方法進行更新。這是的可變版本)標準補丁提供的方法,其用法與可變類型的相同。 \ 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 deleted file mode 100644 index 62566b77..00000000 --- a/doc/zh_TW/syntax/type/advanced/projection.md +++ /dev/null @@ -1,25 +0,0 @@ -# 投影類型 - -投影類型表示以下代碼中類似於的類型。 - - -```erg -Add R = Trait { - .`_+_` = Self, R -> Self.AddO - .AddO = Type -} - -AddForInt = Patch(Int, Impl := Add Int) -AddForInt. - AddO = Int -``` - -類型定義了與某個對象的相加。由於方法應該是類型屬性,因此的類型聲明必須位於縮進下面。 類型的 misso 是聲明,其投影類型類型的實體具有屬於的子類型的類型。例如,。 - - -```erg -assert Int < Add -assert Int.AddO == Int -assert Odd < Add -assert Odd.AddO == Even -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/quantified_dependent.md b/doc/zh_TW/syntax/type/advanced/quantified_dependent.md deleted file mode 100644 index ef0ea90c..00000000 --- a/doc/zh_TW/syntax/type/advanced/quantified_dependent.md +++ /dev/null @@ -1,30 +0,0 @@ -# 量化依賴性 - -Erg 有量化類型和依賴類型。這樣自然就可以把這兩個組合在一起做成模具了。那就是量化依賴型。 - - -```erg -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} -``` - -量化依賴性的標準形式是。其中是類型構建器,是類型參數,是條件表達式。 - -作為左邊值的量化依賴類型只能在與原始類型相同的模塊中定義方法。 - - -```erg -K A: Nat = Class ... -K(A). - ... -K(A | A >= 1). - method ref! self(A ~> A+1) = ... -``` - -量化依賴型作為右邊值,必須在類型變量列表()中聲明要使用的類型變量。 - - -```erg -# Tは具體的な型 -a: |N: Nat| [T; N | N > 1] -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/shared.md b/doc/zh_TW/syntax/type/advanced/shared.md deleted file mode 100644 index 5fa83b6e..00000000 --- a/doc/zh_TW/syntax/type/advanced/shared.md +++ /dev/null @@ -1,72 +0,0 @@ -# 共享引用(Shared Reference) - -共享引用是一種必須小心處理的語言功能。例如,在 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] -``` - -普通會員闖入了貴賓區。這是一個明顯的 bug,有什麼不對呢?原因是共享引用的。 是通過複製而創建的,但其類型已發生變化。但是,由於繼承了,所以被認為是沒有問題的。 關係對於不變對象來說是沒有問題的。但是,如果像上面那樣進行破壞性操作,就會出現破綻。 - -在 Erg 中,由於所有權系統,這些代碼被彈出。 - - -```erg -NormalMember = Class() -VIPMember = Class() - -vip_area = [].into [VIPMember; !_] -normal_area: [NormalMember; !_] = vip_area - -normal_area.push!(NormalMember.new()) -log vip_area # OwnershipError: `vip_room` was moved to `normal_room` -``` - -但是,在某些情況下,只有一個對象的所有權是不方便的。為此,Erg 的類型為,它表示共享狀態。 - - -```erg -$p1 = SharedCell!.new(!1) -$p2 = $p1.mirror!() -$p3 = SharedCell!.new(!1) -# $p1 == $p2 比較內容類型 Int! -assert $p1 == $p2 -assert $p1 == $p3 -# 檢查 `.addr!` 以查看 $p1 和 $p2 是否相同 -assert $p1.addr!() == $p2.addr!() -assert $p1.addr!() != $p3.addr!() -$p1.add! 1 -assert $p1 == 2 -assert $p2 == 2 -assert $p3 == 1 -``` - -類型的對象必須以開頭。此外,由於其性質,它不能是常數。 - -類型也是類型的子類型,可以調用類型的方法。類型特定的方法只有。 - -一個重要的事實是,是非變態的。即,不定義不同類型參數的包含關係。 - - -```erg -$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. -``` - -但是下面的代碼沒有問題。在最後一行中,類型轉換為參數。 - - -```erg -$normal_area = SharedCell!.new([].into [NormalMember; !_]) -$normal_area.push!(NormalMember.new()) # OK -$normal_area.push!(VIPMember.new()) # OK -``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/special.md b/doc/zh_TW/syntax/type/advanced/special.md deleted file mode 100644 index c0d32308..00000000 --- a/doc/zh_TW/syntax/type/advanced/special.md +++ /dev/null @@ -1,54 +0,0 @@ -# 特殊類型(Self,Super) - -表示你的類型。你可以簡單地將其用作別名,但請注意,它在派生類型中的含義是不同的(指你自己的類型)。 - - -```erg -@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 -``` - -表示基類的類型。方法本身引用基類,而實例使用其類型。 - - -```erg -@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 -``` - -## 特殊類型變量 - -和可用作結構化任務中的類型變量。這是屬於該類型子類型的類。也就是說,在類型中,表示。 - - -```erg -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 deleted file mode 100644 index 075c6b74..00000000 --- a/doc/zh_TW/syntax/type/advanced/typeof.md +++ /dev/null @@ -1,61 +0,0 @@ -# Typeof, classof - -是可以窺視 Erg 的類型推理系統的函數,其舉動很複雜。 - - -```erg -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} -``` - -函數返回的不是對象的類,而是結構類型。因此,對於類的實例,則為。關於值類,本來不存在對應的記錄類型。為了解決這個問題,值類是具有屬性的記錄型。此外,不能訪問該屬性,也不能在用戶定義類型中定義屬性。 - - -```erg -i: Int = ... -assert Typeof(i) == {__valueclass_tag__ = Phantom Int} -s: Str = ... -assert Typeof(s) == {__valueclass_tag__ = Phantom Str} -``` - -用輸出的只是結構型。說明了結構型有屬性型、篩子型和(真的)代數演算型。這些是獨立的類型(存在推理的優先順序),不發生推理的重解。屬性型、代數運算型可能跨越多個類,而篩型是單一類的亞型。 Erg 盡可能地將對象的類型作為篩子類型進行推論,當不能進行推論時,將篩子類型的基類擴大到結構化(後述)的類型。 - -## 結構化 - -所有類都可以轉換為結構型。這被稱為。可以通過函數獲取類的結構化類型。如果用定義類(所有類都用這種形式定義),則。 - - -```erg -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 structurized -# 你實際上不能用 __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 deleted file mode 100644 index 37ba9f9e..00000000 --- a/doc/zh_TW/syntax/type/advanced/variance.md +++ /dev/null @@ -1,128 +0,0 @@ -# 退化(variance) - -Erg 可以進行多相型的分型,但是有一部分必須注意的地方。 - -首先考慮通常的多相型的包含關係。一般情況下,存在容器和代入的類型,當時,為。例如,。因此,用定義的方法,也可以使用。 - -考慮典型的多相型型。請注意,這一次不考慮元素的數量,因此不是。那麼,在型中存在的方法,分別表示要素的追加、取出。套路是這樣的。 - -Array.push!: Self(T).(T) => NoneTypeArray.pop!: Self(T).() => T - -我們可以直觀地了解到, - -* 當時OK(將上傳至即可) -* 當時為 NG -* 是 NG -* 好的 - -是。這在類型系統上 - -* (Self(Object).(Object) => NoneType) < (Self(Str).(Str) => NoneType) -* (Self(Str).() => Str) < (Self(Object).() => Object) - -的意思。 - -前者可能看起來很奇怪。雖然是,但將其作為自變量的函數的包含關係卻發生了逆轉。在類型理論中,這種關係(的類型關係)稱為反變(contravariant),相反,的類型關係稱為共變(covariant)。也就是說,可以說函數型是關於自變量的類型的反變,關於返回值的類型的共變。聽起來很複雜,但正如剛才看到的那樣,如果套用實例來考慮的話,這是一個合理的規則。即便如此,如果還不明白的話,可以考慮如下。 - -Erg 的設計方針中有“輸入的類型大,輸出的類型小”。這可以從函數的變性說起。從上面的規則來看,輸入型是大的一方整體來說是小的類型。因為通用函數明顯比專用函數稀少。而且輸出型越小整體越小。 - -結果上面的方針等於說“函數的類型最小化”。 - -## 過錯變性 - -Erg 還有一種變性。它是非變性的。這是編入型中等具有的變性。這意味著,關於的 2 個類型,即使存在包含關係,也不能在之間進行轉換。這是因為是共享參照。有關詳細信息,請參見。 - -## 變性指定的全稱類型 - -可以指定全稱類型的類型變量的上限和下限。 - - -```erg -|A <: T| K(A) -|B :> T| K(B) -``` - -類型變量列表中的類型變量。在上面的變性說明中,類型變量是類型的任何子類,類型變量是類型的任何超類。此時,也稱為的上限型,的下限型。 - -還可以疊加退化規範。 - - -```erg -# U < A < T -{... | A <: T; A :> U} -``` - -下面是使用變性規範的代碼示例。 - - -```erg -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 -``` - -## 變性指定 - -請注意中的示例,我們將更詳細地討論這些示例。為了了解上面的代碼,我們需要了解多相型的變性。關於變性,我們在中進行了詳細說明,但目前需要的事實有以下三個: - -* 通常的多相型,等對於共變() -* 函數與自變量類型相反(當) -* 函數與返回類型共變(當) - -例如,可以上播到可以上播到。 - -現在,我們將考慮如果省略方法的退化規範會發生什麼情況。 - - -```erg -... -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 -``` - -即使在這種情況下,Erg 編譯器也可以很好地推論的上限和下限類型。但是,請注意,Erg 編譯器並不理解方法的含義。編譯器只是根據變量和類型變量的使用方式機械地推理和推導類型關係。 - -如註釋所示,的類型的子類(如果,則等)。即推論為。此約束禁止更改參數類型的上傳(e.g.)。但是,請注意,約束並沒有改變函數類型的包含關係。 這一事實保持不變,只是不能在方法中執行這樣的上播。同樣,從的轉換在的約束條件下是可能的,因此可以這樣推論退化規範。此約束禁止更改的返回類型的上傳(e.g.)。 - -現在,我想如果我允許這個上傳會發生什麼情況。讓我們來反轉退化規範。 - - -```erg -... -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`. Or you may have the wrong variance specification. -# TypeWarning: `U` in the `.upcast` cannot take anything other than `U == T`. Replace `U` with `T`. Or you may have the wrong variance specification. -``` - -只有當同時滿足約束和退化規範時,才能滿足。因此,此指定幾乎沒有任何意義。實際上,只允許“上播,如”=“上播,不改變”。 - -## Appendix:用戶定義的變體 - -用戶定義類型的變性默認為非變。但是,也可以用這一標記軌跡指定變性。如果指定,則該類型對於是反變的。如果指定,則該類型對於為協變。 - - -```erg -K T = Class(...) -assert not K(Str) <= K(Object) -assert not K(Str) >= K(Object) - -InputStream T = Class ..., Impl := Inputs(T) -# Objectを受け入れるストリームは、Strを受け入れるともみなせる -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 deleted file mode 100644 index 1cb10b38..00000000 --- a/doc/zh_TW/syntax/type/advanced/widening.md +++ /dev/null @@ -1,93 +0,0 @@ -# 類型擴展(Type Widening) - -例如定義如下的多相關數。 - - -```erg -ids|T|(x: T, y: T) = x, y -``` - -代入相同類的實例對沒有任何問題。如果代入包含關係中的其他類的實例對的話,就會被上播到較大的一方,成為相同的類型。另外,如果代入不在包含關係中的其他類,就會出現錯誤,這也很容易理解。 - - -```erg -assert ids(1, 2) == (1, 2) -assert ids(1, 2.0) == (1.0, 2.0) -ids(1, "a") # TypeError -``` - -那麼,擁有其他結構型的型的情況又會怎樣呢? - - -```erg -i: Int or Str -j: Int or NoneType -ids(i, j) # ? -``` - -在解釋這一點之前,我們必須注意一個事實,即 Erg 類型系統實際上沒有看到類(在運行時)。 - - -```erg -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 -``` - -之所以沒有看到類,是因為有時不能正確看到,這是因為在 Erg 中對象的類屬於運行時信息。例如,型對象的類是或者,這是哪一個只有執行後才能知道。當然,型的對象的類是由確定的,這時從類型系統中也能看到的結構型。 - -現在,讓我們回到另一個結構類型的例子。從結論上來說,上面的代碼如果沒有類型,就會成為 TypeError。但是,如果用類型註釋進行類型擴大,編譯就可以通過。 - - -```erg -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 -``` - -有以下可能性。 - -* :。 -* :時。 -* :時。 - -有以下可能性。 - -* :時。 -* :。 -* 不能簡化(獨立類型):當時。 - -## 子例程定義中的類型擴展 - -在 Erg 中,返回值類型不一致時默認為錯誤。 - - -```erg -parse_to_int s: Str = - if not s.is_numeric(): - do parse_to_int::return error("not numeric") - ... # return Int object -# TypeError: mismatch types of return values -# 3 | do parse_to_int::return error("not numeric") -# └─ Error -# 4 | ... -# └ Int -``` - -為了解決這一問題,必須將返回類型顯式指定為 Or 類型。 - - -```erg -parse_to_int(s: Str): Int or Error = - if not s.is_numeric(): - do parse_to_int::return error("not numeric") - ... # return Int object -``` - -這是為了不讓子程序的返回值類型無意中混入其他類型的設計。但是,當返回值類型的選項是或等具有包含關係的類型時,向較大的類型對齊。 \ No newline at end of file diff --git a/doc/zh_TW/tips.md b/doc/zh_TW/tips.md deleted file mode 100644 index 189c8d0e..00000000 --- a/doc/zh_TW/tips.md +++ /dev/null @@ -1,142 +0,0 @@ -# Tips - -## 我想改變錯誤的顯示語言 - -請下載語言版本的 erg。但是,標準庫之外可能不提供多語言支持。 - -## 只想改變記錄的特定屬性 - - -```erg -record: {.name = Str; .age = Nat; .height = CentiMeter} -{height; rest; ...} = record -mut_record = {.height = !height; ...rest} -``` - -## 我要陰影變量 - -Erg 不能在同一範圍內進行陰影。但是,如果作用域變了,就可以重新定義,所以最好使用即時塊。 - - -```erg -# T!型オブジェクトを取得し、最終的にT型として変數へ代入 -x: T = - x: T! = foo() - x.bar!() - x.freeze() -``` - -## 想辦法重用 final class(不可繼承類) - -我們來做個說唱班。這就是所謂的合成模式。 - - -```erg -FinalWrapper = Class {inner = FinalClass} -FinalWrapper. - method self = - self::inner.method() - ... -``` - -## 要使用非字符串枚舉類型 - -你可以定義其他語言中常見的傳統枚舉類型(代數數據類型),如下所示。當實現時,類和實例是等同的。此外,如果使用,則可選擇的類型將自動定義為重定向屬性。 - - -```erg -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;} -> ... -``` - - -```erg -Status = Enum Ok, Err, ErrWithInfo -# is equivalent to -Status = Class Ok or Err or ErrWithInfo -Status. - Ok = Ok - Err = Err - ErrWithInfo = ErrWithInfo -``` - -## 一開始想要 enumerate - -method 1: - - -```erg -arr = [...] -for! arr.iter().enumerate(start: 1), i => - ... -``` - -method 2: - - -```erg -arr = [...] -for! arr.iter().zip(1..), i => - ... -``` - -## 我想測試我的私有 API(白盒) - -名為的模塊可以專門訪問的專用 API。 模塊不能導入,因此保持了隱藏性。 - - -```erg -# foo.er -private x = ... -``` - - -```erg -# foo.test.er -foo = import "foo" - -@Test -'testing private' x = - ... - y = foo::private x - ... -``` - -## 要定義外部只讀(可變)屬性 - -最好將屬性設為私有,然後定義 getta。 - - -```erg -C = Class {v = Int!} -C:: - inc_v!(ref! self) = self::v.inc!() - ... -C. - get_v(ref self): Int = self::v.freeze() - ... -``` - -## 要在類型系統上標識參數名稱 - -將參數作為記錄接收比較好。 - - -```erg -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 警告的選項(這是故意的設計)。重寫代碼。 \ No newline at end of file diff --git a/doc/zh_TW/tools/build.md b/doc/zh_TW/tools/build.md deleted file mode 100644 index bb87c146..00000000 --- a/doc/zh_TW/tools/build.md +++ /dev/null @@ -1,13 +0,0 @@ -# build 子命令 - -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 deleted file mode 100644 index f1dfa9ac..00000000 --- a/doc/zh_TW/tools/env.md +++ /dev/null @@ -1,3 +0,0 @@ -# env 子命令 - -env 子命令指定 erg 執行環境。在中創建新的運行時環境。當交互工具打開並指定 erg 版本時,將安裝該版本的 erg(如果已安裝,則將其用作新環境)。你可以在中切換環境。創建的環境可以在中進行編輯,可以預安裝軟件包或指定其他語言的依賴關係。該命令的最大特徵是可以將在中再現環境的信息作為文件輸出。據此,可以在與他人相同的環境下馬上開始開發。並且,在中,可以像軟件包那樣公開環境。 \ No newline at end of file diff --git a/doc/zh_TW/tools/fmt.md b/doc/zh_TW/tools/fmt.md deleted file mode 100644 index 654c1b18..00000000 --- a/doc/zh_TW/tools/fmt.md +++ /dev/null @@ -1,5 +0,0 @@ -# fmt - -fmt 子命令允許在中設置代碼格式。以下是常用的旗幟。 - -* explicit-type:自動完成省略類型的位置。 \ No newline at end of file diff --git a/doc/zh_TW/tools/index.md b/doc/zh_TW/tools/index.md deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/zh_TW/tools/install.md b/doc/zh_TW/tools/install.md deleted file mode 100644 index 669093d5..00000000 --- a/doc/zh_TW/tools/install.md +++ /dev/null @@ -1,9 +0,0 @@ -# install 子命令 - -install 可以安裝在註冊表站點註冊的軟件包。基本用法與包管理器(如 cargo)相同。 - -## 方便的功能 - -* 如果有名字相似的軟件包名稱,並且下載量比那個多 10 倍以上,就會出現錯誤輸入的提示。由此,可以防止 typo squatting。 -* 如果軟件包大小很大(50 MB 或更大),請查看大小以確定是否安裝。 -* 如果軟件包為 duplicated,則提示替換軟件包。 \ No newline at end of file diff --git a/doc/zh_TW/tools/pack.md b/doc/zh_TW/tools/pack.md deleted file mode 100644 index 97f4fc64..00000000 --- a/doc/zh_TW/tools/pack.md +++ /dev/null @@ -1,82 +0,0 @@ -# 包管理器 - -Erg 標配包管理器,可通過子命令調用。以下是典型的選項。 - -* :將當前目錄初始化為軟件包。生成文件和目錄。指定是可執行文件的軟件包,指定是庫的軟件包,指定是兩個軟件包。如果指定,它將自動放置許可證文件。 -* :構建包。執行測試並進行優化。工件配置在或。 -* :安裝軟件包。對於庫,被放置在以下,應用程序被放置在作為 shell 腳本。添加時進行最優化。 -* :構建軟件包並運行應用程序(僅限 app 軟件包)。 -* 刪除:build 目錄中的內容。 -* :測試軟件包。有關詳細信息,請參見。 -* :發布/發佈軟件包。我需要 GitHub 帳戶和公鑰。 - -另外,本文檔說明了管理自己的軟件包時的方法。要安裝或搜索外部軟件包,請參閱。此外,有關 Erg 的封裝系統,請參見。 - -## 整個軟件包的標準目錄配置(適用於應用程序軟件包) - - -```console -/package # パッケージのルートディレクトリ - /build # ビルド結果を格納するディレクトリ - /debug # デバッグビルド時の成果物 - /release # リリースビルド時の成果物 - /doc # ドキュメント(さらに`en`, `ja`などのサブディレクトリに分けることで各國語対応可能) - /src # ソースコード - /main.er # main関數を定義するファイル - /tests # (ブラックボックス)テストファイルを格納するディレクトリ - /package.er # パッケージの設定を定義するファイル -``` - -## package.er - -如果,就會生成以下文件中記述了軟件包的設定。以下是的記述例子。 - - -```erg -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) -``` - -## 語義 - -Erg 軟件包根據指定版本。語義版本化通常以格式指定,其中 x,y 和 z 是大於或等於 0 的整數。每個數字的含義如下。 - -* x:主要版本(增加一個,以進行破壞兼容性的更新) -* y:次要版本(兼容更新(如 API 添加或過時)時增加 1;補丁版本升級(如錯誤修復) -* z:修補程序版本(錯誤修復和兼容性較小的更改增加 1;嚴重的不兼容修復將在主要版本升級中提供) - -但是,在默認情況下,對版本的更改始終不兼容。如果你想在版本升級時保持兼容性,請在後面指定(Erg 自己的規則)。例如,如果你想添加,同時兼容,即升級到,請指定。如果已修復錯誤,請指定。這將確保該版本與上一版本兼容。如果你想將升級為,也可以使用此選項。也就是說,與上一個版本兼容。 - -語義版本化在生成鎖定文件時非常重要。鎖定文件是為保持相關軟件包的兼容性而生成的文件,它依賴於舊軟件包,除非明確更新相關軟件包的新版本。當多人開發具有相關軟件包的軟件包時,鎖定文件非常有用。它還可以節省本地存儲,因為相關軟件包可以在兼容的情況下使用更多相關軟件包。 - -Erg 軟件包管理器嚴格執行以上規則,任何與規則相衝突的軟件包更新都將被拒絕。 Erg 包管理器與版本控制系統(如 git)配合使用,在 publish 包時檢測代碼差異,以驗證版本化的有效性。具體地說,包管理器看 API 的類型。如果類型是舊版本的子類型,則將更改視為兼容(請注意,這不是完全驗證。可能存在類型上兼容但語義上不兼容的更改。這是開發人員的工作。 - -此外,由於軟件包在註冊表中註冊了整個存儲庫,因此開發人員不能在不通過軟件包管理器的情況下更新軟件包。此外,軟件包可以過時,但不能刪除。 - -### Appendix:語義版本化問題及其對策 - -語義版本化中存在(至少)兩個已知問題。首先,語義版本化可能會施加過大的限制。在語義版本化中,只有一個不兼容的 API 更改會提升整個包的主要版本。這會導致“我想嘗試一個新的 API,但因為我必須處理另一個不兼容的 API 更改而推遲升級”。還有一點,語義版本可能承諾過高。如上一節所述,API 的“兼容更改”在理論上無法證明。如果你指定要版本的軟件包,則從語義版本的角度來看,可以使用大於或等於小於的所有軟件包(不能使用)。但是,實際上,軟件包開發人員無意中使用 API 可能會導致構建不成功。 - -為了解決這個問題,Erg 採取了一種方法,允許你同時使用不同版本的軟件包(通過重命名)。這允許你在引入部分版本 2 的 API 的同時繼續使用版本 1 的 API。此外,雖然不是很理想,但如果只有某些次要版本的 API 可以在沒有錯誤的情況下使用,則可以將其保留到下一個版本。 - -## publish - -可以使用子命令發佈軟件包。我需要一個 GitHub 賬戶來發表。缺省情況下,軟件包註冊為。如果滿足一定的條件(下載數量,維護頻率等),則可以申請註冊省略所有者名稱的別名。軟件包名稱不區分大小寫和分隔符,如。 \ No newline at end of file diff --git a/doc/zh_TW/tools/repl.md b/doc/zh_TW/tools/repl.md deleted file mode 100644 index 4a5267dc..00000000 --- a/doc/zh_TW/tools/repl.md +++ /dev/null @@ -1,15 +0,0 @@ -# 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 deleted file mode 100644 index eb9d4ce0..00000000 --- a/doc/zh_TW/tools/test.md +++ /dev/null @@ -1,43 +0,0 @@ -# test 子命令 - -erg 指令中有 test 這個子指令,進行測試安裝以及執行的支援。 - -## 測試裝飾器(@Test) - -Erg 使用命令測試軟件包中的目錄或文件中的子程序。 子例程負責黑盒測試(不測試私有函數),子例程負責白盒測試(也測試私有函數)。 - - -```erg -# tests/test1.er -{add; ...} = import "foo" - -@Test -test_1_plus_n(n: Nat) = - assert add(1, n) == n + 1 -``` - -運行結果顯示為摘要,並且可以以各種文件格式(.md,.csv,etc.)輸出。 - -## Doc Test - -在 Erg 中,,以後成為註釋行,但在中成為 doc comment,可以通過 VSCode 等編輯器標記註釋。並且,如果 doc comment 中的源代碼被指定為 erg,則通過 erg test 命令進行自動測試。以下是測試的例子。 - - -```erg -VM = ... - ... - #[[ - execute commands. - ```erg - # 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 = - ... - ... -``` - -測試時使用的模擬對象(嘲笑對象)定義在模塊中。 \ No newline at end of file