From d15cbbf7b33df0f78a575cff9679d84c36ea3ab1 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 07:20:19 +0800 Subject: [PATCH 01/42] Improve the English translation of doc and increase the simplified Chinese translation of doc --- doc/EN/API/consts.md | 13 + doc/EN/API/funcs.md | 121 +++ doc/EN/API/index.md | 0 doc/EN/API/modules/external/alstruct.md | 57 ++ doc/EN/API/modules/repl.md | 24 + doc/EN/API/modules/status.md | 6 + doc/EN/API/modules/unit.md | 73 ++ doc/EN/API/modules/unsound.md | 24 + doc/EN/API/operators.md | 64 ++ doc/EN/API/procs.md | 39 + doc/EN/API/special.md | 175 ++++ doc/EN/API/types.md | 262 ++++++ doc/EN/API/types/classes/Array!(T).md | 4 + doc/EN/API/types/classes/Array(T).md | 3 + doc/EN/API/types/classes/ArrayWithLen(T,N).md | 34 + .../types/classes/ArrayWithMutLength!(T,N).md | 34 + doc/EN/API/types/classes/Class.md | 0 doc/EN/API/types/classes/Complex.md | 14 + doc/EN/API/types/classes/Dict!.md | 7 + doc/EN/API/types/classes/Either.md | 12 + doc/EN/API/types/classes/Float.md | 21 + doc/EN/API/types/classes/Function(N).md | 9 + doc/EN/API/types/classes/Inf.md | 7 + doc/EN/API/types/classes/Int.md | 10 + doc/EN/API/types/classes/IntRange.md | 19 + doc/EN/API/types/classes/Interval.md | 18 + doc/EN/API/types/classes/Iterator.md | 0 doc/EN/API/types/classes/Kind(N).md | 5 + doc/EN/API/types/classes/Matrix.md | 7 + doc/EN/API/types/classes/Module.md | 3 + doc/EN/API/types/classes/Nat.md | 18 + doc/EN/API/types/classes/Neg.md | 8 + doc/EN/API/types/classes/Never.md | 13 + doc/EN/API/types/classes/NonZero.md | 30 + doc/EN/API/types/classes/Object.md | 7 + doc/EN/API/types/classes/Operator.md | 7 + doc/EN/API/types/classes/Option.md | 21 + doc/EN/API/types/classes/Pos.md | 8 + doc/EN/API/types/classes/Ratio.md | 5 + doc/EN/API/types/classes/Record.md | 14 + doc/EN/API/types/classes/Result.md | 7 + doc/EN/API/types/classes/Str!.md | 3 + doc/EN/API/types/classes/Str.md | 9 + doc/EN/API/types/classes/StrWithLen.md | 0 doc/EN/API/types/classes/Subroutine.md | 19 + doc/EN/API/types/classes/Tensor.md | 24 + doc/EN/API/types/classes/TransCell(T).md | 12 + doc/EN/API/types/classes/Tuple.md | 27 + doc/EN/API/types/classes/Type.md | 0 doc/EN/API/types/classes/Vector.md | 3 + doc/EN/API/types/patches/BinOp.md | 7 + doc/EN/API/types/patches/UnaryOp.md | 7 + doc/EN/API/types/traits/Add(R,O).md | 34 + doc/EN/API/types/traits/Div(R,O).md | 9 + doc/EN/API/types/traits/Eq.md | 0 doc/EN/API/types/traits/Into.md | 11 + doc/EN/API/types/traits/Iterable.md | 0 doc/EN/API/types/traits/Num.md | 16 + doc/EN/API/types/traits/Ord.md | 0 doc/EN/API/types/traits/SafeDiv(R,O).md | 8 + doc/EN/API/types/traits/Sample.md | 31 + doc/EN/API/types/traits/Seq.md | 0 doc/EN/API/types/traits/Show.md | 0 doc/EN/API/types/traits/Unpack.md | 13 + doc/EN/compiler/TODO_hint.md | 4 + doc/EN/compiler/TODO_recov_suggest.md | 11 + doc/EN/compiler/TODO_warn.md | 5 + doc/EN/compiler/abandoned.md | 10 + doc/EN/compiler/hir.md | 148 ++++ doc/EN/compiler/index.md | 0 doc/EN/compiler/inference.md | 438 +++++++++ doc/EN/compiler/overview.md | 28 +- doc/EN/compiler/refinement_subtyping.md | 149 ++++ doc/EN/compiler/trait_method_resolving.md | 95 ++ doc/EN/compiler/transpile.md | 90 ++ doc/EN/compiler/type_var_normalization.md | 39 + doc/EN/dev_guide/branches.md | 2 + doc/EN/dev_guide/build_features.md | 6 +- doc/EN/dev_guide/directories.md | 44 +- doc/EN/dev_guide/doc_guideline.md | 8 +- doc/EN/dev_guide/env.md | 16 +- doc/EN/dev_guide/faq_syntax.md | 110 +-- doc/EN/dev_guide/i18n_messages.md | 47 +- doc/EN/dev_guide/rust_code_guideline.md | 26 +- doc/EN/dev_guide/terms.md | 618 ++++++++++++- doc/EN/dev_guide/unify_terms.md | 88 ++ doc/EN/migration_from_py.md | 17 +- doc/EN/python/bytecode_instructions.md | 63 +- doc/EN/syntax/14_set.md | 29 +- doc/EN/syntax/15_type.md | 2 +- doc/EN/syntax/18_ownership.md | 108 +-- doc/EN/syntax/19_visibility.md | 112 +-- doc/EN/syntax/20_naming_rule.md | 30 +- doc/EN/syntax/21_lambda.md | 81 +- doc/EN/syntax/23_closure.md | 58 +- doc/EN/syntax/24_module.md | 2 +- doc/EN/syntax/25_object_system.md | 60 +- doc/EN/syntax/26_pattern_matching.md | 118 +-- doc/EN/syntax/27_comprehension.md | 55 +- doc/EN/syntax/28_spread_syntax.md | 30 +- doc/EN/syntax/29_decorator.md | 93 +- doc/EN/syntax/30_error_handling.md | 75 +- doc/EN/syntax/31_pipeline.md | 17 +- doc/EN/syntax/container_ownership.md | 42 + doc/EN/syntax/grammar.txt | 2 +- doc/EN/syntax/indexes.md | 380 ++++++-- doc/EN/syntax/quick_tour.md | 266 ++++++ doc/EN/syntax/type/14_dependent.md | 68 +- doc/EN/syntax/type/18_mut.md | 148 ++-- doc/EN/syntax/type/19_bound.md | 16 +- doc/EN/syntax/type/advanced.md | 3 +- doc/EN/syntax/type/advanced/GADTs.md | 34 +- doc/EN/syntax/type/advanced/_rank2type.md | 142 +++ doc/EN/syntax/type/advanced/default_param.md | 18 +- doc/EN/syntax/type/advanced/keyword_param.md | 16 +- doc/EN/syntax/type/advanced/kind.md | 34 +- doc/EN/syntax/type/advanced/marker_trait.md | 20 +- doc/EN/syntax/type/advanced/special.md | 28 +- doc/EN/syntax/type/advanced/typeof.md | 65 ++ doc/EN/syntax/type/advanced/variance.md | 143 +++ doc/EN/syntax/type/advanced/widening.md | 92 ++ doc/EN/tools/build.md | 14 + doc/EN/tools/env.md | 7 + doc/EN/tools/fmt.md | 6 + doc/EN/tools/index.md | 0 doc/EN/tools/install.md | 10 + doc/EN/tools/pack.md | 100 +++ doc/EN/tools/repl.md | 15 + doc/EN/tools/test.md | 45 + doc/JA/compiler/architecture.md | 56 +- doc/JA/compiler/parsing.md | 2 +- doc/JA/syntax/type/04_class.md | 10 +- doc/zh_CN/API/consts.md | 13 + doc/zh_CN/API/funcs.md | 121 +++ doc/zh_CN/API/index.md | 0 doc/zh_CN/API/modules/external/alstruct.md | 57 ++ doc/zh_CN/API/modules/repl.md | 24 + doc/zh_CN/API/modules/status.md | 6 + doc/zh_CN/API/modules/unit.md | 73 ++ doc/zh_CN/API/modules/unsound.md | 24 + doc/zh_CN/API/operators.md | 64 ++ doc/zh_CN/API/procs.md | 39 + doc/zh_CN/API/special.md | 175 ++++ doc/zh_CN/API/types.md | 262 ++++++ doc/zh_CN/API/types/classes/Array!(T).md | 3 + doc/zh_CN/API/types/classes/Array(T).md | 3 + .../API/types/classes/ArrayWithLen(T,N).md | 34 + .../types/classes/ArrayWithMutLength!(T,N).md | 26 + doc/zh_CN/API/types/classes/Class.md | 0 doc/zh_CN/API/types/classes/Complex.md | 14 + doc/zh_CN/API/types/classes/Dict!.md | 7 + doc/zh_CN/API/types/classes/Either.md | 12 + doc/zh_CN/API/types/classes/Float.md | 21 + doc/zh_CN/API/types/classes/Function(N).md | 9 + doc/zh_CN/API/types/classes/Inf.md | 7 + doc/zh_CN/API/types/classes/Int.md | 10 + doc/zh_CN/API/types/classes/IntRange.md | 19 + doc/zh_CN/API/types/classes/Interval.md | 18 + doc/zh_CN/API/types/classes/Iterator.md | 0 doc/zh_CN/API/types/classes/Kind(N).md | 5 + doc/zh_CN/API/types/classes/Matrix.md | 7 + doc/zh_CN/API/types/classes/Module.md | 3 + doc/zh_CN/API/types/classes/Nat.md | 18 + doc/zh_CN/API/types/classes/Neg.md | 8 + doc/zh_CN/API/types/classes/Never.md | 13 + doc/zh_CN/API/types/classes/NonZero.md | 30 + doc/zh_CN/API/types/classes/Object.md | 7 + doc/zh_CN/API/types/classes/Operator.md | 7 + doc/zh_CN/API/types/classes/Option.md | 21 + doc/zh_CN/API/types/classes/Pos.md | 8 + doc/zh_CN/API/types/classes/Ratio.md | 5 + doc/zh_CN/API/types/classes/Record.md | 14 + doc/zh_CN/API/types/classes/Result.md | 7 + doc/zh_CN/API/types/classes/Str!.md | 3 + doc/zh_CN/API/types/classes/Str.md | 9 + doc/zh_CN/API/types/classes/StrWithLen.md | 0 doc/zh_CN/API/types/classes/Subroutine.md | 19 + doc/zh_CN/API/types/classes/Tensor.md | 24 + doc/zh_CN/API/types/classes/TransCell(T).md | 12 + doc/zh_CN/API/types/classes/Tuple.md | 27 + doc/zh_CN/API/types/classes/Type.md | 0 doc/zh_CN/API/types/classes/Vector.md | 3 + doc/zh_CN/API/types/patches/BinOp.md | 7 + doc/zh_CN/API/types/patches/UnaryOp.md | 7 + doc/zh_CN/API/types/traits/Add(R,O).md | 34 + doc/zh_CN/API/types/traits/Div(R,O).md | 9 + doc/zh_CN/API/types/traits/Eq.md | 0 doc/zh_CN/API/types/traits/Into.md | 11 + doc/zh_CN/API/types/traits/Iterable.md | 0 doc/zh_CN/API/types/traits/Num.md | 16 + doc/zh_CN/API/types/traits/Ord.md | 0 doc/zh_CN/API/types/traits/SafeDiv(R,O).md | 8 + doc/zh_CN/API/types/traits/Sample.md | 31 + doc/zh_CN/API/types/traits/Seq.md | 0 doc/zh_CN/API/types/traits/Show.md | 0 doc/zh_CN/API/types/traits/Unpack.md | 13 + doc/zh_CN/compiler/TODO_hint.md | 4 + doc/zh_CN/compiler/TODO_recov_suggest.md | 11 + doc/zh_CN/compiler/TODO_warn.md | 5 + doc/zh_CN/compiler/abandoned.md | 10 + doc/zh_CN/compiler/architecture.md | 42 + doc/zh_CN/compiler/errors.md | 131 +++ doc/zh_CN/compiler/hir.md | 148 ++++ doc/zh_CN/compiler/index.md | 0 doc/zh_CN/compiler/inference.md | 436 +++++++++ doc/zh_CN/compiler/overview.md | 36 + doc/zh_CN/compiler/parsing.md | 31 + doc/zh_CN/compiler/refinement_subtyping.md | 155 ++++ doc/zh_CN/compiler/trait_method_resolving.md | 86 ++ doc/zh_CN/compiler/transpile.md | 91 ++ doc/zh_CN/compiler/type_var_normalization.md | 35 + doc/zh_CN/dev_guide/branches.md | 31 + doc/zh_CN/dev_guide/build_features.md | 17 + doc/zh_CN/dev_guide/directories.md | 25 + doc/zh_CN/dev_guide/doc_guideline.md | 13 + doc/zh_CN/dev_guide/env.md | 19 + doc/zh_CN/dev_guide/faq_syntax.md | 108 +++ doc/zh_CN/dev_guide/i18n_messages.md | 55 ++ doc/zh_CN/dev_guide/index.md | 0 doc/zh_CN/dev_guide/rust_code_guideline.md | 23 + doc/zh_CN/dev_guide/terms.md | 831 ++++++++++++++++++ doc/zh_CN/dev_guide/unify_terms.md | 80 ++ doc/zh_CN/faq_general.md | 27 + doc/zh_CN/faq_technical.md | 25 + doc/zh_CN/improved_points.md | 46 + doc/zh_CN/index.md | 25 + doc/zh_CN/migration_from_py.md | 28 + doc/zh_CN/python/bytecode_instructions.md | 106 +++ doc/zh_CN/python/bytecode_specification.md | 70 ++ doc/zh_CN/python/class_system.md | 95 ++ doc/zh_CN/python/index.md | 0 doc/zh_CN/syntax/00_basic.md | 121 +++ doc/zh_CN/syntax/01_literal.md | 165 ++++ doc/zh_CN/syntax/02_name.md | 169 ++++ doc/zh_CN/syntax/03_declaration.md | 48 + doc/zh_CN/syntax/04_function.md | 306 +++++++ doc/zh_CN/syntax/05_builtin_funcs.md | 52 ++ doc/zh_CN/syntax/06_operator.md | 30 + doc/zh_CN/syntax/07_side_effect.md | 123 +++ doc/zh_CN/syntax/08_procedure.md | 12 + doc/zh_CN/syntax/09_builtin_procs.md | 13 + doc/zh_CN/syntax/10_array.md | 56 ++ doc/zh_CN/syntax/11_tuple.md | 125 +++ doc/zh_CN/syntax/12_dict.md | 71 ++ doc/zh_CN/syntax/13_record.md | 198 +++++ doc/zh_CN/syntax/14_set.md | 50 ++ doc/zh_CN/syntax/15_type.md | 7 + doc/zh_CN/syntax/16_iterator.md | 91 ++ doc/zh_CN/syntax/17_mutability.md | 92 ++ doc/zh_CN/syntax/18_ownership.md | 103 +++ doc/zh_CN/syntax/19_visibility.md | 199 +++++ doc/zh_CN/syntax/20_naming_rule.md | 52 ++ doc/zh_CN/syntax/21_lambda.md | 102 +++ doc/zh_CN/syntax/22_subroutine.md | 65 ++ doc/zh_CN/syntax/23_closure.md | 99 +++ doc/zh_CN/syntax/24_module.md | 47 + doc/zh_CN/syntax/25_object_system.md | 77 ++ doc/zh_CN/syntax/26_pattern_matching.md | 203 +++++ doc/zh_CN/syntax/27_comprehension.md | 65 ++ doc/zh_CN/syntax/28_spread_syntax.md | 45 + doc/zh_CN/syntax/29_decorator.md | 124 +++ doc/zh_CN/syntax/30_error_handling.md | 106 +++ doc/zh_CN/syntax/31_pipeline.md | 32 + .../syntax/32_integration_with_Python.md | 87 ++ doc/zh_CN/syntax/33_package_system.md | 83 ++ doc/zh_CN/syntax/34_generator.md | 37 + doc/zh_CN/syntax/SUMMARY.md | 69 ++ doc/zh_CN/syntax/container_ownership.md | 42 + doc/zh_CN/syntax/grammar.txt | 88 ++ doc/zh_CN/syntax/indexes.md | 452 ++++++++++ doc/zh_CN/syntax/quick_tour.md | 287 ++++++ doc/zh_CN/syntax/type/01_type_system.md | 225 +++++ doc/zh_CN/syntax/type/02_basic.md | 170 ++++ doc/zh_CN/syntax/type/03_trait.md | 193 ++++ doc/zh_CN/syntax/type/04_class.md | 285 ++++++ doc/zh_CN/syntax/type/05_inheritance.md | 248 ++++++ doc/zh_CN/syntax/type/06_nst_vs_sst.md | 43 + doc/zh_CN/syntax/type/07_patch.md | 223 +++++ doc/zh_CN/syntax/type/08_value.md | 38 + doc/zh_CN/syntax/type/09_attributive.md | 7 + doc/zh_CN/syntax/type/10_interval.md | 39 + doc/zh_CN/syntax/type/11_enum.md | 86 ++ doc/zh_CN/syntax/type/12_refinement.md | 75 ++ doc/zh_CN/syntax/type/13_algebraic.md | 82 ++ doc/zh_CN/syntax/type/14_dependent.md | 76 ++ doc/zh_CN/syntax/type/15_quantified.md | 288 ++++++ doc/zh_CN/syntax/type/16_subtyping.md | 80 ++ doc/zh_CN/syntax/type/17_type_casting.md | 74 ++ doc/zh_CN/syntax/type/18_mut.md | 168 ++++ doc/zh_CN/syntax/type/19_bound.md | 16 + doc/zh_CN/syntax/type/advanced.md | 1 + doc/zh_CN/syntax/type/advanced/GADTs.md | 68 ++ doc/zh_CN/syntax/type/advanced/_rank2type.md | 142 +++ .../syntax/type/advanced/default_param.md | 28 + doc/zh_CN/syntax/type/advanced/erasure.md | 45 + doc/zh_CN/syntax/type/advanced/existential.md | 39 + .../syntax/type/advanced/keyword_param.md | 26 + doc/zh_CN/syntax/type/advanced/kind.md | 157 ++++ .../syntax/type/advanced/marker_trait.md | 33 + doc/zh_CN/syntax/type/advanced/mut_struct.md | 40 + doc/zh_CN/syntax/type/advanced/newtype.md | 31 + doc/zh_CN/syntax/type/advanced/overloading.md | 91 ++ doc/zh_CN/syntax/type/advanced/phantom.md | 58 ++ doc/zh_CN/syntax/type/advanced/projection.md | 25 + .../type/advanced/quantified_dependent.md | 30 + doc/zh_CN/syntax/type/advanced/shared.md | 72 ++ doc/zh_CN/syntax/type/advanced/special.md | 54 ++ doc/zh_CN/syntax/type/advanced/typeof.md | 61 ++ doc/zh_CN/syntax/type/advanced/variance.md | 128 +++ doc/zh_CN/syntax/type/advanced/widening.md | 93 ++ doc/zh_CN/tips.md | 142 +++ doc/zh_CN/tools/build.md | 13 + doc/zh_CN/tools/env.md | 3 + doc/zh_CN/tools/fmt.md | 5 + doc/zh_CN/tools/index.md | 0 doc/zh_CN/tools/install.md | 9 + doc/zh_CN/tools/pack.md | 82 ++ doc/zh_CN/tools/repl.md | 15 + doc/zh_CN/tools/test.md | 43 + 319 files changed, 17672 insertions(+), 893 deletions(-) create mode 100644 doc/EN/API/consts.md create mode 100644 doc/EN/API/funcs.md create mode 100644 doc/EN/API/index.md create mode 100644 doc/EN/API/modules/external/alstruct.md create mode 100644 doc/EN/API/modules/repl.md create mode 100644 doc/EN/API/modules/status.md create mode 100644 doc/EN/API/modules/unit.md create mode 100644 doc/EN/API/modules/unsound.md create mode 100644 doc/EN/API/operators.md create mode 100644 doc/EN/API/procs.md create mode 100644 doc/EN/API/special.md create mode 100644 doc/EN/API/types.md create mode 100644 doc/EN/API/types/classes/Array!(T).md create mode 100644 doc/EN/API/types/classes/Array(T).md create mode 100644 doc/EN/API/types/classes/ArrayWithLen(T,N).md create mode 100644 doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md create mode 100644 doc/EN/API/types/classes/Class.md create mode 100644 doc/EN/API/types/classes/Complex.md create mode 100644 doc/EN/API/types/classes/Dict!.md create mode 100644 doc/EN/API/types/classes/Either.md create mode 100644 doc/EN/API/types/classes/Float.md create mode 100644 doc/EN/API/types/classes/Function(N).md create mode 100644 doc/EN/API/types/classes/Inf.md create mode 100644 doc/EN/API/types/classes/Int.md create mode 100644 doc/EN/API/types/classes/IntRange.md create mode 100644 doc/EN/API/types/classes/Interval.md create mode 100644 doc/EN/API/types/classes/Iterator.md create mode 100644 doc/EN/API/types/classes/Kind(N).md create mode 100644 doc/EN/API/types/classes/Matrix.md create mode 100644 doc/EN/API/types/classes/Module.md create mode 100644 doc/EN/API/types/classes/Nat.md create mode 100644 doc/EN/API/types/classes/Neg.md create mode 100644 doc/EN/API/types/classes/Never.md create mode 100644 doc/EN/API/types/classes/NonZero.md create mode 100644 doc/EN/API/types/classes/Object.md create mode 100644 doc/EN/API/types/classes/Operator.md create mode 100644 doc/EN/API/types/classes/Option.md create mode 100644 doc/EN/API/types/classes/Pos.md create mode 100644 doc/EN/API/types/classes/Ratio.md create mode 100644 doc/EN/API/types/classes/Record.md create mode 100644 doc/EN/API/types/classes/Result.md create mode 100644 doc/EN/API/types/classes/Str!.md create mode 100644 doc/EN/API/types/classes/Str.md create mode 100644 doc/EN/API/types/classes/StrWithLen.md create mode 100644 doc/EN/API/types/classes/Subroutine.md create mode 100644 doc/EN/API/types/classes/Tensor.md create mode 100644 doc/EN/API/types/classes/TransCell(T).md create mode 100644 doc/EN/API/types/classes/Tuple.md create mode 100644 doc/EN/API/types/classes/Type.md create mode 100644 doc/EN/API/types/classes/Vector.md create mode 100644 doc/EN/API/types/patches/BinOp.md create mode 100644 doc/EN/API/types/patches/UnaryOp.md create mode 100644 doc/EN/API/types/traits/Add(R,O).md create mode 100644 doc/EN/API/types/traits/Div(R,O).md create mode 100644 doc/EN/API/types/traits/Eq.md create mode 100644 doc/EN/API/types/traits/Into.md create mode 100644 doc/EN/API/types/traits/Iterable.md create mode 100644 doc/EN/API/types/traits/Num.md create mode 100644 doc/EN/API/types/traits/Ord.md create mode 100644 doc/EN/API/types/traits/SafeDiv(R,O).md create mode 100644 doc/EN/API/types/traits/Sample.md create mode 100644 doc/EN/API/types/traits/Seq.md create mode 100644 doc/EN/API/types/traits/Show.md create mode 100644 doc/EN/API/types/traits/Unpack.md create mode 100644 doc/EN/compiler/TODO_hint.md create mode 100644 doc/EN/compiler/TODO_recov_suggest.md create mode 100644 doc/EN/compiler/TODO_warn.md create mode 100644 doc/EN/compiler/abandoned.md create mode 100644 doc/EN/compiler/hir.md create mode 100644 doc/EN/compiler/index.md create mode 100644 doc/EN/compiler/inference.md create mode 100644 doc/EN/compiler/refinement_subtyping.md create mode 100644 doc/EN/compiler/trait_method_resolving.md create mode 100644 doc/EN/compiler/transpile.md create mode 100644 doc/EN/compiler/type_var_normalization.md create mode 100644 doc/EN/syntax/container_ownership.md create mode 100644 doc/EN/syntax/type/advanced/_rank2type.md create mode 100644 doc/EN/syntax/type/advanced/typeof.md create mode 100644 doc/EN/syntax/type/advanced/variance.md create mode 100644 doc/EN/syntax/type/advanced/widening.md create mode 100644 doc/EN/tools/build.md create mode 100644 doc/EN/tools/env.md create mode 100644 doc/EN/tools/fmt.md create mode 100644 doc/EN/tools/index.md create mode 100644 doc/EN/tools/install.md create mode 100644 doc/EN/tools/pack.md create mode 100644 doc/EN/tools/repl.md create mode 100644 doc/EN/tools/test.md create mode 100644 doc/zh_CN/API/consts.md create mode 100644 doc/zh_CN/API/funcs.md create mode 100644 doc/zh_CN/API/index.md create mode 100644 doc/zh_CN/API/modules/external/alstruct.md create mode 100644 doc/zh_CN/API/modules/repl.md create mode 100644 doc/zh_CN/API/modules/status.md create mode 100644 doc/zh_CN/API/modules/unit.md create mode 100644 doc/zh_CN/API/modules/unsound.md create mode 100644 doc/zh_CN/API/operators.md create mode 100644 doc/zh_CN/API/procs.md create mode 100644 doc/zh_CN/API/special.md create mode 100644 doc/zh_CN/API/types.md create mode 100644 doc/zh_CN/API/types/classes/Array!(T).md create mode 100644 doc/zh_CN/API/types/classes/Array(T).md create mode 100644 doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md create mode 100644 doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md create mode 100644 doc/zh_CN/API/types/classes/Class.md create mode 100644 doc/zh_CN/API/types/classes/Complex.md create mode 100644 doc/zh_CN/API/types/classes/Dict!.md create mode 100644 doc/zh_CN/API/types/classes/Either.md create mode 100644 doc/zh_CN/API/types/classes/Float.md create mode 100644 doc/zh_CN/API/types/classes/Function(N).md create mode 100644 doc/zh_CN/API/types/classes/Inf.md create mode 100644 doc/zh_CN/API/types/classes/Int.md create mode 100644 doc/zh_CN/API/types/classes/IntRange.md create mode 100644 doc/zh_CN/API/types/classes/Interval.md create mode 100644 doc/zh_CN/API/types/classes/Iterator.md create mode 100644 doc/zh_CN/API/types/classes/Kind(N).md create mode 100644 doc/zh_CN/API/types/classes/Matrix.md create mode 100644 doc/zh_CN/API/types/classes/Module.md create mode 100644 doc/zh_CN/API/types/classes/Nat.md create mode 100644 doc/zh_CN/API/types/classes/Neg.md create mode 100644 doc/zh_CN/API/types/classes/Never.md create mode 100644 doc/zh_CN/API/types/classes/NonZero.md create mode 100644 doc/zh_CN/API/types/classes/Object.md create mode 100644 doc/zh_CN/API/types/classes/Operator.md create mode 100644 doc/zh_CN/API/types/classes/Option.md create mode 100644 doc/zh_CN/API/types/classes/Pos.md create mode 100644 doc/zh_CN/API/types/classes/Ratio.md create mode 100644 doc/zh_CN/API/types/classes/Record.md create mode 100644 doc/zh_CN/API/types/classes/Result.md create mode 100644 doc/zh_CN/API/types/classes/Str!.md create mode 100644 doc/zh_CN/API/types/classes/Str.md create mode 100644 doc/zh_CN/API/types/classes/StrWithLen.md create mode 100644 doc/zh_CN/API/types/classes/Subroutine.md create mode 100644 doc/zh_CN/API/types/classes/Tensor.md create mode 100644 doc/zh_CN/API/types/classes/TransCell(T).md create mode 100644 doc/zh_CN/API/types/classes/Tuple.md create mode 100644 doc/zh_CN/API/types/classes/Type.md create mode 100644 doc/zh_CN/API/types/classes/Vector.md create mode 100644 doc/zh_CN/API/types/patches/BinOp.md create mode 100644 doc/zh_CN/API/types/patches/UnaryOp.md create mode 100644 doc/zh_CN/API/types/traits/Add(R,O).md create mode 100644 doc/zh_CN/API/types/traits/Div(R,O).md create mode 100644 doc/zh_CN/API/types/traits/Eq.md create mode 100644 doc/zh_CN/API/types/traits/Into.md create mode 100644 doc/zh_CN/API/types/traits/Iterable.md create mode 100644 doc/zh_CN/API/types/traits/Num.md create mode 100644 doc/zh_CN/API/types/traits/Ord.md create mode 100644 doc/zh_CN/API/types/traits/SafeDiv(R,O).md create mode 100644 doc/zh_CN/API/types/traits/Sample.md create mode 100644 doc/zh_CN/API/types/traits/Seq.md create mode 100644 doc/zh_CN/API/types/traits/Show.md create mode 100644 doc/zh_CN/API/types/traits/Unpack.md create mode 100644 doc/zh_CN/compiler/TODO_hint.md create mode 100644 doc/zh_CN/compiler/TODO_recov_suggest.md create mode 100644 doc/zh_CN/compiler/TODO_warn.md create mode 100644 doc/zh_CN/compiler/abandoned.md create mode 100644 doc/zh_CN/compiler/architecture.md create mode 100644 doc/zh_CN/compiler/errors.md create mode 100644 doc/zh_CN/compiler/hir.md create mode 100644 doc/zh_CN/compiler/index.md create mode 100644 doc/zh_CN/compiler/inference.md create mode 100644 doc/zh_CN/compiler/overview.md create mode 100644 doc/zh_CN/compiler/parsing.md create mode 100644 doc/zh_CN/compiler/refinement_subtyping.md create mode 100644 doc/zh_CN/compiler/trait_method_resolving.md create mode 100644 doc/zh_CN/compiler/transpile.md create mode 100644 doc/zh_CN/compiler/type_var_normalization.md create mode 100644 doc/zh_CN/dev_guide/branches.md create mode 100644 doc/zh_CN/dev_guide/build_features.md create mode 100644 doc/zh_CN/dev_guide/directories.md create mode 100644 doc/zh_CN/dev_guide/doc_guideline.md create mode 100644 doc/zh_CN/dev_guide/env.md create mode 100644 doc/zh_CN/dev_guide/faq_syntax.md create mode 100644 doc/zh_CN/dev_guide/i18n_messages.md create mode 100644 doc/zh_CN/dev_guide/index.md create mode 100644 doc/zh_CN/dev_guide/rust_code_guideline.md create mode 100644 doc/zh_CN/dev_guide/terms.md create mode 100644 doc/zh_CN/dev_guide/unify_terms.md create mode 100644 doc/zh_CN/faq_general.md create mode 100644 doc/zh_CN/faq_technical.md create mode 100644 doc/zh_CN/improved_points.md create mode 100644 doc/zh_CN/index.md create mode 100644 doc/zh_CN/migration_from_py.md create mode 100644 doc/zh_CN/python/bytecode_instructions.md create mode 100644 doc/zh_CN/python/bytecode_specification.md create mode 100644 doc/zh_CN/python/class_system.md create mode 100644 doc/zh_CN/python/index.md create mode 100644 doc/zh_CN/syntax/00_basic.md create mode 100644 doc/zh_CN/syntax/01_literal.md create mode 100644 doc/zh_CN/syntax/02_name.md create mode 100644 doc/zh_CN/syntax/03_declaration.md create mode 100644 doc/zh_CN/syntax/04_function.md create mode 100644 doc/zh_CN/syntax/05_builtin_funcs.md create mode 100644 doc/zh_CN/syntax/06_operator.md create mode 100644 doc/zh_CN/syntax/07_side_effect.md create mode 100644 doc/zh_CN/syntax/08_procedure.md create mode 100644 doc/zh_CN/syntax/09_builtin_procs.md create mode 100644 doc/zh_CN/syntax/10_array.md create mode 100644 doc/zh_CN/syntax/11_tuple.md create mode 100644 doc/zh_CN/syntax/12_dict.md create mode 100644 doc/zh_CN/syntax/13_record.md create mode 100644 doc/zh_CN/syntax/14_set.md create mode 100644 doc/zh_CN/syntax/15_type.md create mode 100644 doc/zh_CN/syntax/16_iterator.md create mode 100644 doc/zh_CN/syntax/17_mutability.md create mode 100644 doc/zh_CN/syntax/18_ownership.md create mode 100644 doc/zh_CN/syntax/19_visibility.md create mode 100644 doc/zh_CN/syntax/20_naming_rule.md create mode 100644 doc/zh_CN/syntax/21_lambda.md create mode 100644 doc/zh_CN/syntax/22_subroutine.md create mode 100644 doc/zh_CN/syntax/23_closure.md create mode 100644 doc/zh_CN/syntax/24_module.md create mode 100644 doc/zh_CN/syntax/25_object_system.md create mode 100644 doc/zh_CN/syntax/26_pattern_matching.md create mode 100644 doc/zh_CN/syntax/27_comprehension.md create mode 100644 doc/zh_CN/syntax/28_spread_syntax.md create mode 100644 doc/zh_CN/syntax/29_decorator.md create mode 100644 doc/zh_CN/syntax/30_error_handling.md create mode 100644 doc/zh_CN/syntax/31_pipeline.md create mode 100644 doc/zh_CN/syntax/32_integration_with_Python.md create mode 100644 doc/zh_CN/syntax/33_package_system.md create mode 100644 doc/zh_CN/syntax/34_generator.md create mode 100644 doc/zh_CN/syntax/SUMMARY.md create mode 100644 doc/zh_CN/syntax/container_ownership.md create mode 100644 doc/zh_CN/syntax/grammar.txt create mode 100644 doc/zh_CN/syntax/indexes.md create mode 100644 doc/zh_CN/syntax/quick_tour.md create mode 100644 doc/zh_CN/syntax/type/01_type_system.md create mode 100644 doc/zh_CN/syntax/type/02_basic.md create mode 100644 doc/zh_CN/syntax/type/03_trait.md create mode 100644 doc/zh_CN/syntax/type/04_class.md create mode 100644 doc/zh_CN/syntax/type/05_inheritance.md create mode 100644 doc/zh_CN/syntax/type/06_nst_vs_sst.md create mode 100644 doc/zh_CN/syntax/type/07_patch.md create mode 100644 doc/zh_CN/syntax/type/08_value.md create mode 100644 doc/zh_CN/syntax/type/09_attributive.md create mode 100644 doc/zh_CN/syntax/type/10_interval.md create mode 100644 doc/zh_CN/syntax/type/11_enum.md create mode 100644 doc/zh_CN/syntax/type/12_refinement.md create mode 100644 doc/zh_CN/syntax/type/13_algebraic.md create mode 100644 doc/zh_CN/syntax/type/14_dependent.md create mode 100644 doc/zh_CN/syntax/type/15_quantified.md create mode 100644 doc/zh_CN/syntax/type/16_subtyping.md create mode 100644 doc/zh_CN/syntax/type/17_type_casting.md create mode 100644 doc/zh_CN/syntax/type/18_mut.md create mode 100644 doc/zh_CN/syntax/type/19_bound.md create mode 100644 doc/zh_CN/syntax/type/advanced.md create mode 100644 doc/zh_CN/syntax/type/advanced/GADTs.md create mode 100644 doc/zh_CN/syntax/type/advanced/_rank2type.md create mode 100644 doc/zh_CN/syntax/type/advanced/default_param.md create mode 100644 doc/zh_CN/syntax/type/advanced/erasure.md create mode 100644 doc/zh_CN/syntax/type/advanced/existential.md create mode 100644 doc/zh_CN/syntax/type/advanced/keyword_param.md create mode 100644 doc/zh_CN/syntax/type/advanced/kind.md create mode 100644 doc/zh_CN/syntax/type/advanced/marker_trait.md create mode 100644 doc/zh_CN/syntax/type/advanced/mut_struct.md create mode 100644 doc/zh_CN/syntax/type/advanced/newtype.md create mode 100644 doc/zh_CN/syntax/type/advanced/overloading.md create mode 100644 doc/zh_CN/syntax/type/advanced/phantom.md create mode 100644 doc/zh_CN/syntax/type/advanced/projection.md create mode 100644 doc/zh_CN/syntax/type/advanced/quantified_dependent.md create mode 100644 doc/zh_CN/syntax/type/advanced/shared.md create mode 100644 doc/zh_CN/syntax/type/advanced/special.md create mode 100644 doc/zh_CN/syntax/type/advanced/typeof.md create mode 100644 doc/zh_CN/syntax/type/advanced/variance.md create mode 100644 doc/zh_CN/syntax/type/advanced/widening.md create mode 100644 doc/zh_CN/tips.md create mode 100644 doc/zh_CN/tools/build.md create mode 100644 doc/zh_CN/tools/env.md create mode 100644 doc/zh_CN/tools/fmt.md create mode 100644 doc/zh_CN/tools/index.md create mode 100644 doc/zh_CN/tools/install.md create mode 100644 doc/zh_CN/tools/pack.md create mode 100644 doc/zh_CN/tools/repl.md create mode 100644 doc/zh_CN/tools/test.md diff --git a/doc/EN/API/consts.md b/doc/EN/API/consts.md new file mode 100644 index 00000000..daf7d1e5 --- /dev/null +++ b/doc/EN/API/consts.md @@ -0,0 +1,13 @@ +# built-in constants + +## True + +## False + +## None + +## Ellipsis + +## Not Implemented + +## Inf \ No newline at end of file diff --git a/doc/EN/API/funcs.md b/doc/EN/API/funcs.md new file mode 100644 index 00000000..78128595 --- /dev/null +++ b/doc/EN/API/funcs.md @@ -0,0 +1,121 @@ +# 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 + +Note that the order of arguments is reversed from Python. + +### log(x: Object, type: LogType = Info) -> None + +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: ✅ +* type == Warn: ⚠️ +* type == Hint: 💡 + +### panic(msg: Str) -> Panic + +Display msg and stop. +Emoji-capable terminals have a 🚨 prefix. + +### discard|T|(x: ...T) -> NoneType + +Throw away `x`. Used when the return value is not used. Unlike `del`, it does not make the variable `x` inaccessible. + +``` erg +p!x= + # Let q! return some None or non-() value + # use `discard` if you don't need it + discard q!(x) + f x + +discard True +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 + +Evaluate code as code and return. + +### classof(object: Object) -> Class + +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 generation system + +### 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" +``` + +## constant expression functions + +### 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 +C = Class {i = Int} +NewInt = ClassInt +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" +``` + +The second argument, Impl, is the trait to implement. + +### Inherit + +Inherit a class. You can use the base class methods as they are. + +### Traits + +Create a new trait. Currently, only record types can be specified. + +### Type of + +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: Type of i = ... +# TypeWarning: Typeof(i) == Int, please replace it +``` + +### Deprecated + +Use as a decorator. Warn about deprecated types and functions. \ No newline at end of file diff --git a/doc/EN/API/index.md b/doc/EN/API/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/API/modules/external/alstruct.md b/doc/EN/API/modules/external/alstruct.md new file mode 100644 index 00000000..66bd2e86 --- /dev/null +++ b/doc/EN/API/modules/external/alstruct.md @@ -0,0 +1,57 @@ +# alstruct + +Modules that provide traits representing algebraic structures and patches for them. + +* members + +## BinOp + +``` erg +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 +``` + +## SemiGroup + +``` erg +SemiGroup Op: Kind 2 = Op(Self, Self) + +IntIsSemiGroupAdd = Patch Int, Impl=SemiGroupAdd + +Int <: SemiGroup Add +``` + +## Functors + +``` 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: { + .pure|T: 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/EN/API/modules/repl.md b/doc/EN/API/modules/repl.md new file mode 100644 index 00000000..a4091909 --- /dev/null +++ b/doc/EN/API/modules/repl.md @@ -0,0 +1,24 @@ +# module `repl` + +provides REPL(Read-Eval-Print-Loop)-related APIs. + +## functions + +* `gui_help` + +View information about an object in a browser. Can be used offline. + +## types + +### Guess = Object + +#### methods + +* `.guess` + +Infers a function given its arguments and return value. + +``` erg +1.guess((1,), 2) # +[1, 2].guess((3, 4), [1, 2, 3, 4]) # +``` \ No newline at end of file diff --git a/doc/EN/API/modules/status.md b/doc/EN/API/modules/status.md new file mode 100644 index 00000000..a30b4ad0 --- /dev/null +++ b/doc/EN/API/modules/status.md @@ -0,0 +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 diff --git a/doc/EN/API/modules/unit.md b/doc/EN/API/modules/unit.md new file mode 100644 index 00000000..781eefff --- /dev/null +++ b/doc/EN/API/modules/unit.md @@ -0,0 +1,73 @@ +# module `unit` + +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 # 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 +``` + +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. + +In unit, the following units are defined as types. It is called SI (International System of Units). + +* 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) + +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 = Patch UnitMul(Meter, Meter) +``` + +Some auxiliary units are also predefined. + +* 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 +* 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 + +*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/EN/API/modules/unsound.md b/doc/EN/API/modules/unsound.md new file mode 100644 index 00000000..28998a72 --- /dev/null +++ b/doc/EN/API/modules/unsound.md @@ -0,0 +1,24 @@ +# module `unsound` + +Provides APIs perform unsound and unsafe operations that cannot be guaranteed safe in Erg's type system. + +## `unsafe!` + +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 +``` + +## 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 + +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/EN/API/operators.md b/doc/EN/API/operators.md new file mode 100644 index 00000000..31b1f58b --- /dev/null +++ b/doc/EN/API/operators.md @@ -0,0 +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 + +Executes the and operation. + +### `or`(x: Bool, y: Bool) -> Bool + +Executes the and operation. + +## prefix operator + +### `+_`|T <: Num|(x: T) -> T + +Same as id by default. + +### `-_`|T <: Num|(x: T) -> T.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 + +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 + +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/EN/API/procs.md b/doc/EN/API/procs.md new file mode 100644 index 00000000..371b2f7c --- /dev/null +++ b/doc/EN/API/procs.md @@ -0,0 +1,39 @@ +# procedures + +## print! + +``` erg +print!(x) -> NoneType +``` + + Returns x with a newline. + +##debug! + +``` erg +debug!(x, type = Info) -> NoneType +``` + +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 + +Traverse the iterator with the action of block. + +## while! cond: Bool!, block: () => NoneType + +Execute block while cond is True. + +## Lineno!() -> Nat + +## Filename!() -> Str + +## Namespace!() -> Str + +## Module!() -> Module \ No newline at end of file diff --git a/doc/EN/API/special.md b/doc/EN/API/special.md new file mode 100644 index 00000000..698429dc --- /dev/null +++ b/doc/EN/API/special.md @@ -0,0 +1,175 @@ +# Special form + +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 + +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 +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 +print! Class() # > +print! x: Int -> x + 1 # > +C = Class() +print! c # +f = x: Int -> x + 1 +print! f # +gx: Int = x + 1 +print! g # +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. + +``` erg +i = j = 1 # SyntaxError: multiple assignments are not allowed +print!(x=1) # SyntaxError: cannot use `=` in function arguments +# hint: did you mean keyword arguments (`x: 1`)? +if True, do: + 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) + +Determine if subject matches T. If they don't match, throw a compile error. + +``` erg +a: Int +f x: Int, y: Int = x / y +``` + +Also used for `:` applied styles. + +``` erg +fx: + y + z +``` + +Like `:` and `=`, the result of the operation is undefined. + +``` erg +_ = x: Int # SyntaxError: +print!(x: Int) # SyntaxError: +``` + +## `.`(obj, attr) + +Read attributes of obj. +`x.[y, z]` will return the y and z attributes of x as an array. + +## `|>`(obj, c: Callable) + +Execute `c(obj)`. `x + y |>.foo()` is the same as `(x + y).foo()`. + +### (x: Option T)`?` -> T | T + +Postfix operator. Call `x.unwrap()` and `return` immediately in case of error. + +## match(obj, ...lambdas: Lambda) + +For obj, execute lambdas that match the pattern. + +``` erg +match[1, 2, 3]: + (l: Int) -> log "this is type of Int" + [[a], b] -> log a, b + [...a] -> log a +# (one two three) +``` + +## del(x: ...T) -> NoneType | T + +Delete the variable `x`. However, built-in objects cannot be deleted. + +``` erg +a = 1 +del a # OK + +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 + +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 +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) + +Generates sieve type, rank 2 type. + +### `...` + +Expand a nested collection. It can also be used for pattern matching. + +``` 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} +``` + +## 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! + +Returns a mutable reference to a mutable object. \ No newline at end of file diff --git a/doc/EN/API/types.md b/doc/EN/API/types.md new file mode 100644 index 00000000..2eba4b08 --- /dev/null +++ b/doc/EN/API/types.md @@ -0,0 +1,262 @@ +# List of built-in Erg types + +Attributes of the type itself are not stored in the `.__dict__` and cannot be referenced from the instance + +## Fundamental types + +### Objects + +* `__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__`: returns the string representation (rich) of the object + +###Fmt + +* `__format__`: Returns a formatted string + +### Doc + +* `__doc__`: object description + +### Named + +* `__name__`: the name of the object + +### Pickles + +* `__reduce__`: Serialize objects with Pickle +* `__reduce_ex__`: __reduce__ that allows you to specify the protocol version + +## Object system + +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__`: Supertypes (`__mro__` is an array, but this one is a Set) +* `__basicsize__`: +* `__dictoffset__`: not supported by Evm +* `__flags__`: +* `__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__`: Returns the class from which the instance was created (automatically attached to objects created with `.new`) + +### Class + +* `__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`: object comparison function (==) +* `__ne__`: object comparison function (!=), with default implementation + +### Ord + +* `__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 + +### Bin Add + +* Implements `__add__(self, rhs: Self) -> Self`: `+` + +### Add 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__`: implements `**` (with default implementation) + +### Div R, O + +* Implements `__div__(self, rhs: Self) -> Self`: `/`, may panic due to 0 + +### BinDiv <: Div Self + +* `__mod__`: implement `%` (with default implementation) + +## numeric type + +### Num (= Add and Sub and Mul and Eq) + +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`: 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`: returns the numerator +* `denominator: Int`: Returns the denominator + +### Int (= Inherit Ratio) + +### Nat (= Inherit Int) + +* `times!`: run the proc self times + +## Other basic types + +### Bool + +* `__and__`: +* `__or__`: +* `not`: + +## Str (<: Seq) + +* `capitalize` +* `chomp`: remove newline characters +* `isalnum`: +* `isascii`: +* `isalpha`: +* `isdecimal`: +* `is sight`: +* `is identifier` +*`islower` +* `is numeric` +* `isprintable` +* `isspace` +* `is title` +* `isupper` +*`lower` +* `swapcase` +* `title` +* `upper` + +## others + +### Bits + +* `from_bytes`: Convert from Bytes +* `to_bytes`: Convert to Bytes (specify length and endian (byteorder)) +* `bit_length`: returns bit length + +### Iterable T + +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`: Create an Iterator. + +### Iterator T + +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`: Returns the first element and the remaining Iterator. +*`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 and ... + +* `next!`: Get the first element. + +## SizedIterator T = Iterator T and ... + +An Iterator over a finite number of elements. + +* `len`: +* `chain`: +* `count`: +* `is_empty`: +* `rev`: +* `next_back`: +* `nth_back`: +* `rfind`: +* `rfold`: +* `sum`: +* `max`: +* `min`: + +## Seq T = SizedIterable T and ... + +* `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 ...) + +* `__setitem__!`: +* `__delitem__!`: +* `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 elements +* `translate!` \ No newline at end of file diff --git a/doc/EN/API/types/classes/Array!(T).md b/doc/EN/API/types/classes/Array!(T).md new file mode 100644 index 00000000..51902435 --- /dev/null +++ b/doc/EN/API/types/classes/Array!(T).md @@ -0,0 +1,4 @@ +# Array! T + +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/EN/API/types/classes/Array(T).md b/doc/EN/API/types/classes/Array(T).md new file mode 100644 index 00000000..78300991 --- /dev/null +++ b/doc/EN/API/types/classes/Array(T).md @@ -0,0 +1,3 @@ +# Array T: Type + +Defined by `Array T = ArrayWithLen T, _`. There is a syntactic sugar called `[T]`. \ No newline at end of file diff --git a/doc/EN/API/types/classes/ArrayWithLen(T,N).md b/doc/EN/API/types/classes/ArrayWithLen(T,N).md new file mode 100644 index 00000000..c9dd51c3 --- /dev/null +++ b/doc/EN/API/types/classes/ArrayWithLen(T,N).md @@ -0,0 +1,34 @@ +# ArrayWithLen T: Type, N: Nat + +`[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 +assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] +``` + +* 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. + + ``` erg + assert[].all(_ -> False) + ``` + + ```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 +assert ["a", "b", "c", "b", "c", "b"].freq() \ +== [{"a", 1}, {"b": 3}, {"c": 2}] +``` \ No newline at end of file diff --git a/doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md new file mode 100644 index 00000000..0a6fed5c --- /dev/null +++ b/doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md @@ -0,0 +1,34 @@ +# ArrayWithLen T: Type, N: Nat + +`[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 +assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] +``` + +* 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. + + ``` erg + assert[].all(_ -> False) + ``` + + ```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 +assert ["a", "b", "c", "b", "c", "b"].freq() \ +== [{"a", 1}, {"b": 3}, {"c": 2}] +``` \ No newline at end of file diff --git a/doc/EN/API/types/classes/Class.md b/doc/EN/API/types/classes/Class.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/API/types/classes/Complex.md b/doc/EN/API/types/classes/Complex.md new file mode 100644 index 00000000..8e5bd75d --- /dev/null +++ b/doc/EN/API/types/classes/Complex.md @@ -0,0 +1,14 @@ +# Complex + +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 + +Num and Norm + +## methods + +* abs +* conjugate +* imag +* real \ No newline at end of file diff --git a/doc/EN/API/types/classes/Dict!.md b/doc/EN/API/types/classes/Dict!.md new file mode 100644 index 00000000..8fa22607 --- /dev/null +++ b/doc/EN/API/types/classes/Dict!.md @@ -0,0 +1,7 @@ +# Dict! K, V + +A type that represents a dictionary (hashmap). There is a syntactic sugar called `{K: V}`. + +## methods + +* invert!(self) -> Self! V, K \ No newline at end of file diff --git a/doc/EN/API/types/classes/Either.md b/doc/EN/API/types/classes/Either.md new file mode 100644 index 00000000..16f56740 --- /dev/null +++ b/doc/EN/API/types/classes/Either.md @@ -0,0 +1,12 @@ +# Either L, R = L or R + +A type that represents "either L or R". You can think of it as a two-limited form of the Or type. + +## methods + +* orl +* orr +* andl +* andr +* mapl +* mapr \ No newline at end of file diff --git a/doc/EN/API/types/classes/Float.md b/doc/EN/API/types/classes/Float.md new file mode 100644 index 00000000..387c4257 --- /dev/null +++ b/doc/EN/API/types/classes/Float.md @@ -0,0 +1,21 @@ +# Float size + +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 + +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, date: Nat) -> [Str] + Separate by dight digits. 3 with no arguments. \ No newline at end of file diff --git a/doc/EN/API/types/classes/Function(N).md b/doc/EN/API/types/classes/Function(N).md new file mode 100644 index 00000000..e210780b --- /dev/null +++ b/doc/EN/API/types/classes/Function(N).md @@ -0,0 +1,9 @@ +# Function N: Nat + +## methods of Function 1 + +* then(self, g: Self) -> Self + +``` erg +assert f(g(x)) == f.then(g) x +``` \ No newline at end of file diff --git a/doc/EN/API/types/classes/Inf.md b/doc/EN/API/types/classes/Inf.md new file mode 100644 index 00000000..cd8c3f71 --- /dev/null +++ b/doc/EN/API/types/classes/Inf.md @@ -0,0 +1,7 @@ +# Inf + +Inf is a class whose only instance is inf. +The main use of inf is with interval types. +For example, integer types greater than or equal to 2 are `2.. Self(L1+L2, R1+R2) + +normal addition. Addition of `Int` and `Nat` is defined here under the pretense that it is defined in each class. + +``` 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/EN/API/types/classes/Interval.md b/doc/EN/API/types/classes/Interval.md new file mode 100644 index 00000000..5492537d --- /dev/null +++ b/doc/EN/API/types/classes/Interval.md @@ -0,0 +1,18 @@ +# Interval begin, end := WellOrder + +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 +Months = 1..12 +Alphabet = "a".."z" +Weekdays = Monday..Friday +Winter = November..December or January..February +``` + +``` erg +0..1 # integer range +0.0..1.0 # real (rational) range +# or same for 0/1..1/1 +``` + +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/EN/API/types/classes/Iterator.md b/doc/EN/API/types/classes/Iterator.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/API/types/classes/Kind(N).md b/doc/EN/API/types/classes/Kind(N).md new file mode 100644 index 00000000..4a72aec9 --- /dev/null +++ b/doc/EN/API/types/classes/Kind(N).md @@ -0,0 +1,5 @@ +# Kind N: Nat + +```erg +Kind N: Nat = (Type; N) -> Type +``` diff --git a/doc/EN/API/types/classes/Matrix.md b/doc/EN/API/types/classes/Matrix.md new file mode 100644 index 00000000..eb926248 --- /dev/null +++ b/doc/EN/API/types/classes/Matrix.md @@ -0,0 +1,7 @@ +# Matrix T: Num, Shape: [M, N] + +A type that represents a matrix. It inherits from Tensor[M, N]. + +## def + +Inherit Tensor T, [M, N] \ No newline at end of file diff --git a/doc/EN/API/types/classes/Module.md b/doc/EN/API/types/classes/Module.md new file mode 100644 index 00000000..03b89e9f --- /dev/null +++ b/doc/EN/API/types/classes/Module.md @@ -0,0 +1,3 @@ +# Module + +## methods diff --git a/doc/EN/API/types/classes/Nat.md b/doc/EN/API/types/classes/Nat.md new file mode 100644 index 00000000..027d496a --- /dev/null +++ b/doc/EN/API/types/classes/Nat.md @@ -0,0 +1,18 @@ +# Nat + +A type that represents a natural number. Used for array indices and range types. + +##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/EN/API/types/classes/Neg.md b/doc/EN/API/types/classes/Neg.md new file mode 100644 index 00000000..2c369f3c --- /dev/null +++ b/doc/EN/API/types/classes/Neg.md @@ -0,0 +1,8 @@ +# Neg + +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 + +Inf<..-1 \ No newline at end of file diff --git a/doc/EN/API/types/classes/Never.md b/doc/EN/API/types/classes/Never.md new file mode 100644 index 00000000..c6cdea6b --- /dev/null +++ b/doc/EN/API/types/classes/Never.md @@ -0,0 +1,13 @@ +# Never + +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 +# Never <: Panic +f(): Panic = exit 0 # OK +g(): Never = panic() # TypeError +``` + +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/EN/API/types/classes/NonZero.md b/doc/EN/API/types/classes/NonZero.md new file mode 100644 index 00000000..c54965f7 --- /dev/null +++ b/doc/EN/API/types/classes/NonZero.md @@ -0,0 +1,30 @@ +# NonZeroN + +A class that represents a non-zero number. The safety of division by zero is guaranteed. + +```mermaid +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 \ No newline at end of file diff --git a/doc/EN/API/types/classes/Object.md b/doc/EN/API/types/classes/Object.md new file mode 100644 index 00000000..e7e2cf58 --- /dev/null +++ b/doc/EN/API/types/classes/Object.md @@ -0,0 +1,7 @@ +# Objects + +It is the supertype of all types. + +## methods + +* __sizeof__: Nat \ No newline at end of file diff --git a/doc/EN/API/types/classes/Operator.md b/doc/EN/API/types/classes/Operator.md new file mode 100644 index 00000000..a22e91b9 --- /dev/null +++ b/doc/EN/API/types/classes/Operator.md @@ -0,0 +1,7 @@ +# Operator [...T], O + +is the type of the operator. + +##def + +Inherit Func [...T], O \ No newline at end of file diff --git a/doc/EN/API/types/classes/Option.md b/doc/EN/API/types/classes/Option.md new file mode 100644 index 00000000..a66367d9 --- /dev/null +++ b/doc/EN/API/types/classes/Option.md @@ -0,0 +1,21 @@ +# Option T = T or NoneType + +A type that represents "may fail". + +## methods + +* unwrap(self, msg = "unwrapped a None value") -> T or Panic + +Extract it expecting the contents to be `T` type. If it is `None`, output `msg` and panic. + +``` 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/EN/API/types/classes/Pos.md b/doc/EN/API/types/classes/Pos.md new file mode 100644 index 00000000..c3d4ca6a --- /dev/null +++ b/doc/EN/API/types/classes/Pos.md @@ -0,0 +1,8 @@ +# Pos + +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.._` \ No newline at end of file diff --git a/doc/EN/API/types/classes/Ratio.md b/doc/EN/API/types/classes/Ratio.md new file mode 100644 index 00000000..938357f3 --- /dev/null +++ b/doc/EN/API/types/classes/Ratio.md @@ -0,0 +1,5 @@ +#Ratio + +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/EN/API/types/classes/Record.md b/doc/EN/API/types/classes/Record.md new file mode 100644 index 00000000..8e0bf5fc --- /dev/null +++ b/doc/EN/API/types/classes/Record.md @@ -0,0 +1,14 @@ +# Record + +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 +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/EN/API/types/classes/Result.md b/doc/EN/API/types/classes/Result.md new file mode 100644 index 00000000..64824ce6 --- /dev/null +++ b/doc/EN/API/types/classes/Result.md @@ -0,0 +1,7 @@ +# Result T, E + +``` erg +Result T, E <: Error = Either T, E +``` + +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/EN/API/types/classes/Str!.md b/doc/EN/API/types/classes/Str!.md new file mode 100644 index 00000000..a790d1d3 --- /dev/null +++ b/doc/EN/API/types/classes/Str!.md @@ -0,0 +1,3 @@ +# StrWithLen!N: Nat! = Inherit StrWithLenN + +A type that represents a variable-length string. \ No newline at end of file diff --git a/doc/EN/API/types/classes/Str.md b/doc/EN/API/types/classes/Str.md new file mode 100644 index 00000000..5a185e01 --- /dev/null +++ b/doc/EN/API/types/classes/Str.md @@ -0,0 +1,9 @@ +# Str + +(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 + +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/EN/API/types/classes/StrWithLen.md b/doc/EN/API/types/classes/StrWithLen.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/API/types/classes/Subroutine.md b/doc/EN/API/types/classes/Subroutine.md new file mode 100644 index 00000000..c7533cac --- /dev/null +++ b/doc/EN/API/types/classes/Subroutine.md @@ -0,0 +1,19 @@ +# Subroutines + +Base type of Func and Proc. + +## methods + +* return + +Interrupts a subroutine and returns the specified value. Useful for quickly escaping from a nest. + +``` 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/EN/API/types/classes/Tensor.md b/doc/EN/API/types/classes/Tensor.md new file mode 100644 index 00000000..98488e92 --- /dev/null +++ b/doc/EN/API/types/classes/Tensor.md @@ -0,0 +1,24 @@ +# Tensor Shape: [Nat; N] + + 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.arrange(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/EN/API/types/classes/TransCell(T).md b/doc/EN/API/types/classes/TransCell(T).md new file mode 100644 index 00000000..9b042627 --- /dev/null +++ b/doc/EN/API/types/classes/TransCell(T).md @@ -0,0 +1,12 @@ +# TransCell! T: Type! + +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 +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/EN/API/types/classes/Tuple.md b/doc/EN/API/types/classes/Tuple.md new file mode 100644 index 00000000..fb4b33ee --- /dev/null +++ b/doc/EN/API/types/classes/Tuple.md @@ -0,0 +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) + ``` + +* zip_by self, op, other + + 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/EN/API/types/classes/Type.md b/doc/EN/API/types/classes/Type.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/API/types/classes/Vector.md b/doc/EN/API/types/classes/Vector.md new file mode 100644 index 00000000..ed14caa1 --- /dev/null +++ b/doc/EN/API/types/classes/Vector.md @@ -0,0 +1,3 @@ +# Vector T: Num, N: Nat + +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/EN/API/types/patches/BinOp.md b/doc/EN/API/types/patches/BinOp.md new file mode 100644 index 00000000..50374b29 --- /dev/null +++ b/doc/EN/API/types/patches/BinOp.md @@ -0,0 +1,7 @@ +# BinOp L, R, O + +The type of the binary operator. + +## Patches + +Operator [L, R], O \ No newline at end of file diff --git a/doc/EN/API/types/patches/UnaryOp.md b/doc/EN/API/types/patches/UnaryOp.md new file mode 100644 index 00000000..bdc35fe6 --- /dev/null +++ b/doc/EN/API/types/patches/UnaryOp.md @@ -0,0 +1,7 @@ +# Unary Op T, O + +The type of the unary operator. + +##def + +Operator [T], O \ No newline at end of file diff --git a/doc/EN/API/types/traits/Add(R,O).md b/doc/EN/API/types/traits/Add(R,O).md new file mode 100644 index 00000000..952dd1b8 --- /dev/null +++ b/doc/EN/API/types/traits/Add(R,O).md @@ -0,0 +1,34 @@ +# Add R + +``` erg +Add R = Trait { + .AddO = Type + .`_+_` = (Self, R) -> Self.AddO +} +``` + +`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 +`_+_`(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 +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 +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/EN/API/types/traits/Div(R,O).md b/doc/EN/API/types/traits/Div(R,O).md new file mode 100644 index 00000000..3f0906d6 --- /dev/null +++ b/doc/EN/API/types/traits/Div(R,O).md @@ -0,0 +1,9 @@ +# Div R, O + +Use `SafeDiv` if there are no errors due to division by zero. + +``` erg +Div R, O = Trait { + .`/` = Self.(R) -> O or Panic +} +``` \ No newline at end of file diff --git a/doc/EN/API/types/traits/Eq.md b/doc/EN/API/types/traits/Eq.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/API/types/traits/Into.md b/doc/EN/API/types/traits/Into.md new file mode 100644 index 00000000..4b43a843 --- /dev/null +++ b/doc/EN/API/types/traits/Into.md @@ -0,0 +1,11 @@ +# Into T + +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/EN/API/types/traits/Iterable.md b/doc/EN/API/types/traits/Iterable.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/API/types/traits/Num.md b/doc/EN/API/types/traits/Num.md new file mode 100644 index 00000000..a49e9815 --- /dev/null +++ b/doc/EN/API/types/traits/Num.md @@ -0,0 +1,16 @@ +# 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` \ No newline at end of file diff --git a/doc/EN/API/types/traits/Ord.md b/doc/EN/API/types/traits/Ord.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/API/types/traits/SafeDiv(R,O).md b/doc/EN/API/types/traits/SafeDiv(R,O).md new file mode 100644 index 00000000..d214d620 --- /dev/null +++ b/doc/EN/API/types/traits/SafeDiv(R,O).md @@ -0,0 +1,8 @@ +# SafeDiv R, O + +``` erg +SafeDiv R, O = Subsume Div, { + @Override + .`/` = Self.(R) -> O +} +``` \ No newline at end of file diff --git a/doc/EN/API/types/traits/Sample.md b/doc/EN/API/types/traits/Sample.md new file mode 100644 index 00000000..a51d45ac --- /dev/null +++ b/doc/EN/API/types/traits/Sample.md @@ -0,0 +1,31 @@ +# 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. + +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 is sampled in 64bit range by default +print! Int. sample!() # 1313798 +print! {x = Int; y = Int}.sample!() # {x = -32432892, y = 78458576891} +``` + +Below is an implementation example of `Sample`. + +``` erg +EmailAddress = Class {header = Str; domain = Str}, Impl=Sample and Show +@Impl Show +Email address. + show self = "{self::header}@{self::domain}" +@Impl Sample +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} +``` \ No newline at end of file diff --git a/doc/EN/API/types/traits/Seq.md b/doc/EN/API/types/traits/Seq.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/API/types/traits/Show.md b/doc/EN/API/types/traits/Show.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/API/types/traits/Unpack.md b/doc/EN/API/types/traits/Unpack.md new file mode 100644 index 00000000..2b1c1d40 --- /dev/null +++ b/doc/EN/API/types/traits/Unpack.md @@ -0,0 +1,13 @@ +# Unpack + +marker trait. When implemented, elements can be decomposed by pattern matching like records. + +``` 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/EN/compiler/TODO_hint.md b/doc/EN/compiler/TODO_hint.md new file mode 100644 index 00000000..3844f83f --- /dev/null +++ b/doc/EN/compiler/TODO_hint.md @@ -0,0 +1,4 @@ +# 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/EN/compiler/TODO_recov_suggest.md b/doc/EN/compiler/TODO_recov_suggest.md new file mode 100644 index 00000000..a11955fa --- /dev/null +++ b/doc/EN/compiler/TODO_recov_suggest.md @@ -0,0 +1,11 @@ +# 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/EN/compiler/TODO_warn.md b/doc/EN/compiler/TODO_warn.md new file mode 100644 index 00000000..0ba2ebf2 --- /dev/null +++ b/doc/EN/compiler/TODO_warn.md @@ -0,0 +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)? diff --git a/doc/EN/compiler/abandoned.md b/doc/EN/compiler/abandoned.md new file mode 100644 index 00000000..483fe374 --- /dev/null +++ b/doc/EN/compiler/abandoned.md @@ -0,0 +1,10 @@ +# Abandoned/rejected language specifications + +## Overloading (ad-hoc polymorphism) + +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 + +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/EN/compiler/hir.md b/doc/EN/compiler/hir.md new file mode 100644 index 00000000..896e6e61 --- /dev/null +++ b/doc/EN/compiler/hir.md @@ -0,0 +1,148 @@ +# High-level Intermediate Representation (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 +v = ![] +for! 0..10, i => + v.push!i +log v.sum() +``` + +The AST generated from this code looks like this: + +``` erg +AST(Module[ + VarDef{ + sig: VarSignature { + pat: VarPattern::Ident(None, VarName("v")), + spec_t: None, + }, + op: "=", + body: Block[ + Unary Op { + op: "!", + expr: Array([]), + }, + ], + }, + Call { + obj: Accessor::Local("for!"), + args: [ + BinOp{ + op: "..", + lhs: Literal(0), + rhs: Literal(10), + }, + Lambda{ + sig: LambdaSignature { + params: [ + Param Signature { + 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: [], + } + ], + } +]) +``` + +And the HIR generated from the AST looks like this: + +``` 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: [ + Param Signature { + 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 + } + ], + } +]) +``` + +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/EN/compiler/index.md b/doc/EN/compiler/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/compiler/inference.md b/doc/EN/compiler/inference.md new file mode 100644 index 00000000..4f513eb2 --- /dev/null +++ b/doc/EN/compiler/inference.md @@ -0,0 +1,438 @@ +# type inference algorithm + +> __Warning__: This section is being edited and may contain some errors. + +The notation used below is shown. + +``` 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 +v = ![] +v.push! 1 +print! v +``` + +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. 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: + 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]} + 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 + +## 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 { + ... + Var(RcCell>), // a reference to the type of other expression, see docs/compiler/inference.md + ... +} +``` + +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) ). + +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 + +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. + +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 +gen ?T = 'T +inst 'T = ?T (?T ∉ Γ) +``` + +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. + +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 +unify(?T, Int) == Ok(()) # ?T == (Int) + +# S is the type assignment rule, T is the applicable type +subst(S: {?T --> X}, T: ?T -> ?T) == X -> X +# Type assignment rules are {?T --> X, ?U --> T} +subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y +``` + +## semi-unification + +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 +# If the formal parameter type is T +f(x: T): T = ... + +a: U +# 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 +x -> + y = x + y +``` + +First, Erg allocates type variables as follows: +The type of y is also unknown, but is left unassigned for now. + +``` erg +x(: ?T) -> + y = x + y +``` + +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 +x(: ?T) -> + y = x (: inst ?T) + 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 +x(: ?T) -> + y(:gen?T) = x(:?T) + y +``` + +``` erg +x(: ?T) -> + y(: 'T) = x + y +``` + +The type of y is now a quantified type variable `'T`. In the next line, `y` is used immediately. Concrete. + +``` 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 +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 +# normal type variable +?T<1>, ?T<2>, ... +# type variable with subtype constraint +?T<1>(<:U) or ?T(<:U)<1>, ... +``` + +Let's try again. + +``` erg +x -> + y = x + y +``` + +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 +# level 1 +x (: ?T<2>) -> + # level 2 + y = x + y +``` + +First, instantiate the rvalue `x`. Same as before, nothing changed. + +``` 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 +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 +``` + +That is, the lvalue `y` has type `?T<2>`. + +``` erg +x (: ?T<2>) -> + # ↓ not generalized + y(: ?T<2>) = x + 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 +x (: ?T<2>) -> + y(: ?T<2>) = x + y (: inst ?T<2>) +``` + +``` 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 +fx, y = id(x) + y +id x = x + +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 +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 +# BAD +f x (: ?V<2>), y (: ?W<2>) = + # ?V<2>(<: ?T<1>) + # ?T<1>(:> ?V<2>) + id(x) (: ?U<1>) + y (: ?W<2>) +``` + +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 +# 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>)) # Inherit the constraints of ?L + # ?L<2> --> ?U<1> + # ?R<2> --> ?W<2> (not ?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 +``` + +When defining, raise the level so that it can be generalized. + +``` 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 +# ?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>) +``` + +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 +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)) +``` + +Type variables are bounded to the smallest type that has an implementation. + +``` 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>) +# 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 # 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 +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 +fx, y = id(x) + y +id x = x + +f(10, 1) +``` \ No newline at end of file diff --git a/doc/EN/compiler/overview.md b/doc/EN/compiler/overview.md index 3d43120c..8cd43ef0 100644 --- a/doc/EN/compiler/overview.md +++ b/doc/EN/compiler/overview.md @@ -1,36 +1,36 @@ -# Overview of `erg +# overview of `erg` -This section introduces the function of each layer and especially important functions and methods. +We will introduce the function of each layer and the particularly important functions and methods. -## 1. Lexical analysis +## 1. Lexical Analysis -* `Lexer` performs lexical analysis. `Lexer::next` (`Lexer` is implemented as an iterator) handles the main logic of lexical analysis. `Token` is output as a result of parsing. +* 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. Parsing -* `Parser` performs the parsing. Especially important is `Parser::parse_expr`. The result of parsing is `AST`, a collection of `ast::Expr`. +* `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. Desugaring -* `Desugarer` performs desugaring. An `AST` is output. +* Desugaring is done by `Desugarer`. `AST` will be output. ## 4. Type checking/type inference -* `ASTLowerer` performs typing. Type checking is mainly done by `Context`. Of particular importance are `Context::supertype_of` (to determine subtype relationships), `Context::unify/sub_unify` (to unify/semi-unify type variables) and `Context::init_builtin_*` (to define built-in API). The `HIR` is output as a result of the analysis. +* `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. Side Effect Check +## 5. Side effect check -* `SideEffectChecker` does this. +* `SideEffectChecker` does. ## 6. Ownership check -* Performed by `OwnershipChecker`. +* `OwnershipChecker` does. -## 7. Bytecode generation +## 7. Bytecode Generation -* `CodeGenerator` converts `HIR` to `CodeObj`. The `CodeObj` holds the bytecode and execution settings. Especially important is `CodeGenerator::compile_expr`. +* `CodeGenerator` converts `HIR` to `CodeObj`. `CodeObj` holds bytecode and execution configuration. Of particular importance is `CodeGenerator::compile_expr`. --- -* All the above processes are put together by `Compiler` as a facade. -* Execution of the generated bytecode is of course done by Python, which is called by `DummyVM`. +* 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/EN/compiler/refinement_subtyping.md b/doc/EN/compiler/refinement_subtyping.md new file mode 100644 index 00000000..f6695330 --- /dev/null +++ b/doc/EN/compiler/refinement_subtyping.md @@ -0,0 +1,149 @@ +# Sieve type + +The sieve type is the following type. + +``` erg +{I: Int | I >= 0} +{S: StrWithLen N | N >= 1} +{T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0} +``` + +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} +* 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} + +## 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+ε}` +* 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}` +* 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 + * {...} <: _ = 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 )) + * basic formula + * {I >= l} <: {I >= r} = (l >= r) + * {I <= l} <: {I <= r} = (l <= r) + * {I >= l} <: {I <= r} = False + * {I <= l} <: {I >= r} = False + +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` +* 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)` +* 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 +=> {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/EN/compiler/trait_method_resolving.md b/doc/EN/compiler/trait_method_resolving.md new file mode 100644 index 00000000..f0d8b1a6 --- /dev/null +++ b/doc/EN/compiler/trait_method_resolving.md @@ -0,0 +1,95 @@ +# Resolving patch methods + +`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 +1.times do: + log "hello world" +``` + +`.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. + +~ + +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. + +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 +provided_method_table = { + ... + "foo": [Foo], + ... + ".times": [Nat, Foo], + ... +} +``` + +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 + +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 +o.method(x) -> P.method(o, x) +``` + +## method resolution for universal patches + +Define a patch like this: + +``` 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 +assert (Int -> Int).type == Int +``` + +First, `FnType(T)` is registered in `provided_method_table` in the following format. + +``` erg +provided_method_table = { + ... + "type": [FnType(T)], + ... +} +``` + +`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 +assert FnType(Int).type == Int +``` \ No newline at end of file diff --git a/doc/EN/compiler/transpile.md b/doc/EN/compiler/transpile.md new file mode 100644 index 00000000..0f640339 --- /dev/null +++ b/doc/EN/compiler/transpile.md @@ -0,0 +1,90 @@ +# How is Erg code transpiled to Python code? + +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 + +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 +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' +``` + +It will also be converted to a simple tuple if it can be further optimized. + +## Polymorphic Type + +> WIPs + +## Instant Scope + +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 +x = + 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 +x = + y = 1 + y+1 +``` + +```python +def _(): + x=1 + y = x + return y + 1 +x = _() +``` + +## Visibility + +It does nothing for public variables as it is Python's default. +Private variables are handled by mangling. + +``` 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/EN/compiler/type_var_normalization.md b/doc/EN/compiler/type_var_normalization.md new file mode 100644 index 00000000..3c4fccfc --- /dev/null +++ b/doc/EN/compiler/type_var_normalization.md @@ -0,0 +1,39 @@ +# Normalization + +* 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` + + 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` + + 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` \ No newline at end of file diff --git a/doc/EN/dev_guide/branches.md b/doc/EN/dev_guide/branches.md index ca0a2bdf..236036e7 100644 --- a/doc/EN/dev_guide/branches.md +++ b/doc/EN/dev_guide/branches.md @@ -1,5 +1,7 @@ # Branch naming and operation policy +* Basically, development is done in one `main` branch (monorepo development). Create a `feature-*` branch or `issue-*` branch only when it is difficult to work without branching. + ## main * main development branch diff --git a/doc/EN/dev_guide/build_features.md b/doc/EN/dev_guide/build_features.md index 27013652..d31e879d 100644 --- a/doc/EN/dev_guide/build_features.md +++ b/doc/EN/dev_guide/build_features.md @@ -2,13 +2,13 @@ ## debug -Put into debug mode. This will log the behavior of Erg internally as it happens. +Enter debug mode. As a result, the behavior inside Erg is sequentially displayed in the log. Independent of Rust's `debug_assertions` flag. ## japanese Set the system language to Japanese. -In this build, Erg internal options, help (help, copyright, license, etc.) and error messages are guaranteed to be in Japanese. +Erg internal options, help (help, copyright, license, etc.) and error display are guaranteed to be Japanese. ## simplified_chinese @@ -16,4 +16,4 @@ Set the system language to Simplified Chinese. ## traditional_chinese -Set the system language to Traditional Chinese. +Set the system language to Traditional Chinese. \ No newline at end of file diff --git a/doc/EN/dev_guide/directories.md b/doc/EN/dev_guide/directories.md index 950028fb..998b482a 100644 --- a/doc/EN/dev_guide/directories.md +++ b/doc/EN/dev_guide/directories.md @@ -1,24 +1,24 @@ -# Directory Structure of Erg +# Erg repository directory structure ```console - └─┬ assets: images - ├─ CODE_OF_CONDUCT: Code of Conduct - ├─┬ compiler - │ ├─ erg_common: common utilities - │ ├─ erg_compiler: Compiler - │ └─ erg_parser: Parser - ├─┬ doc - │ ├─┬ EN - │ │ ├─ API: Erg standard API - │ │ ├─ compiler: about implementation of the compiler - │ │ ├─ dev_guide: guide for developers & contributors - │ │ ├─ python: Knowledge of Python required for Erg development - │ │ ├─ syntax: syntax of Erg - │ │ └─ tools: about Erg's CLI tools - │ └─┬ JA - │ ... - ├─ examples: sample code - ├─ library: Erg libraries - ├─ src: main.rs & driver - └─ tests: test code -``` + └─┬ assets: images, etc. + ├─ CODE_OF_CONDUCT: Code of Conduct + ├─┬ compiler + │ ├─ erg_common: common utility + │ ├─ erg_compiler + │ └─ erg_parser: Parser + ├─┬doc + │ ├─┬ EN + │ │ ├─ API: Erg standard API + │ │ ├─ compiler: About compiler implementation + │ │ ├─ dev_guide: Guide for developers and contributors + │ │ ├─ python: Python knowledge required for Erg development + │ │ ├─ syntax: Erg syntax + │ │ └─ tools: Erg command line tools + │ └─┬ JA + │ ... + ├─ examples: sample code + ├─ library: Erg script library + ├─ src: directory where main.rs and driver are placed + └─ tests: test code +``` \ No newline at end of file diff --git a/doc/EN/dev_guide/doc_guideline.md b/doc/EN/dev_guide/doc_guideline.md index 0d72069f..26f717a9 100644 --- a/doc/EN/dev_guide/doc_guideline.md +++ b/doc/EN/dev_guide/doc_guideline.md @@ -2,10 +2,12 @@ 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 document is out-of-date, follow [these instructions](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362) to update it. +* 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 See this for how to write footnotes. [↩](#f1) +1 See this for how to write footnotes. [↩](#f1) \ No newline at end of file diff --git a/doc/EN/dev_guide/env.md b/doc/EN/dev_guide/env.md index 9e977410..ff6ab791 100644 --- a/doc/EN/dev_guide/env.md +++ b/doc/EN/dev_guide/env.md @@ -1,19 +1,19 @@ -# Development Environment +# Development environment -## Need to install +## 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 interpreter -## Recommended +## Recommendation * Editor: Visual Studio Code -* VSCode Extensions: Rust-analyzer, GitLens, Git Graph, GitHub Pull Requests and Issues, Markdown All in One, markdownlint -* OS: Windows 10/11 | Ubuntu 20.04/22.04 | MacOS Monterey -* Others: pyenv, mold +* 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/EN/dev_guide/faq_syntax.md b/doc/EN/dev_guide/faq_syntax.md index 49b02ced..6a34452a 100644 --- a/doc/EN/dev_guide/faq_syntax.md +++ b/doc/EN/dev_guide/faq_syntax.md @@ -1,112 +1,116 @@ # Erg design's "Why" and Answers -## Why do Erg's have an ownership system but also coexist with the reference counting system? +## Why coexist with GC when we have an ownership system? -This is because Erg's motivation for introducing an ownership system is not for "memory management that does not rely on GC" like Rust. -To begin with, Erg is currently a language that is transpiled into Python bytecode, so GC is used after all. -Erg's aim in introducing the ownership system is "localization of mutable state"; in Erg, mutable objects have the concept of ownership. -This is because shared mutable state can easily become a breeding ground for bugs and even violates type safety (see [here](./syntax/type/advanced/shared.md#SharedReference). +Erg's motivation for introducing an ownership system is not for "memory management without relying on GC" like Rust. +In the first place, Erg is currently a language that is reduced to Python bytecode, so GC is used after all. +The aim of Erg's ownership system is ``localization of mutable state''. Erg has a notion of ownership attached to mutable objects. +This is because shared mutable state is prone to bugs and even violates type safety (see [here](../syntax/type/advanced/shared.md#SharedReference)). It's a judgmental decision. -## Why are the parentheses surrounding type parameters || instead of <> or []? +## Why are the braces around type parameters || instead of <> or []? -Because `<>` and `[]` cause syntax conflicts. +This is because `<>` and `[]` cause syntax conflicts. -```erg +``` erg +# version [] id[T: Type] [t]: [T] = t -y = id[Int] # is this a function or array accessing? - +y = id[Int] # is this a function? +# <> version id {t: T} = t -y = (id < Int, 1 > 1) # is this a tuple of bools or a call? - -id{T: Type} {t: T} = t # conflicts with record pattern -y = id{Int} - +y = (id 1) # Is this a tuple? +# {} version +id {T: Type} {t: T} = t +y = id{Int} # is this a function? +# || version id|T: Type| t: T = t y = id|Int| # OK ``` -## The type of {i = 1} is {i = Int}, but in OCaml and other languages it is {i: Int}. Why did Erg adopt the former syntax? +## The type of {i = 1} is {i = Int}, but in OCaml etc. it is {i: Int}. Why did Erg adopt the former syntax? -Because Erg is designed to treat the type itself as a value. +This is because Erg is designed so that the type itself can also be treated as a value. -```erg +``` erg A = [Int; 3] assert A[2] == Int T = (Int, Str) assert T.1 == Str D = {Int: Str} -assert D[Int] == Str +assert D[Int] == ​​Str S = {.i = Int} assert S.i == Int ``` -## Are there any plans to implement macros in Erg? +## Any plans to implement macros in Erg? -No. Macros have four main purposes: first, they are compile-time calculations. This is the role of compile-time functions in Erg. -The second is to delay code execution. The third is common processing, for which polymorphic functions and all-symmetric types are better solutions than macros. -Thus, the type system in Erg takes most of the functionality of macros on its shoulders, so there is no motivation to implement it. +Not currently. Macros have four main purposes. The first is compile-time computation. This is what compile-time functions do in Erg. +The second is code execution delays. This can be replaced with a do block. The third is the commonality of processing, for which polycorrelation and universal types are a better solution than macros. The fourth is automatic code generation, but this is not possible in Erg because it reduces readability. +Since the Erg type system takes over most of the functionality of macros, there is no motivation to introduce them. -## Why is there no exception mechanism in Erg? +## Why doesn't Erg have an exception mechanism? -Because in many cases, error handling with the `Result` type is a better solution. The `Result` type is a common error handling technique used in many relatively new programming languages. +Because in many cases error handling with the `Result` type is a better solution. The `Result` type is a common error handling technique used in relatively new programming languages. -Erg allows the `?` operator allows you to write without much awareness of errors. +In Erg, the `?` operator makes writing error-free. -```erg +``` erg read_file!() = - f = open!("foo.txt")? # If it fails, it returns an error immediately, so `f` is of type `File` + f = open!("foo.txt")? # Returns an error immediately if it fails, so f is of type File f.read_all!() -# `try` procedure can be used to catch and process like an exception +# Capturing like exceptions is also possible with the try procedure try!: - do!: + do! s = read_file!()? - print! s + print!s e => - # Blocks to execute when an error occurs + # block to execute when an error occurs print! e exit 1 ``` -When Python functions are imported, by default they are all considered to be functions with exceptions (if they are not typed manually), and their return type is of type `Result`. -If it is known that an exception will not be sent, it is made explicit by `assert`. +When introducing Python functions, by default they are all assumed to be functions containing exceptions, with a return type of `Result`. +If you know it won't throw an exception, make it explicit with `assert`. + +Another reason Erg does not introduce an exception mechanism is that it plans to introduce features for parallel programming. +This is because the exception mechanism is not compatible with parallel execution (it is troublesome to deal with cases such as when multiple exceptions occur due to parallel execution). ## Erg seems to eliminate Python features that are considered bad practice, why didn't you do away with inheritance? -Because some classes in the Python library are designed to be inherited, and completely eliminating inheritance would cause problems in their use. -However, in Erg, classes are `Final` by default, and multiple and multi-layer inheritance is prohibited in principle, so inheritance can be used relatively safely. +This is because Python libraries have classes that are designed on the assumption that they will be inherited, and if inheritance is completely abolished, problems will arise in their operation. +However, in Erg, classes are final by default and multiple/multilevel inheritance is prohibited in principle, so inheritance can be used relatively safely. -## Why does subtype inference for polymorphic functions point to nominal traits by default? +## Why do polymorphic subtype inferences point to nominal traits by default? -Because pointing to structural traits by default complicates type specification and may introduce unintended behavior by the programmer. +Pointing to structural traits by default complicates typing and can introduce behavior unintended by the programmer. -```erg +``` erg # If T is a subtype of a structural trait... -# f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T +# f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T. f|T| x, y: T = x + y - x # T is a subtype of a nominal trait # g: |T <: Add() and Sub()| (T, T) -> T g|T| x, y: T = x + y - x ``` -## Will Erg implement the ability to define its own operators? +## Will Erg not implement the ability to define its own operators? -A: There are no plans to do so. The main reason is that allowing the definition of custom operators raises the question of how to handle the concatenation order. Scala and Haskell, which allow the definition of custom operators, have different approaches, and this can be seen as evidence of a syntax that can lead to differences in interpretation. This can be seen as evidence of a syntax that can lead to differences in interpretation, and also has the disadvantage of creating code with low readability. +A: There are no plans for that. The main reason is that allowing the definition of custom operators raises the question of what to do with their associativity. Scala and Haskell, which can define their own operators, handle them differently, but this can be seen as proof that the grammar can lead to different interpretations. Another disadvantage of custom operators is that they can create code that is not readable. -## Why did Erg do away with augmented assignment operators like `+=`? +## Why did Erg deprecate extended assignment operators like +=? -First of all, variables are not mutable in Erg. In other words, reassignment is not possible. Once an object is assigned to a variable, it is bound to that variable forever until it is released out of scope. Once this is understood, the story is simple. For example, `i += 1` means `i = i + 1`, but such a construction is incorrect because variables are not reassignable. Another design principle of Erg is that operators have no side effects, and while Python generally does this, for some objects, such as Dict, the augmented assignment operator changes the internal state of the object. This is not a very beautiful design. -That is why augmented assignment operators have been deprecated in its entirety. +First, there is no variable mutability in Erg. In other words, it cannot be reassigned. Once an object is bound to a variable, it remains bound to that variable until it goes out of scope and is freed. Mutability in Erg means object mutability. Once you know this, the story is easy. For example, `i += 1` means `i = i + 1`, but such syntax is illegal because variables are not reassigned. Another Erg design principle is that operators should not have side effects. Python is mostly like that, but for some objects such as Dict, extended assignment operators change the internal state of the object. This is not a very beautiful design. +That's why extended assignment operators are obsolete altogether. -## Why does Erg give special grammatical treatment to objects with side effects? +## Why does Erg syntactically specialize objects with side effects? -Localization of side effects is an important part of code maintainability. +Localizing side effects is an important aspect of code maintainability. -However, there are certainly ways to avoid giving side effects special linguistic treatment. For example, procedures can be substituted with algebraic effects (features on the type system). -But such congruence is not always correct. For example, Haskell did not treat strings as special, just arrays of characters, but this abstraction was wrong. +But there is certainly a way to get around side effects without linguistic specialization. For example, procedures can be substituted with algebraic effects (functions on the type system). +But such a union is not always correct. For example, Haskell treats strings as just arrays of characters without special treatment, but this abstraction is wrong. -In what cases can we say that unification was wrong? One indicator is "does the congruence make the error message difficult to read? -The Erg designers decided that the error messages would be easier to read if side effects were treated specially. +In what cases could it be said that union was wrong? One indicator is "whether the unification makes the error message less readable". +The Erg designers decided that giving special treatment to side effects would make error messages easier to read. -Erg has a powerful type system, but it does not dominate everything with types. -If it did, it would end up the same way as Java, which tried to dominate everything with classes. +Erg has a strong type system, but types don't rule everything. +If you do, you'll end up with the same fate that Java tried to rule everything with classes. \ No newline at end of file diff --git a/doc/EN/dev_guide/i18n_messages.md b/doc/EN/dev_guide/i18n_messages.md index 7736ce80..605913ad 100644 --- a/doc/EN/dev_guide/i18n_messages.md +++ b/doc/EN/dev_guide/i18n_messages.md @@ -1,59 +1,58 @@ # Multilingualization of Messages -Erg is working on making all messages (start, option, doc, hint, warning, error messages, etc.) multilingual within the language. -This project is open to anyone without detailed knowledge of Rust or Erg. Your participation is always welcome. +Erg is making its messages (start, options, documentation, hints, warnings, error messages, etc.) multilingual. +You don't need detailed knowledge of Rust or Erg to participate in this project. We appreciate your cooperation. -Here is how to translate them. +The method for multilingualization is explained below. -## Search `switch_lang!` +## Look for `switch_lang!` -In the Erg source code, look for the item `switch_lang!` (use grep or your editor's search function). +Find the entry `switch_lang!` in the Erg source code (use grep or your editor's search function). You should find something like this: ```rust switch_lang!( - "japanese" => format!("この機能({name})はまだ正式に提供されていません"), + "japanese" => format!("This feature ({name}) is not officially available yet"), "english" => format!("this feature({name}) is not implemented yet"), ), ``` -This message is currently supported only in Japanese and English. Let's add a simplified Chinese message as a test. +This message is currently supported in Japanese and English only. Let's try adding a simplified Chinese message. -## Add a New Message +## add a message -Add translated messages as you see the content in other languages. Don't forget the comma (`,`) last. +Add translated messages while viewing content in other languages. Don't forget the comma (`,`) at the end. ```rust switch_lang!( - "japanese" => format!("この機能({name})はまだ正式に提供されていません"), - "simplified_chinese" => format!("该功能({name})还没有正式提供"), + "japanese" => format!("This feature ({name}) is not officially available yet"), + "simplified_chinese" => format!("This function ({name}) has been officially provided"), "english" => format!("this feature({name}) is not implemented yet"), ), ``` -Note that English is the default and must come last. -The `{name}` part is a Rust formatting feature that allows you to embed the contents of a variable (`name`) into a string. +Note that English is the default and should always come last. +The `{name}` part is Rust's formatting feature that allows you to embed the contents of a variable (`name`) into a string. ## Build -Now, let's build with the `--features simplified_chinese` option. +Now let's build with the `--features simplified_chinese` option. screenshot_i18n_messages -We did it! +You did it, did not you! -## FAQ +## FAQs Q: What does a specification like `{RED}{foo}{RESET}` mean? -A: {RED} and subsequent letters will be displayed in red. {RESET} will restore the color. +A: Everything after {RED} is displayed in red. {RESET} restores the color. -Q: If I want to add my language, how do I replace the `"simplified_chinese" =>` part? - -The following languages are currently supported: +Q: If I want to add my own language, how do I replace the `"simplified_chinese" =>` part? +A: We currently support the following languages: * "english" (default) -* "japanese" -* "simplified_chinese" -* "traditional_chinese" +* "japanese" (Japanese) +* "simplified_chinese" (Simplified Chinese) +* "traditional_chinese" (Traditional Chinese) -If you would like to add languages other than these, please make a request. +If you would like to add languages ​​other than these, please make a request. \ No newline at end of file diff --git a/doc/EN/dev_guide/rust_code_guideline.md b/doc/EN/dev_guide/rust_code_guideline.md index e28e0a3c..fa26af68 100644 --- a/doc/EN/dev_guide/rust_code_guideline.md +++ b/doc/EN/dev_guide/rust_code_guideline.md @@ -1,23 +1,23 @@ # Guidelines for Rust code -## Local rules +## local rules -* Use `log!` for debugging output (use `println!` etc. for output processing required for release). -* Unused or internal variables and methods (private and used only for specific functions) should be prefixed with `_`. To avoid conflicts with reserved words, add one trailing `_`. +* 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. -## Encouraged code +## Recommended code -* Define and use domain-specific Enums instead of numeric enumerations or bool. -* Minimize access modifiers. Use `pub(mod)` or `pub(crate)` in preference even when publishing. -* Explicitly convert iterable objects in for expressions to iterators (`for i in x.iter()` instead of `for i in x`). -* Evaluate Lazily. For example, use `unwrap_or_else` instead of `unwrap_or` if `default` is not a literal. +* 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`. -## Unsolicited code +## Code not encouraged -* Use return-type overloading a lot. Specifically, code that uses non-trivial `.into` too often. This is because the result of type inference may be counter-intuitive. In this case, it is recommended to use `from` instead. -* Use `Deref` a lot. This causes practically the same problem as inheritance. +* 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 changes its decision depending on the context +## Code that makes decisions based on context * Define unused helper methods. -* Uses `unwrap`, `clone`. In some cases, there is no choice but to do so. +* 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/EN/dev_guide/terms.md b/doc/EN/dev_guide/terms.md index cd74c39f..d3bbc42f 100644 --- a/doc/EN/dev_guide/terms.md +++ b/doc/EN/dev_guide/terms.md @@ -1,10 +1,13 @@ -# Dictionary of Terminology +# Glossary ## symbol ### ! -### [#](../syntax/00_basic.md/#comments) +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/# comment) ### $ @@ -144,7 +147,7 @@ ## L -### let-polymorphism -> [rank1 polymorphism] +### let-polymorphism -> [rank 1 polymorphism] ### [log] @@ -206,7 +209,7 @@ ## T -### Trait +### Traits ### [True] @@ -227,3 +230,610 @@ ## Y ## 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 +sum = !0 +for! 0..10, i => + sum.add!i + +assert sum == 55 +``` + +### Value Object + +In Erg, equivalent to base object. It can be evaluated at compile time and has a trivial comparison method. + +### [Attachment patch](../syntax/29_decorator.md#attach) + +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. + +### [Dependent type](../syntax/type/dependent_type.md) + +A type whose argument is a value (idiomatically, not a type). + +### immutable -> [immutable] + +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. + +### [instant block](../syntax/00_basic.md#expression separator) + +``` erg +x = + y = f(a) + z = g(b,c) + y+z +``` + +### index + +of the form `x[i]`, or the `i` part thereof. We call `x` an Indexable object. + +### [indent](../syntax/00_basic.md#indent) + +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] + +### [operator](../syntax/06_operator.md) + +An object that applies an operation to its operands. or a symbol denoting that object. + +* [operator binding strength] + +### Override + +Overriding superclass methods in subclasses. +In Erg you have to add `Override` decorator when overriding. + +### [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 + +### [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. + +* [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] + +### [function](../syntax/04_function.md) + +A subroutine with no side effects. + +* [Functional programming](../syntax/23_scope.md#Avoiding mutable stateFunctional programming) + +### base type + +### nominative + +Distinguish by name rather than by symmetrical structure. + +* [named type] -> [class](../syntax/type/04_class.md) +* [Annunciation] +* [nominal subtype](../syntax/type/05_nst_vs_sst.md) + +### capture -> [closure] + +### [covariant] + +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 + +* [Interval type](../syntax/type/11_interval.md) +* interval operator + +### Embedded + +Erg standard APIs not implemented in .er files. + +### [class](../syntax/type/04_class.md) + +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 + +* [higher-order kind](../syntax/type/advanced/kind.md) +* higher order type +* Higher-order functions + +### [public variables] + +### [structural subtype] + +### ~~back reference~~ -> [back reference] + +### [copy] + +### comment + +### [Collection](../syntax/10_array.md) + +### Colon -> [:] + +### [constructor](../syntax/type/04_class.md) + +### container + +### Compiler + +### [compile-time computation](../syntax/04_function.md#compile-time function) + +### comma -> [,] + +## sa line + +### recursion + +Refer to yourself. + +* recursive +* [Recursive function](../syntax/04_function.md#Recursive function) + +### subscript -> [index] + +### [subtyping polymorphism](../syntax/type/overloading.md) + +Polymorphism with subtyping. Subtyping corresponds to set containment in types. + +### Subroutine + +An object that modularizes processing. A generic term for functions, procedures, and methods in Erg. + +### [reference](../syntax/18_memory_management.md#borrowed) + +* reference object +* [Reference counting (RC)](../syntax/18_memory_management.md#memory management) +* Reference equality -> [side effect](../syntax/07_side_effect.md) + +### [identifier](../syntax/02_variable.md/# assignment) + +### signature + +* type signature + +### [dict](../syntax/11_dict.md) + +### [natural number] -> [Nat] + +### Generics -> [Generic] + +### Generator + +### [projective type] + +### borrow -> [reference](../syntax/18_memory_management.md#borrowed) + +### [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] + +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] + +### [script](../syntax/00_basic.md# script) + +A file containing an Erg program. + +### Scope + +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] + +### [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. + +### [set](../syntax/12_set.md) + +### Semicolon -> [;] + +### [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 + +### [algebra](../syntax/02_name.md) + +* [algebraic type](../syntax/type/13_algebraic.md) +* algebraic data types + +### [assignment](../syntax/02_variable.md/#assignment) + +### Multiple + +* [Multiple inheritance](../syntax/type/07_inheritance.md/#Prohibition of multiple inheritance) +* Multiple assignment +* Overload -> [No overloading] + +### Polymorphism + +* [polymorphic type](../syntax/type/quantified.md) +* polycorrelation coefficient + +### polymorphism -> [polymorphism] + +### duck typing + +### [tuple](../syntax/11_tuple.md) + +### Single-phase + +* Single phase +* Single-phase type +* Single correlation coefficient + +### [Lazy initialization] + +### Extraction Assignment + +### Abstract syntax tree -> [AST] + +### Infix operator + +The operator `∘` applied in the form `x∘y`. + +### [constant](../syntax/02_name.md/#constant) + +Immutable, compile-time evaluable algebra. + +* [constant type](../syntax/type/advanced/const.md) +* [constant expression](../syntax/type/advanced/const.md) + +### [definition] + +Allocating an object corresponding to a variable. + +### Provided Attributes + +Attributes available as API. Especially attributes auto-implemented by traits. + +### [Apply] + +To pass an argument to a function object and get the evaluation result. + +### [decorator](../syntax/29_decorator.md) + +``` 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. + +### [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] + +### [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) + +## na line + +### [Comprehension](../syntax/27_comprehension.md) + +### ~~Infix operator~~ -> [Infix operator] + +### [namespace] + +## is a line + +### [Array](../syntax/10_array.md) + +### [derived type](../syntax/type/variances.md/# user-defined type variations) + +### [pattern (match)](../syntax/26_pattern_matching.md) + +### [package](../syntax/33_package_system.md) + +### hashmap -> [dict](../syntax/11_dict.md) + +### [patch](../syntax/type/07_patch.md) + +### public variables -> [public variables](../syntax/19_visibility.md) + +### parameter -> [argument](../syntax/04_function.md) + +### [Parametric Polymorphism](../syntax/type/overloading.md) + +### [contravariant](../syntax/type/advanced/variance.md) + +### Compare + +* [comparison operator] +* [comparable type] + +### [private variable](../syntax/19_visibility.md) + +### standard + +* standard output +* standard input +* standard library + +### [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] + +### [procedure](../syntax/08_procedure.md) + +### [arguments](../syntax/04_function.md) + +### Partial Typing -> [Subtyping] + +### [immutable] + +In Erg, an object should never change its contents. + +* [immutable object] +* [immutable type] +* [immutable reference] + +### [sieve type](../syntax/type/12_refinement.md) + +### [block] + +### Destructuring assignment + +### [variable](../syntax/02_variable.md) + +### bottom + +* bottom type -> [{}] +* Bottom class -> [Never] + +### [Polymorphism] + +## ma line + +### ~~ prefix operator ~~ -> prefix operator + +### [marker type](../syntax/type/advanced/marker_trait.md) + +### [anonymous function](../syntax/21_lambda.md) + +### mutable -> [mutable] + +### [move] + +### methods + +### Metacharacters + +### [module](../syntax/24_module.md) + +### [String] -> [Str] + +* [String interpolation](../syntax/01_literal.md/#Str literal) + +### Return value + +## or line + +### [phantom type](../syntax/type/advanced/phantom.md) + +### Request Attributes + +### [element] + +### [call] + +## Ra line + +### [Library] + +### lambda expression -> [anonymous function](../syntax/20_lambda.md) + +### rank + +* [rank2 polymorphism](../syntax/type/advanced/rank2type.md) + +### [literal](../syntax/01_literal.md) + +* [literal identifier](../syntax/18_naming_rule.md/#literal identifier) + +### [quantified](../syntax/type/quantified.md) + +### [Layout](../syntax/type/mut.md) + +### [enum](../syntax/type/10_enum.md) + +### [record](../syntax/12_record.md) + +* [record type] +* Record Polymorphism -> [Column Polymorphism] + +### [column polymorphism] + +### [local variables](../syntax/19_visibility.md) + +## line + +### Wildcard \ No newline at end of file diff --git a/doc/EN/dev_guide/unify_terms.md b/doc/EN/dev_guide/unify_terms.md index e69de29b..4ef35c31 100644 --- a/doc/EN/dev_guide/unify_terms.md +++ b/doc/EN/dev_guide/unify_terms.md @@ -0,0 +1,88 @@ +# Unification of terminology + +## Accessibility, Visibility + +Use Visibility. + +## Complement (negative type, complementary type) + +Use negative types. The result of Complement is not necessarily Not type. + +## Diff (difference type, exclusion type, direct difference type) + +Use exclusion types. The result of Diff is not always Not type. + +## Intersection (intersection type, intersection type, Cartesian product type) + +Use intersection types. Do not use Cartesian product types. This is because there is also a usage that regards a tuple as a Cartesian product type. +However, from the point of view of attribute subtyping, it is essentially equivalent to Erg's And type. +Also, the result of Intersection is not necessarily And type. For example `{1, 2, 3} and {1, 2} == {1, 2}`. + +## Translation of Nominal subtyping + +There are nominal/nominal/nominal subtyping, but use nominal subtyping. + +## Ratio type translation + +Use rational numbers. Since Float is provided separately, it is not called a floating-point number type. + +## Union + +Use a union type. The result of Union is not necessarily Or type. + +## Type bound, Type constraint + +A list of predicate expressions given to quantified and sieve types. Use type bounds. + +## subroutines, routines, subprograms + +Use subroutines. + +## Referentially transparent/not, with/without side effects + +Use with/without side effects. + +## identifiers, algebra, variables, names, symbols + +In its original meaning, + +* 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). + +``` 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. + +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 + +Attribute, use attributes. +By the way, a record is a function that can define an object with element attributes without a class. + +## Application, Call + +Giving arguments to a subroutine object and getting a result. +Use Call. This is because Application has a usage of "applied software". + +## Array, List + +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. + +## procedures, procedures + +Standardize on procedures. Subroutine is a generic term for functions (and operators), procedures and methods. Callable is also anything that implements `__call__`. + +## lambda functions, lambda expressions, anonymous functions, anonymous functions + +Unify with anonymous functions. In English, Lambda can be used to shorten the number of characters, but the official name is Anonymous function. +Also, Erg's anonymous functions are not anonymous, so we don't use them. \ No newline at end of file diff --git a/doc/EN/migration_from_py.md b/doc/EN/migration_from_py.md index f039b9ca..af3a0e43 100644 --- a/doc/EN/migration_from_py.md +++ b/doc/EN/migration_from_py.md @@ -1,28 +1,25 @@ -# Tips on migrating from Python to Erg +# Tips for migrating from Python to Erg -## Want to convert a string to an int, etc +## I want to convert a string to int etc. Use the `parse` method of the `Str` class. It returns a `Result` type. ```python -# Python s: str i: int = int(s) ``` -```erg -# 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 +``` 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/EN/python/bytecode_instructions.md b/doc/EN/python/bytecode_instructions.md index 83879068..e0427708 100644 --- a/doc/EN/python/bytecode_instructions.md +++ b/doc/EN/python/bytecode_instructions.md @@ -1,7 +1,7 @@ # Python Bytecode Instructions -Python bytecode variable manipulation instructions are accessed through namei (name index). This is to realize Python's dynamic variable access (access by string using eval, etc.). -Each instruction is 2 bytes, and instructions and arguments are stored in a little endian. +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) @@ -16,7 +16,7 @@ globals[namei] = stack.pop() stack.push(globals[namei]) ``` -Only called at the top level. +Only called at top level. ## LOAD_GLOBAL(namei) @@ -24,7 +24,7 @@ Only called at the top level. stack.push(globals[namei]) ``` -To Load what was STORE_NAME at the top level in the inner scope, but namei at the top level is not necessarily the same as namei in a code object of a certain scope (namei, not name, is the same). +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) @@ -32,10 +32,10 @@ To Load what was STORE_NAME at the top level in the inner scope, but namei at th stack.push(consts[namei]) ``` -Load constants in the constants table. -Currently (Python 3.9), CPython MAKE_FUNCTION every time a lambda function is called "\". +Load constants in the constant table. +Currently (Python 3.9), in CPython, each lambda function is MAKE_FUNCTION with the name "\" -````console +```console >>> dis.dis("[1,2,3].map(lambda x: x+1)") 1 0 LOAD_CONST 0 (1) 2 LOAD_CONST 1 (2) @@ -47,33 +47,30 @@ Currently (Python 3.9), CPython MAKE_FUNCTION every time a lambda function is ca 14 MAKE_FUNCTION 0 16 CALL_FUNCTION 1 18 RETURN_VALUE -```` +``` ## STORE_FAST(namei) -```python fastlocals[namei] = stack.pop() -``` - -Probably corresponds to STORE_NAME at the top level. -This is supposed to store an unreferenced (or single) variable. -Is it for optimization that the global space has its own instruction? +Possibly corresponds to STORE_NAME at top level +The unreferenced (or single) variable is assumed to be stored by this +Is it for optimization that the global space has its own instructions? ## LOAD_FAST(namei) stack.push(fastlocals[namei]) -fastlocals is varnames? +fastlocals are varnames? ## LOAD_CLOSURE(namei) ```python cell = freevars[namei] -stack.push(cell) +stack. push(cell) ``` -After that BUILD_TUPLE is called. -It is only called in a closure, and cellvars is supposed to store references in the closure. -Unlike LOAD_DEREF, the entire cell (container with references) is pushed onto the stack +Then BUILD_TUPLE is called +It is only called inside the closure, and cellvars are supposed to store references inside the closure. +Unlike LOAD_DEREF, each cell (container filled with references) is pushed to the stack ## STORE_DEREF(namei) @@ -82,8 +79,8 @@ cell = freevars[namei] cell.set(stack.pop()) ``` -Variables without references in the inner scope are STORE_FAST, but referenced variables are STORE_DEREF. -In Python, the reference count is increased or decreased within this instruction +Variables without references in inner scopes are STORE_FAST, but referenced variables are STORE_DEREF +In Python, the reference count is incremented and decremented within this instruction ## LOAD_DEREF(namei) @@ -92,26 +89,26 @@ cell = freevars[namei] stack.push(cell.get()) ``` -## Name List +## name list ### varnames -List of names of internal variables of the function corresponding to `fast_locals`. -Even if there is a variable with the same name in names, it is not basically the same (it is newly created, and the outside variable cannot be accessed from its scope). -In other words, variables defined in scope without external references go into varnames +Name list of function internal variables corresponding to fast_locals +Even if there are variables with the same name in names, they are basically not the same (newly created and outside variables cannot be accessed from that scope) +i.e. variables without external references defined in scope go into varnames ### names -Corresponding to `globals`. -A list of names of external constants (reference only) used in a scope (even ordinary variables at the top level go into names). -In other words, constants defined outside the scope go into names +Compatible with globals +Name list of external constants (only referenced) used within the scope (at the top level, even ordinary variables are included in names) +i.e. constants defined outside the scope go into names -## free variable +## free variables -Corresponds to `freevars`. -Variables captured by closure. It behaves static within the same function instance. +Compatible with freevars +Variables captured by the closure. It behaves statically within the same function instance. ## cell variables -Corresponds to `cellvars`. -Variables captured by an inner closure function within a function. A copy is made, so the original variable remains intact. +Corresponds to cellvars +Variables captured within a function to an inner closure function. Since a copy is made, the original variable remains as it is. \ No newline at end of file diff --git a/doc/EN/syntax/14_set.md b/doc/EN/syntax/14_set.md index b1757c12..324b4969 100644 --- a/doc/EN/syntax/14_set.md +++ b/doc/EN/syntax/14_set.md @@ -1,16 +1,16 @@ # Set -A set is an unordered array with no duplicates. +A set represents a collection, which is structurally a duplicate, unordered array. -```erg +``` erg assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3} assert {1, 2} == {1, 1, 2} # duplicates are automatically removed assert {1, 2} == {2, 1} ``` -Sets can perform mathematical set operations. +Sets can perform set operations. -```erg +``` erg assert 1 in {1, 2, 3} assert not 1 in {} assert {1} or {2} == {1, 2} @@ -18,30 +18,29 @@ assert {1, 2} and {2, 3} == {2} assert {1, 2} not {2} == {1} ``` -A set is a homogenous collection. Objects of different classes must be made equal in order to coexist. +A set is a homogeneous collection. In order for objects of different classes to coexist, they must be homogenized. -```erg -s1 = {"a", 1, "b", -1} # TypeError -s2: {Int or Str} = {"a", 1, "b", -1} +``` erg +s: {Int or Str} = {"a", 1, "b", -1} ``` -## Set as Type +## Sets as types -Sets can also be treated as types. Such a type is called an __Enum type_. +Sets can also be treated as types. Such types are called __Enum types__. -```erg +``` erg i: {1, 2, 3} = 1 assert i in {1, 2, 3} ``` -The elements of the set are directly the elements of the type. -Note that the set itself is different. +Elements of the set are directly elements of the type. +Note that the sets themselves are different. -```erg +``` 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/EN/syntax/15_type.md b/doc/EN/syntax/15_type.md index 97b8bad7..8430dc74 100644 --- a/doc/EN/syntax/15_type.md +++ b/doc/EN/syntax/15_type.md @@ -4,4 +4,4 @@ Types are a very important feature in Erg, so we have a [dedicated section](./ty

Previous | Next -

+

\ No newline at end of file diff --git a/doc/EN/syntax/18_ownership.md b/doc/EN/syntax/18_ownership.md index 26b463a0..1f1e0232 100644 --- a/doc/EN/syntax/18_ownership.md +++ b/doc/EN/syntax/18_ownership.md @@ -1,110 +1,110 @@ -# Ownership System +# Ownership system -Since Erg is a language that uses Python as its host language, its method of memory management is dependent on the Python implementation. -Semantically, however, Erg's memory management is different from that of Python. The most noticeable differences appear in the ownership system and the prohibition of circular references. +Since Erg is a language that uses Python as the host language, the method of memory management depends on the Python implementation. +But semantically Erg's memory management is different from Python's. A notable difference is in the ownership system and the prohibition of circular references. ## Ownership -Erg has an ownership system influenced by Rust. -While Rust's ownership system is generally considered arcane, Erg's has been simplified to make it intuitive. -In Erg, ownership is attached to __mutable objects__, which cannot be referenced after you lose ownership. +Erg has an ownership system inspired by Rust. +Rust's ownership system is generally considered esoteric, but Erg's is simplified to be intuitive. +In Erg, __mutable objects__ are owned and cannot be referenced after ownership is lost. -```erg -v = [1, 2, 3].into [Int; !3]. +``` erg +v = [1, 2, 3].into [Int; !3] -push!vec, x = +push! vec, x = vec.push!(x) - vec. + vec -# ownership of v's contents ([1, 2, 3]) is transferred to w +# The contents of v ([1, 2, 3]) are owned by w w = push! v, 4 print! v # error: v was moved -print! w # [1, 2, 3, 4] +print!w # [1, 2, 3, 4] ``` -Ownership transfers occur when an object is passed to a subroutine, for example. -If you wish to retain ownership of the object after passing it to a subroutine, you must do cloning, freezing, or borrowing. -However, as described below, borrowing can only be used in limited situations. +Ownership transfer occurs, for example, when an object is passed to a subroutine. +If you want to still have ownership after giving it away, you'll need to clone, freeze, or borrow. +However, as will be explained later, there are limited situations in which it can be borrowed. -## Cloning +## replication -Duplicate an object and transfer ownership of it. This is done by applying the `.clone` method to the real argument. -The cloned object will be exactly the same as the original object, but independent of each other and unaffected by changes. +Duplicate an object and transfer its ownership. It does this by applying the `.clone` method to the actual arguments. +The duplicated object is exactly the same as the original, but independent of each other and unaffected by changes. -Cloning is equivalent to deep copying in Python, and is generally more computationally and memory expensive than freezing and borrowing, since it re-creates the same object in its entirety. -Subroutines that require object duplication are called "argument-consuming" subroutines. +Duplication is equivalent to Python's deep copy, and since it recreates the same object entirely, the computation and memory costs are generally higher than freezing and borrowing. +A subroutine that needs to duplicate an object is said to be an "argument consuming" subroutine. -```erg -capitalize s: Str! - s.capitalize!() +``` erg +capitalize s: Str!= + s. capitalize!() s -s1 = !" hello" +s1 = !"hello" s2 = capitalize s1.clone() -log s2, s1 # !" HELLO hello" +log s2, s1 # !"HELLO hello" ``` -## Freezing +## freeze -Taking advantage of the fact that immutable objects can be referenced from multiple places, a variable object is converted to an immutable object. -This is called freezing. Freezing is used to create iterators from mutable arrays. -Since iterators cannot be created directly from mutable arrays, they are converted to immutable arrays. -If you do not want to destroy the array, use the [`.freeze_map` method](./type/mut.md), etc. +We take advantage of the fact that immutable objects can be referenced from multiple places and convert mutable objects to immutable objects. +This is called freezing. Freezing is used, for example, when creating an iterator from a mutable array. +Since you can't create an iterator directly from a mutable array, convert it to an immutable array. +If you don't want to destroy the array, use the [`.freeze_map` method](./type/mut.md). -```erg -# Calculate the sum of the values produced by the iterator +``` 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]. +x = [1, 2, 3].into [Int; !3] x.push!(4) -i = x.iter() # TypeError: [Int; !4] has no method `iter`. +i = x.iter() # TypeError: [Int; !4] has no method `iter` y = x.freeze() i = y.iter() assert sum(i) == 10 -y # y is still touched after this. +y # y can still be touched ``` -## Borrowing +## borrow -Borrowing is less expensive than cloning or freezing. -Borrowing can be done in simple cases such as the following. +Borrowing is cheaper than duplicating or freezing. +Borrowing can be done in the following simple cases: -```erg +``` erg peek_str ref(s: Str!) = log s -s = !" hello" +s = !"hello" peek_str s ``` -The borrowed value is called a __reference__ to the original object. -You can "subloan" a reference to another subroutine, but you can't consume it because you are only borrowing it. +A borrowed value is called a __reference__ to the original object. +You can "sublease" the reference to another subroutine, but you cannot consume it because you are only borrowing it. -```erg -steal_str ref(s: Str!) =. - # The log function only borrows arguments, so it can subloan +``` erg +steal_str ref(s: Str!) = + # Since the log function only borrows the arguments, it can be sub-leased log s - # Discard function consumes arguments, so it is an error + # error because the discard function consumes arguments discard s # OwnershipError: cannot consume a borrowed value # hint: use `clone` method ``` -```erg +``` erg steal_str ref(s: Str!) = - # this is also no good (= consumes the right side) + # This is no good either (= consumes the right side) x = s # OwnershipError: cannot consume a borrowed value x ``` -Erg references are more restrictive than Rust. Although references are first-class objects in the language, they cannot be created explicitly and can only be specified as a way of passing real arguments by `ref`/`ref!`. -This means that it is not possible to pack references into arrays or create classes with references as attributes. +Erg's references are more restrictive than Rust's. References are first-class objects in the language, but cannot be created explicitly, they can only be specified as argument passing via `ref`/`ref!`. +This means that you cannot stuff references into arrays or create classes with references as attributes. -However, such restrictions are common in languages without references, so they are not that inconvenient. +However, such restrictions are a natural specification in languages ​​without references in the first place, and they are not so inconvenient. -## Circular references +## circular references -Erg is designed to prevent unintentional memory leaks, and the memory checker will generate an error when it detects a circular reference. In most cases, this error can be resolved with a weak reference `Weak`. However, this does not allow the creation of objects with circular structures such as cyclic graphs, so we plan to implement an API that can create circular references as an unsafe operation. +Erg is designed to prevent unintentional memory leaks, and will issue an error if the memory checker detects a circular reference. In most cases, this error can be resolved with a weak reference `Weak`. However, since it is not possible to generate objects with circular structures such as cyclic graphs, we plan to implement an API that can generate circular references as unsafe operations.

Previous | Next -

+

\ No newline at end of file diff --git a/doc/EN/syntax/19_visibility.md b/doc/EN/syntax/19_visibility.md index 4c1fef53..e5ef1e80 100644 --- a/doc/EN/syntax/19_visibility.md +++ b/doc/EN/syntax/19_visibility.md @@ -1,56 +1,56 @@ # Visibility Erg variables have the concept of __visibility__. -All variables we have seen so far are called __private variables__. These are variables that are invisible to the outside world. -For example, a private variable defined in the `foo` module cannot be referenced from another module. +All the variables we've seen so far are called __private variables__. This is an externally invisible variable. +For example, a private variable defined in the `foo` module cannot be referenced by another module. -```erg +``` 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) ``` -In contrast, there is also a __public variable__, which can be referenced externally. +On the other hand, there are also __public variables__, which can be referenced from the outside. Public variables are defined with `.`. -```erg +``` 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" ``` -Private variables do not need to be marked with anything, but can be marked with `::` or `self::` (or `Self::` for types, etc.) to make them explicitly private. A module can also be `module::`. +You don't need to add anything to private variables, but you can also add `::` or `self::` (`Self::` for types etc.) to indicate that they are private. increase. It can also be `module::` if it is a module. -```erg +``` 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 mere sequential execution, private variables are almost synonymous with local variables. They can be referenced from inner scope. +In the context of purely sequential execution, private variables are almost synonymous with local variables. It can be referenced from the inner scope. -```erg +``` erg ::x = "this is a private variable" y = x + 1 # exactly module::x ``` -The `::` allows you to distinguish between variables with the same name in a scope. -Specify the scope of the variable you want to reference on the left. For the top level, specify `module`. -If not specified, the innermost variable is referenced as in the normal case. +By using `::`, you can distinguish variables with the same name within the scope. +Specify the scope of the variable you want to refer to on the left. Specify `module` for the top level. +If not specified, the innermost variable is referenced as usual. -```erg +``` erg ::x = 0 assert x == 0 y = @@ -64,38 +64,38 @@ y = assert module::x == 0 ``` -In the scope of an anonymous subroutine, `self` specifies its own scope. +In the anonymous subroutine scope, `self` specifies its own scope. -```erg +``` 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. - # Top-level x is referenced (warns to make it module::x) + # Top-level x is referenced (warning to use module::x) f1 self = x - # x of instance attribute is referenced + # instance attribute x is referenced f2 self = self::x ``` ## Visibility in external modules -A class defined in one module can actually define methods from an external module as well. +A class defined in one module can actually define methods from an external module. -```erg -## foo.er +``` erg +# foo.er .Foo = Class() ``` -```erg -# bar.er +``` erg +#bar.er {Foo; ...} = import "foo" Foo:: @@ -109,45 +109,45 @@ Foo. foo::private() # AttributeError ``` -However, both of those methods can only be used within that module. -Externally defined private methods can be referenced by methods of the `Foo` class only within the defining module. -Public methods are exposed outside the class, but not to outside the module. +However, both of those methods are only available within that module. +Private methods defined externally are visible to methods of the `Foo` class only within the defining module. +Public methods are exposed outside the class, but not outside the module. -```erg -# baz.er. +``` erg +# baz.er {Foo; ...} = import "foo" foo = Foo.new() foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defined in module 'bar') ``` -Also, you cannot define a method on the type you are re-exporting. -This is to avoid confusion when a method is found or not found depending on the module from which it is imported. +Also, methods cannot be defined in the type to be re-exported. +This is to avoid confusion about methods being found or not found depending on the module they are imported from. -```erg -# bar.er +``` erg +#bar.er {.Foo; ...} = import "foo" .Foo:: private self = pass # Error -.Foo. - Foo:: public self = self::private() # Error +Foo. + public self = self::private() # Error ``` If you want to do something like this, define a [patch](./type/07_patch.md). -```erg -# bar.er. +``` erg +#bar.er {Foo; ...} = import "foo" FooImpl = Patch Foo -FooImpl:: +FooImpl :=: private self = pass -FooImpl. +Foo Impl. public self = self::private() ``` -```erg +``` erg # baz.er {Foo; ...} = import "foo" {FooImpl; ...} = import "bar" @@ -156,7 +156,7 @@ foo = Foo.new() foo.public() ``` -## Restricted Public Variables +## restricted public variables Variable visibility is not limited to complete public/private. You can also publish with restrictions. @@ -164,14 +164,14 @@ You can also publish with restrictions. ``` erg # foo.er .record = { - .a = { - .(.record)x = 0 - .(module)y = 0 - .z = 0 - } - _ = .a.x # OK - _ = .a.y # OK - _ = .a.z # OK + .a = { + .(.record)x = 0 + .(module)y = 0 + .z = 0 + } + _ = .a.x # OK + _ = .a.y # OK + _ = .a.z # OK } _ = .record.a.x # VisibilityError @@ -187,5 +187,5 @@ _ = foo.record.a.z # OK ```

- Previous | Next -

+ Previous | Next +

\ No newline at end of file diff --git a/doc/EN/syntax/20_naming_rule.md b/doc/EN/syntax/20_naming_rule.md index f729d83e..dee0d1cf 100644 --- a/doc/EN/syntax/20_naming_rule.md +++ b/doc/EN/syntax/20_naming_rule.md @@ -1,38 +1,38 @@ -# Naming Conventions +# Naming convention -If a variable is to be used as a constant expression, it must begin with a capital letter. The second and succeeding letters may be in lowercase. +If you want to use a variable as a constant expression, make sure it starts with a capital letter. Two or more letters may be lowercase. -```erg +``` erg i: Option Type = Int match i: t: Type -> log "type" None -> log "None" ``` -Objects with side-effects must end with `!` must end with `!`. They are procedures, procedural methods, and mutable types. -However, the `Proc` type itself is not a mutable type. +Objects with side effects always end with `!`. Procedures and procedural methods, and mutable types. +However, the `Proc` type itself is not mutable. -```erg +``` erg # Callable == Func or Proc c: Callable = print! match c: - p! -> log "proc" # can omit `: Proc` since it is self-explanatory + p! -> log "proc" # `: Proc` can be omitted since it is self-explanatory f -> log "func" ``` -If you want to expose the attribute to the outside world, define it with `.`. `.` attribute is not prefixed, the attribute is not public. To avoid confusion, they cannot coexist in the same scope. +If you want to expose an attribute to the outside world, define it with `.` at the beginning. If you don't put `.` at the beginning, it will be private. To avoid confusion, they cannot coexist within the same scope. -```erg +``` erg o = {x = 1; .x = 2} # SyntaxError: private and public variables with the same name cannot coexist ``` ## Literal Identifiers -The above rule can be avoided by enclosing the string in single quotes (''). That is, a procedural object can also be assigned without `!`. In this case, however, even if the value is a constant expression, it is not considered a constant. -Such a string identifier enclosed in single quotes is called a literal identifier. -This is used when calling the API (FFI) of other languages such as Python. +The above rule can be circumvented by enclosing the string in single quotes (''). That is, procedural objects can also be assigned without `!`. However, in this case, even if the value is a constant expression, it is not considered a constant. +A character string enclosed in single quotes like this is called a literal identifier. +This is used when calling APIs (FFI) of other languages ​​such as Python. -```erg +``` erg bar! = pyimport("foo").'bar' ``` @@ -40,11 +40,11 @@ Identifiers that are also valid in Erg do not need to be enclosed in ''. Furthermore, literal identifiers can contain both symbols and spaces, so strings that cannot normally be used as identifiers can be used as identifiers. -```erg +``` erg '∂/∂t' y 'test 1: pass x to y'() ```

Previous | Next -

+

\ No newline at end of file diff --git a/doc/EN/syntax/21_lambda.md b/doc/EN/syntax/21_lambda.md index 67167106..08415e13 100644 --- a/doc/EN/syntax/21_lambda.md +++ b/doc/EN/syntax/21_lambda.md @@ -1,94 +1,95 @@ -# Anonymous Function +# anonymous function -An anonymous function is a syntax for creating function objects on the fly without naming them. +Anonymous functions are a syntax for creating function objects on the fly without naming them. -```erg -# `->` is the anonymous function operator +``` 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 `()` if there is only one argument. +You can omit the `()` if there is only one argument. -```erg -assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4]. -assert ((i, j) -> [i, j])(1, 2) == [1, 2]. +``` 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 `0..9, (i -> ...)`, not `(0..9, i) -> ...`. -`->` takes only one argument on the left side. Multiple arguments are taken as a single tuple. +In the case below it is `0..9, (i -> ...)` and not `(0..9, i) -> ...`. +`->` takes only one argument on the left side. Multiple arguments are received as a single tuple. -```erg +``` erg for 0..9, i: Int -> ... ``` -For anonymous functions, there is a difference in syntactic interpretation due to whitespace. +In anonymous functions, there is a difference in parsing due to whitespace. -```erg -# In this case, it is interpreted as ``T(() -> Int)``. -i: T () -> Int -# In this case, it is interpreted as (U()) -> Int +``` 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. `=>` is an anonymous procedure operator. +Anonymous functions can be used without arguments. -```erg -p!= () => print!"`p!` was called" -# `() ->`, `() =>` have the sugar-coated constructs `do`, `do!`. +``` erg +# `=>` is an anonymous procedure operator +p! = () => print! "`p!` was called" +# `() ->`, `() =>` have syntax sugar `do`, `do!` # p! = do! print! "`p!` was called" p!() # `p!` was called ``` -Argumentless functions can be used for lazy initialization. +No-argument functions can be used for lazy initialization. -```erg +``` erg time = import "time" date = import "datetime" now = if! True: - do! - time.sleep! + do!: + time. sleep! 1000 date.now!() do date.new("1970", "1", "1", "00", "00") ``` -Typing and pattern matching can also be done. For this reason, the ``match`` function is realized almost entirely by the power of anonymous functions. -The anonymous functions given as arguments to the ``match`` function are tried in order from the top. So, it is necessary to describe special cases at the top and more general cases as you go down. If you get the order wrong (as far as possible), the compiler will issue a Warning. +You can also type and pattern match. Because of this, the `match` function is mostly implemented with the power of anonymous functions. +Anonymous functions given as arguments to the `match` function are tried in order from the top. So, you should describe the special cases at the top and the more general cases at the bottom. If you get the order wrong, the compiler will issue a warning (if possible). -```erg -n = (Complex or Ratio or Int).sample! -i = match n: +``` erg +n = (Complex or Ratio or Int).sample!() +i = matchn: PI -> PI # if equal to constant PI - (i: 1..10) -> i # if 1~10 Int - (i: Int) -> i # for Int - (c: Complex) -> c.real() # case of Complex, Int < Complex, but can fall back - _ -> panic "cannot convert to Int" # none of the above; match must cover all patterns + For (i: 1..10) -> i # Int from 1 to 10 + (i: Int) -> i # Int + (c: Complex) -> c.real() # For Complex. Int < Complex, but can fallback + _ -> panic "cannot convert to Int" # If none of the above apply. match must cover all patterns ``` -Error handling can also be done using `?` or `match`. +Error handling is also generally done using `?` or `match`. -```erg +``` 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 Polymorphic Function +## 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/EN/syntax/23_closure.md b/doc/EN/syntax/23_closure.md index 3d5040d9..52c6c917 100644 --- a/doc/EN/syntax/23_closure.md +++ b/doc/EN/syntax/23_closure.md @@ -1,32 +1,32 @@ # Closure -Erg subroutines have a "closure" feature that captures external variables. +Erg subroutines have a feature called a "closure" that captures external variables. -```erg +``` erg outer = 1 f x = outer + x assert f(1) == 2 ``` -Like immutable objects, mutable objects can also be captured. +As with immutable objects, mutable objects can also be captured. -```erg +``` erg sum = !0 for! 1..10, i => - sum.add! + sum.add!i assert sum == 45 -p! x = - sum.add! +p!x= + sum.add!x p!(1) assert sum == 46 ``` Note, however, that functions cannot capture mutable objects. -If mutable objects could be referenced in a function, the following code could be written. +If a mutable object can be referenced in a function, you can write code like the following. -```erg -# !!! This code is actually an error !!! +``` erg +# !!! This code actually gives an error !!! i = !0 f x = i + x assert f 1 == 1 @@ -34,31 +34,31 @@ i.add! 1 assert f 1 == 2 ``` -The function should return the same value for the same argument, but that assumption has been violated. -Note that ``i`` is evaluated for the first time at call time. +The function should return the same value for the same arguments, but the assumption is broken. +Note that `i` is evaluated only at call time. -If you want the contents of a mutable object at the time of the function definition, `.clone` it. +Call `.clone` if you want the contents of the mutable object at the time the function was defined. -```erg +``` 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 ``` -## Avoiding Mutable States, Functional Programming +## avoid mutable state, functional programming -```erg -## Erg +``` erg +# Erg sum = !0 for! 1..10, i => - sum.add! + sum.add!i assert sum == 45 ``` -The equivalent program above can be written in Python as follows. +The equivalent program above can be written in Python as follows: ```python # Python @@ -68,29 +68,29 @@ for i in range(1, 10): assert sum == 45 ``` -However, Erg recommends a simpler way of writing. -Instead of using subroutines and mutable objects to carry around state, the style is to localize the state using functions. This is called functional programming. +However, Erg recommends a simpler notation. +Instead of carrying around state using subroutines and mutable objects, use a style of localizing state using functions. This is called functional programming. -```erg +``` erg # Functional style sum = (1..10).sum() assert sum == 45 ``` -The above code produces exactly the same result as the previous one, but it can be seen that this one is much simpler. +The code above gives exactly the same result as before, but you can see that this one is much simpler. -The `fold` function can be used to perform a variety of operations other than summing. +The `fold` function can be used to do more than sum. `fold` is an iterator method that executes the argument `f` for each iteration. -The initial value of the counter to accumulate the results is specified by `init` and accumulated in `acc`. +The initial value of the counter that accumulates results is specified in `init` and accumulated in `acc`. -```erg +``` erg # start with 0, result will sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i) assert sum == 45 ``` -Erg is designed to be a natural and concise description of programming with invariant objects. +Erg is designed to be a natural succinct description of programming with immutable objects.

Previous | Next -

+

\ No newline at end of file diff --git a/doc/EN/syntax/24_module.md b/doc/EN/syntax/24_module.md index ba586185..2a7c92d9 100644 --- a/doc/EN/syntax/24_module.md +++ b/doc/EN/syntax/24_module.md @@ -39,4 +39,4 @@ Since module types are also record types, deconstruction assignment is possible.

Previous | Next -

+

\ No newline at end of file diff --git a/doc/EN/syntax/25_object_system.md b/doc/EN/syntax/25_object_system.md index 7b85ea6f..c02573ea 100644 --- a/doc/EN/syntax/25_object_system.md +++ b/doc/EN/syntax/25_object_system.md @@ -1,64 +1,68 @@ # Object -All data that can be assigned to a variable. The `Object` class has the following attributes. +All data that can be assigned to a variable. The attributes of the `Object` class are as follows. -* `. __repr__`: returns a (non-rich) string representation of the object. -* `. __sizeof__`: returns the size of the object (including heap allocation). -* `. __dir__`: return a list of attributes of the object. -* `. __hash__`: return the hash value of the object. -* `. __getattribute__`: retrieve and return an object's attributes * `. -* `.clone`: create and return a clone of an object (an independent entity in memory). -* `.copy`: return a copy of an object (identical in memory). +* `.__repr__`: Returns a (non-rich) string representation of the object +* `.__sizeof__`: Returns the size of the object (including heap allocation) +* `.__dir__`: Returns a list of object attributes +* `.__hash__`: returns the hash value of the object +* `.__getattribute__`: Get and return an attribute of an object +* `.clone`: Creates and returns a clone of an object (with an independent entity in memory) +* `.copy`: Returns a copy of the object (pointing to the same thing in memory) ## Record -An object created by a record literal (`{attr = value; ...}`). -This object can be a `.clone` or a `. __sizeof__` and other basic methods. +An object generated by a record literal (`{attr = value; ...}`). +This object has basic methods such as `.clone` and `.__sizeof__`. -```erg +``` erg obj = {.x = 1} assert obj.x == 1 -obj2 = {. .x; .y = 2} +obj2 = {...x; .y = 2} assert obj2.x == 1 and obj2.y == 2 ``` ## Attribute -An object associated with an object. In particular, a subroutine attribute that takes itself (`self`) as its implicit first argument is called a method. +An object associated with an object. In particular, a subroutine attribute that takes self (`self`) as its implicit first argument is called a method. -```erg -# Note that private_attr does not have `. Note that there is no `. +``` 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 -An object belonging to a specific type (e.g. `1` is an element of type `Int`). All objects are at least `{=}` type. -In the case of an element of a class, it is sometimes called an instance. +An object belonging to a particular type (e.g. `1` is an element of type `Int`). All objects are at least elements of type `{=}`. +Elements of classes are sometimes called instances. ## Subroutine -An object that is an instance of a function or procedure (including methods). The class representing a subroutine is `Subroutine`. -More generally, `.__call__` is called a `Callable`. +Indicates an object that is an instance of a function or procedure (including methods). The class representing a subroutine is `Subroutine`. +An object that implements `.__call__` is more commonly called a `Callable`. ## Callable -Object that implements `.__call__`. Superclass of `Subroutine`. +An object that implements `.__call__`. It is also the superclass of `Subroutine`. ## Type -An object that defines required attributes and makes objects common. -There are two main types: polymorphic type and monomorphic type. Typical monomorphic types are `Int`, `Str`, etc. Polymorphic types include `Option Int`, `[Int; 3]` and so on. -In addition, types that define methods to change the state of an object are called mutable types, and require variable attributes marked with `!` (e.g., dynamic arrays: `[T; !_]`). +An object that defines requirement attributes and commonizes objects. +There are two main types: Polymorphic Type and Monomorphic Type. Typical monomorphic types are `Int`, `Str`, etc., and polymorphic types are `Option Int`, `[Int; 3]`, etc. +Furthermore, a type that defines a method that changes the state of an object is called a Mutable type, and it is necessary to add `!` to the variable attribute (e.g. dynamic array: `[T; !_]`) . + +## Class + +A type that has `.__new__`, `.__init__` methods, etc. Implement class-based object orientation. ## Function -Subroutines that have read permission for external variables (excluding static variables) but do not have read/write permission for external variables. In other words, it has no external side effects. -Erg functions are defined differently than Python because they do not allow side effects. +A subroutine that has read permission for external variables (excluding static variables) but does not have read/write permission for external variables. In other words, it has no external side effects. +Erg functions are defined differently than Python's because they do not allow side effects. ## Procedure @@ -71,8 +75,8 @@ A subroutine that implicitly takes `self` as the first argument. It is a differe ## Entity Objects that are not subroutines and types. -Monomorphic entities (`1`, `"a"`, etc.) are also called value objects, and polymorphic entities (`[1, 2, 3], {"a": 1}`) are also called container objects. +Monomorphic entities (`1`, `"a"`, etc.) are also called value objects, polymorphic entities (`[1, 2, 3], {"a": 1}`) are also called container objects .

Previous | Next -

+

\ No newline at end of file diff --git a/doc/EN/syntax/26_pattern_matching.md b/doc/EN/syntax/26_pattern_matching.md index 80819de2..8539689e 100644 --- a/doc/EN/syntax/26_pattern_matching.md +++ b/doc/EN/syntax/26_pattern_matching.md @@ -1,52 +1,56 @@ -# Pattern matching, Irrefutability +# pattern matching, refutable -## Patterns Available in Erg +## Patterns available in Erg -### Variable Pattern +### variable pattern -```erg -# basic assignment +``` 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 # (anonymous) function fn = x -> x + 1 fn: Int -> Int = x -> x + 1 + # higher-order type a: [Int; 4] = [0, 1, 2, 3] # or -a: Array Int, 4 = [0, 1, 2, 3] # or +a: Array Int, 4 = [0, 1, 2, 3] ``` -### Literal Pattern +### Literal patterns -```erg -# if `i` cannot be determined to be 1 at compile time, TypeError occurs. -# short hand of `_: {1} = i` +``` erg +# Raise a TypeError if `i` cannot be determined to be 1 at compile time. +# omit `_: {1} = i` 1 = i + # simple pattern matching match x: 1 -> "1" 2 -> "2" _ -> "other" + # fibonacci function -fib 0 = 0 -fib 1 = 1 -fib n: Nat = fib n-1 + fib n-2 +fib0 = 0 +fib1 = 1 +fibn: Nat = fibn-1 + fibn-2 ``` -### Constant Pattern +### constant pattern -```erg -cond = False +``` erg +cond=False match! cond: - True => print! + True => print! "cond is True" _ => print! "cond is False" PI = 3.141592653589793 @@ -58,61 +62,61 @@ name = match num: _ -> "unnamed" ``` -### Refinement Pattern +### Sieve pattern -```erg +``` erg +# these two are the same Array(T, N: {N | N >= 3}) -# == == Array(T, N | N >= 3) f M, N | M >= 0, N >= 1 = ... f(1, 0) # TypeError: N (2nd parameter) must be 1 or more ``` -### Discard (Wildcard) Pattern +### discard (wildcard) pattern -```erg +``` erg _ = 1 _: Int = 1 -zero _ = 0 +zero_ = 0 right(_, r) = r ``` -### Varargs Patterns +### Variable length patterns -Used in combination with the tuple/array/record pattern described below. +It is used in combination with the tuple/array/record pattern described later. -```erg -[i, . .j] = [1, 2, 3, 4] -assert j == [2, 3, 4]. +``` 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 +### Tuple pattern -```erg +``` erg (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) -# () can be omitted if not nested (1, 2 are treated as (1, 2)) +# If not nested, () can be omitted (1, 2 are treated as (1, 2)) m, n = 1, 2 f(x, y) = ... ``` -### Array Pattern +### array pattern -```erg +``` 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 +#### record pattern -```erg +``` erg record = {i = 1; j = 2; k = 3} {j; ...} = record # i, k will be freed @@ -127,9 +131,9 @@ age = match person: f {x: Int; y: Int} = ... ``` -### Data Class Pattern +### Data class pattern -```erg +``` erg Point = Inherit {x = Int; y = Int} p = Point::{x = 1; y = 2} Point::{x; y} = p @@ -144,46 +148,46 @@ List T. _ -> ... second self = match self: - Cons::{rest=Cons::{head; ...} ; ...} -> head + Cons::{rest=Cons::{head; ...}; ...} -> head _ -> ... ``` -### Enumeration Pattern +### enumeration pattern -* actually just an enumerated type +*Actually, it's just an enumeration type -```erg +``` erg match x: i: {1, 2} -> "one or two: {i}" _ -> "other" ``` -### Range Pattern +### range pattern -* actually just an interval type +*Actually, it is just an interval type. -```erg +``` erg # 0 < i < 1 -i: 0<... <1 = 0.5 +i: 0<..<1 = 0.5 # 1 < j <= 2 -_: {[I, J] | I, J: 1<. .2} = [1, 2] +_: {[I, J] | I, J: 1<..2} = [1, 2] # 1 <= i <= 5 match i i: 1..5 -> ... ``` -### Non-patterns and Non-patternable Items +### Things that aren't patterns, things that can't be patterned -A pattern is something that can be uniquely specified. In this respect, pattern matching differs from ordinary conditional branching. +A pattern is something that can be uniquely specified. In this respect pattern matching differs from ordinary conditional branching. -The specification of a condition is not unique. For example, to determine whether the number `n` is even, the orthodox way is `n % 2 == 0`, but it can also be written as `(n / 2).round() == n / 2`. -The non-unique form is non-trivial, whether it works correctly or is equivalent to another condition. +Condition specifications are not unique. For example, to check if the number `n` is even, the orthodox is `n % 2 == 0`, but you can also write `(n / 2).round() == n / 2`. +A non-unique form is not trivial whether it works correctly or is equivalent to another condition. -#### Set +#### set -There is no pattern for sets. There is no pattern for sets because there is no way to retrieve elements uniquely. -They can be retrieved with an iterator, but the order is not guaranteed. +There is no set pattern. Because the set has no way to uniquely retrieve the elements. +You can retrieve them by iterator, but the order is not guaranteed.

Previous | Next -

+

\ No newline at end of file diff --git a/doc/EN/syntax/27_comprehension.md b/doc/EN/syntax/27_comprehension.md index 91a9a4b5..bd4ea15b 100644 --- a/doc/EN/syntax/27_comprehension.md +++ b/doc/EN/syntax/27_comprehension.md @@ -1,56 +1,65 @@ # Comprehension -An array can be created by `[expr | (name <- iterable)+ (predicate)*]`, -And a set can be created by `{expr | (name <- iterable)+ (predicate)*}`. +Array with `[expr | (name <- iterable)+ (predicate)*]`, +set with `{expr | (name <- iterable)+ (predicate)*}`, +You can create a Dict with `{key: value | (name <- iterable)+ (predicate)*}`. -Dict can be created by `{key: value | (name <- iterable)+ (predicate)*}`. +The first part of the clauses separated by `|` is called the layout clause (location clause), the second part is called the bind clause (binding clause), and the third part is called the guard clause (conditional clause). +A guard clause can be omitted, but a bind clause cannot be omitted, and a guard clause cannot precede a bind clause. -The first part of a clause delimited by `|` is called a layout clause, the second part is called a bind clause, and the third part is called a guard clause. -The guard clause can be omitted, but not the bind clause, and the guard clause cannot be placed before the bind clause. +Comprehension example -e.g. +``` erg +# the layout clause is i +# bind clause is i <- [0, 1, 2] +assert [i | i <- [0, 1, 2]] == [0, 1, 2] -```erg -assert [i | i <- [0, 1, 2]] == [0, 1, 2]] -assert [i / 2 | i <- 0..2] == [0.0, 0.5, 1.0]] +# layout clause is i / 2 +# bind clause is i <- 0..2 +assert [i/2 | i <- 0..2] == [0.0, 0.5, 1.0] + +# layout clause is (i, j) +# bind clause i <- 0..2, j <- 0..2 +# guard clause is (i + j) % 2 == 0 assert [(i, j) | i <- 0..2; j <- 0..2; (i + j) % 2 == 0] == [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)] + assert {i % 2 | i <- 0..9} == {0, 1} assert {k: v | k <- ["a", "b"]; v <- [1, 2]} == {"a": 1, "b": 2} ``` -Erg's comprehension notation is influenced by Haskell, but there are some differences. -In Haskell's list comprehensions, the order of variables makes a difference in the result, but not in Erg. +Erg comprehensions are inspired by Haskell, but with some differences. +For Haskell list comprehensions, the order of variables makes a difference in the result, but in Erg it doesn't matter. -```haskell +``` haskell -- Haskell -[(i, j) | i <- [1..3], j <- [3..5]] == [(1,3),(1,4),(1,5),(2,3),(2,4),(2,5),(3,3),(3,4),(3,5)] -[(i, j) | j <- [3..5], i <- [1..3]] == [(1,3),(2,3),(3,3),(1,4),(2,4),(3,4),(1,5),(2,5),(3,5)] +[(i, j) | i <- [1..3], j <- [3..5]] == [(1,3),(1,4),(1,5),(2 ,3),(2,4),(2,5),(3,3),(3,4),(3,5)] +[(i, j) | j <- [3..5], i <- [1..3]] == [(1,3),(2,3),(3,3),(1 ,4),(2,4),(3,4),(1,5),(2,5),(3,5)] ``` -```erg +``` 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)] ``` -## Refinement type +## Sieve type -Similar to comprehensions are refinement types. A refinement type is a type (enumerated type) in the form `{Name: Type | Predicate}`. -In the case of a refinement type, Name is limited to one and the layout cannot be specified (but multiple values can be handled by using a tuple type, for example), and Predicate must be a compile-time computation, i.e., a constant expression. +Similar to comprehensions are sieve types. A sieve type is a type (enumerated type) created in the form `{Name: Type | Predicate}`. +In the case of the sieve type, only one Name can be specified and the layout cannot be specified (however, multiple values ​​can be handled if it is a tuple type), and the Predicate can be calculated at compile time, that is, only a constant expression can be specified. -```erg +``` erg Nat = {I: Int | I >= 0} -# If the predicate expression is and only, it can be replaced by ;. +# If the predicate expression is only and, it can be replaced with ; # Nat2D = {(I, J): (Int, Int) | I >= 0; J >= 0} Nat2D = {(I, J): (Int, Int) | I >= 0 and J >= 0} ```

Previous | Next -

+

\ No newline at end of file diff --git a/doc/EN/syntax/28_spread_syntax.md b/doc/EN/syntax/28_spread_syntax.md index 74f54a12..aed87510 100644 --- a/doc/EN/syntax/28_spread_syntax.md +++ b/doc/EN/syntax/28_spread_syntax.md @@ -1,42 +1,42 @@ # Spread assignment -In a spread assignment, a variable can be prefixed with `...` in front of the variable, all the remaining elements can be expanded into the variable. This is called a spread assignment. +In a decomposing assignment, putting `...` in front of a variable expands all remaining elements into that variable. This is called expansion assignment. -```erg -[x, ... .y] = [1, 2, 3] +``` erg +[x,...y] = [1, 2, 3] assert x == 1 -assert y == [2, 3]. -x, ... .y = (1, 2, 3) +assert y == [2, 3] +x, ...y = (1, 2, 3) assert x == 1 assert y == (2, 3) ``` ## Extract assignment -If nothing is written after `...`, the remaining elements are ignored and an assignment is made. This type of expansion assignment is specifically called an extract assignment. -Extract assignment is a useful syntax for bringing certain attributes local to a module or record. +If nothing is written after `...`, the remaining elements are ignored and assigned. This type of expansion assignment is specifically called extractive assignment. +Extraction assignment is a convenient syntax for localizing specific attributes within a module or record. -```erg -{sin; cos; tan; ...} = import "math" +``` erg +{sin; cos; tan; ..} = import "math" ``` -This way, `sin`, `cos`, `tan` can be used locally from then on. +After that, you can use `sin, cos, tan` locally. You can do the same with records. -```erg +``` erg record = {x = 1; y = 2} {x; y; ...} = record ``` -If you want to expand all of them, use `{*} = record`, this is equivalent to `open` in OCaml and so on. +If you want to expand all, use `{*} = record`. It is `open` in OCaml. -```erg +``` 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/EN/syntax/29_decorator.md b/doc/EN/syntax/29_decorator.md index 2e1889eb..a5ed389c 100644 --- a/doc/EN/syntax/29_decorator.md +++ b/doc/EN/syntax/29_decorator.md @@ -1,82 +1,81 @@ -# Decorator +# decorator (modifier) -Decorators are used to add or make explicit a specific state or behavior for a type or function. -The syntax for decorators is as follows. +Decorators are used to add or demonstrate a particular state or behavior to a type or function. +The syntax of the decorator is as follows. -```erg +``` erg @deco -X = ... +X=... ``` -There can be more than one decorator, as long as they do not conflict. +You can have multiple decorators as long as they don't conflict. -A decorator is not a special object; its entity is simply a single-argument function. A decorator is equivalent to the following pseudo code. +A decorator is not a special object, it's just a one-argument function. The decorator is equivalent to the following pseudocode. -```erg -X = ... +``` erg +X=... X = deco(X) ``` -Erg does not allow reassignment of variables, so the above code will not pass. -For a simple variable, `X = deco(...)` is the same, but for instant blocks and subroutines, you can't do that, so you need decorators. +Erg doesn't allow reassignment of variables, so code like the one above won't work. +For simple variables it's the same as `X = deco(...)`, but for instant blocks and subroutines you can't do that, so you need a decorator. -```erg +``` erg @deco -f x = ... +f x = y = ... x + y -# Can also prevent code from going horizontal. +# You can also prevent the code from becoming horizontal @LongNameDeco1 @LongNameDeco2 -C = Class ... +C = Class... ``` -Here are some frequently used built-in decorators. +Below are some frequently used built-in decorators. ## Inheritable -Indicates that the type being defined is an inheritable class. If the `scope` argument is set to `"public"`, the class can be inherited by classes in external modules. By default, it is `"private"` and cannot be inherited from outside. +Indicates that the defining type is an inheritable class. If you specify `"public"` for the argument `scope`, it will be possible to inherit even the class of the external module. By default it is `"private"` and cannot be inherited externally. -## Final +##Final -disables overriding the `"final"` method. If you attach it to a class, it becomes a non-inheritable class, but since it is the default, it is meaningless. +Make the method non-overridable. Adding it to a class makes it a non-inheritable class, but since it's the default it doesn't make sense. ## Override -Use to override an attribute, which by default Erg will fail if you try to define an attribute that is the same as the base class. +Used when overriding attributes. By default, Erg will throw an error if you try to define the same attribute as the base class. ## Impl -Indicates implementation of traits. +Indicates that the argument trait is implemented. -```erg -ClosedAdd = Trait { - . `_+_` = Self.(Self) -> Self +``` erg +Add = Trait { + .`_+_` = Self.(Self) -> Self } -ClosedSub = Trait { - . `_-_` = Self.(Self) -> Self +Sub = Trait { + .`_-_` = Self.(Self) -> Self } -C = Class {i = Int} +C = Class({i = Int}, Impl := Add and Sub) C. - @Impl ClosedAdd + @Impl Add `_+_` self, other = C.new {i = self::i + other::i} - @Impl ClosedSub + @Impl Sub `_-_` self, other = C.new {i = self::i - other::} ``` ## Attach Specifies the attachment patch that comes with the trait by default. -This allows you to reproduce the same behavior as the Rust trait. +This allows you to reproduce the same behavior as Rust traits. -```erg +``` erg # foo.er - Add R = Trait { - .`_+_` = Self.(R) -> Self.AddO .AddO = Type + .`_+_` = Self.(R) -> Self.AddO } @Attach AddForInt, AddForOdd ClosedAdd = Subsume Add(Self) @@ -87,35 +86,35 @@ AddForOdd = Patch(Odd, Impl := ClosedAdd) AddForOdd.AddO = Even ``` -This way, when you import traits from other modules, the attachment patch is automatically applied. +This will automatically apply the attachment patch when importing traits from other modules. -```erg -# Originally IntIsBinAdd, OddIsBinAdd must be imported at the same time, but can be omitted with attachment patch +``` 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 ``` -Internally, they are only connected together using the trait's `.attach` method. If there is a conflict, it can be removed using the trait's `.detach` method. +Internally it's just attached using the trait's `.attach` method. Conflicts can be removed with the trait's `.detach` method. -```erg +``` 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 is outdated and deprecated. +Indicates that the variable specification is obsolete and deprecated. ## Test -Indicates a subroutine for tests. Test subroutines are executed with the `erg test` command. +Indicates that this is a test subroutine. Test subroutines are run with the `erg test` command.

Previous | Next -

+

\ No newline at end of file diff --git a/doc/EN/syntax/30_error_handling.md b/doc/EN/syntax/30_error_handling.md index 1a45a675..c67e363a 100644 --- a/doc/EN/syntax/30_error_handling.md +++ b/doc/EN/syntax/30_error_handling.md @@ -1,22 +1,22 @@ -# Error Handling +# error handling system -Mainly uses Result type. -Erg will throw away Error type objects (not supported at top level). +Mainly use Result type. +In Erg, an error occurs if you throw away an Error type object (not supported at the top level). -## Exceptions, Interoperation with Python +## Exceptions, interop with Python -Erg does not have an exception mechanism (Exception). +Erg does not have an exception mechanism (Exception). When importing a Python function -* Set the return value as `T or Error` type. -* set the return value to `T or Panic` type (which may raise an error at runtime). +* Set return value to `T or Error` type +* `T or Panic` type (may cause runtime error) -The latter is the default for `pyimport`. If you want to import as the former, use -If you want to import as the former, specify `Error` in `pyimport`'s `exception_type` (`exception_type: {Error, Panic}`). +There are two options, `pyimport` defaults to the latter. If you want to import as the former, use +Specify `Error` in `pyimport` `exception_type` (`exception_type: {Error, Panic}`). ## Exceptions and Result types -The `Result` type represents a value that may be an error. Error handling with `Result` is superior to the exception mechanism in several ways. -First, you can tell from the type definition that a subroutine may raise an error, and it is obvious when you actually use it. +The `Result` type represents values ​​that may be errors. Error handling with `Result` is superior to the exception mechanism in several ways. +First of all, it's obvious from the type definition that the subroutine might throw an error, and it's also obvious when you actually use it. ```python # Python @@ -28,31 +28,31 @@ except e: print(e) ``` -In the above example, it is not clear from the code alone which function sends the exception. Even going back to the function definition, it is difficult to determine if the function raises the exception. +In the above example, it is not possible to tell from this code alone which function raised the exception. Even going back to the function definition, it's hard to tell if the function throws an exception. -```erg +``` erg # Erg -try! - do! - x = foo!()? .bar()? - y = baz! +try!: + do!: + x = foo!()?.bar() + y = baz!() qux!()? e => - print! + print! e ``` -On the flip side, we can see that `foo!` and `qux!` can produce errors in this example. -To be precise, `y` could also be of type `Result`, but we will have to deal with that eventually in order to use the values inside. +On the other hand, in this example we can see that `foo!` and `qux!` can raise an error. +Precisely `y` could also be of type `Result`, but you'll have to deal with it eventually to use the value inside. -That is not the only advantage of using the `Result` type. The `Result` type is also thread-safe. This means that error information can be passed around (easily) during parallel execution. +The benefits of using the `Result` type don't stop there. The `Result` type is also thread-safe. This means that error information can be (easily) passed between parallel executions. ## Context -Unlike exceptions, the `Error`/`Result` types by themselves do not have side-effects, so they do not have context, but the `.context` method can be used to add information to the `Error` object. The `.context` method is a type of method that creates a new `Error` object by consuming the `Error` object itself. It is chainable and can hold multiple contexts. +Since the `Error`/`Result` type alone does not cause side effects, unlike exceptions, it cannot have information such as the sending location (Context), but if you use the `.context` method, you can put information in the `Error` object. can be added. The `.context` method is a type of method that consumes the `Error` object itself and creates a new `Error` object. They are chainable and can hold multiple contexts. -```erg +``` erg f() = - todo() \f} + todo() \ .context "to be implemented in ver 1.2" \ .context "and more hints ..." @@ -62,23 +62,22 @@ f() # hint: and more hints ... ``` -Note that `Error` attributes such as `.msg`, `.kind`, etc., are not secondary and are not context and cannot be overwritten as they were when they were first generated. +Note that `Error` attributes such as `.msg` and `.kind` are not secondary, so they are not context and cannot be overridden as they were originally created. -## Stack Trace +## Stack trace -The `Result` type has been adopted by many other languages because of its convenience, but it has the disadvantage that the source of the error is harder to identify than the exception mechanism. -Therefore, Erg has an attribute `.stack` on the `Error` object to reproduce a pseudo-exception mechanism-like stack trace. - -`.stack` is an array of caller objects. Each time an Error object is `return`ed (including by `?`) it stacks its calling subroutine on the `.stack`. +The `Result` type is often used in other languages ​​because of its convenience, but it has the disadvantage of making it difficult to understand the source of an error compared to the exception mechanism. +Therefore, in Erg, the `Error` object has an attribute called `.stack`, and reproduces a pseudo-exception mechanism-like stack trace. +`.stack` is an array of caller objects. Each time an Error object is `returned` (including by `?`) it pushes its calling subroutine onto the `.stack`. And if it is `?`ed or `.unwrap`ed in a context where `return` is not possible, it will panic with a traceback. -```erg +``` erg f x = ... y = foo.try_some(x)? ... -g x = ... +g x = y = f(x)? ... @@ -89,22 +88,22 @@ i = g(1)? # 10 | y = foo.try_some(x)? # module::f, line 23, file "foo.er" # 23 | y = f(x)? -# module::g, line 40, file "foo.er"? +# module::g, line 40, file "foo.er" # 40 | i = g(1)? # Error: ... ``` ## Panic -Erg also has a mechanism called __panicking__ to deal with unrecoverable errors. -Unrecoverable errors are errors caused by external factors such as software/hardware malfunctions, errors that are so fatal that it makes no sense to continue executing the code, or errors that the programmer did not anticipate. When such an error occurs, the program is terminated on the spot because it cannot be restored to the normal system through the programmer's efforts. This is called "panicking". +Erg also has a mechanism for dealing with unrecoverable errors called __panicing__. +An unrecoverable error is an error caused by an external factor such as a software/hardware malfunction, an error so fatal that it makes no sense to continue executing the code, or an error unexpected by the programmer. Etc. If this happens, the program will be terminated immediately, because the programmer's efforts cannot restore normal operation. This is called "panicing". -Panicking is done with the `panic` function. +Panic is done with the `panic` function. -```erg +``` erg panic "something went wrong!" ```

Previous | Next -

+

\ No newline at end of file diff --git a/doc/EN/syntax/31_pipeline.md b/doc/EN/syntax/31_pipeline.md index 10ae5ace..652f756d 100644 --- a/doc/EN/syntax/31_pipeline.md +++ b/doc/EN/syntax/31_pipeline.md @@ -1,6 +1,6 @@ -# Pipeline Operator +# pipeline operator -The pipeline operator is used like this: +Pipeline operators are used like this: ``` erg assert f(g(x)) == (x |> g |> f) @@ -8,17 +8,20 @@ assert f(g(x, y)) == ((x, y) |> g |> f) ``` In other words, the order `Callable(object)` can be changed to `object |> Callable`. -Pipeline operators can also be used on methods. For methods, `object.method(args)` changes to `object |>.method(args)`. -It looks like just an increase in `|>`, but since the bond strength is low, the amount of `()` may be reduced. +The pipeline operator can also be used on methods. For methods, `object.method(args)` changes to `object |>.method(args)`. +It looks like just more `|>`, but since the bond strength is low, you may be able to reduce the amount of `()`. ``` erg rand = -1.0..1.0 |>.sample!() log rand # 0.2597... + 1+1*2 |>.times do log("a", end := "") # aaa -# without `|>`, the following will be `evens = (1..100).iter().filter(i -> i % 2 == 0).collect(Array)` + evens = 1..100 |>.iter |>.filter i -> i % 2 == 0 |>.collect Array +# When implemented without the pipeline operator, +_evens = (1..100).iter().filter(i -> i % 2 == 0).collect(Array) # or -_evens = 1..100\ +__evens = 1..100 \ .iter() \ .filter i -> i % 2 == 0 \ .collect Array @@ -26,4 +29,4 @@ _evens = 1..100\

Previous | Next -

+

\ No newline at end of file diff --git a/doc/EN/syntax/container_ownership.md b/doc/EN/syntax/container_ownership.md new file mode 100644 index 00000000..3067bb35 --- /dev/null +++ b/doc/EN/syntax/container_ownership.md @@ -0,0 +1,42 @@ +# Subscript (index access) + +`[]` is different from normal methods. + +``` erg +a = [!1, !2] +a[0].inc!() +assert a == [2, 2] +``` + +Recall that the return value of a subroutine cannot be a reference. +The type of `a[0]` here should clearly be `Ref!(Int!)` (the type of `a[0]` depends on the context). +So `[]` is actually part of a special syntax, just like `.`. Unlike Python, it cannot be overloaded. +It is also not possible to reproduce the behavior of `[]` in a method. + +``` 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!() +``` + +Also, `[]` can be disowned, but the element is not shifted. + +``` 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/EN/syntax/grammar.txt b/doc/EN/syntax/grammar.txt index deaff920..d9dbbb2a 100644 --- a/doc/EN/syntax/grammar.txt +++ b/doc/EN/syntax/grammar.txt @@ -76,7 +76,7 @@ record ::= '{' '=' '}' set ::= '{' '}' | '{' expr (',' expr)* ','? '}' dict ::= '{' ':' '}' - | '{' symbol ':' expr (',' symbol ':' expr)* ','? '}' + | '{' expr ':' expr (',' expr ':' expr)* ','? '}' tuple ::= '(' ')' | '(' expr (',' expr)* ','? ')' indent ::= /* ... */ diff --git a/doc/EN/syntax/indexes.md b/doc/EN/syntax/indexes.md index fb591da9..9a530a07 100644 --- a/doc/EN/syntax/indexes.md +++ b/doc/EN/syntax/indexes.md @@ -1,14 +1,14 @@ -# Index +# index -For APIs not in this index, see [here](./API/index.md). -For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of terms. +See [here](../API/index.md) for APIs not in this index. +See [here](../dev_guide/terms.md) for terminology. -## Symbols +## symbol * ! - * !-type → [Mutable type](./type/mut.md) + * !-type → [mutable type](./type/mut.md) * [#](./00_basic.md/#comment) -* $ +*$ * % * & * && @@ -16,18 +16,18 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te * () * * * [*-less multiplication](./01_literal.md/#less-multiplication) -* + (unary) - * +_ → + (unary) -* + (binary) +* + (prefix) + * +_ → + (prefix) +* + (infix) * , -* − (unary) - * −_ → − (unary) -* − (binary) +* − (prefix) + * −_ → − (prefix) +* − (infix) * −> * . → [Visibility] * / * : - * :] + * :: → [visibility] * ; * < * <: @@ -46,9 +46,9 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te * ^ * ^^ * _ - * _+_ → + (binary) - * _-_ → − (binary) -* `` + * _+_ → + (infix) + * _-_ → − (infix) +*`` * {} * {} type * {:} @@ -58,7 +58,7 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te * || * ~ -## Alphabet +## alphabet ### A @@ -68,7 +68,7 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te * [assert] * [attribute] -### B +###B * [Base] * [Bool] @@ -77,24 +77,24 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te * [Class] -### D +###D -* Deprecated +*Deprecated * [distinct] -### E +###E * [enum type] -* [Eq] -* [Erg] +*[Eq] +*[Erg] -### F +###F -* [for] +*[for] -### G +###G -### H +###H ### I @@ -103,74 +103,350 @@ For the meaning of terms, see [here](./dev_guide/terms.md) for the meaning of te * [in] * [Int] -### J +###J -### K +###K ### L -* let-polymorphism → [rank-1 polymorphism] +* let-polymorphism → [rank 1 polymorphism] * [log] -### M +###M * [match] -### N +###N -* [Nat] +*[Nat] * Never -* None -* None -* [Not] +*None +*None +*[Not] * [not] -### O +###O * [Option] * [Or] * [or] -* [Ord] +*[Ord] -### P +###P * panic * [print!](./../API/procs.md#print) * [Python] -### Q +###Q ### R * ref -* ref! +*ref! * [Result] -* [rootobj] +*[rootobj] -### S +###S -* self +*self * [Self](./type/special.md) * [side-effect](./07_side_effect.md) -* [Str] +*[Str] -### T +###T -* Trait +* Traits * [True] * [Type] * [type] -### U +###U -### V +###V ### W * [while!] -### X +###X -### Y +###Y -### Z +###Z + +## A line + +* [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 + +* [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 line + +* 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 + +* [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 + +* [Comprehension](./27_comprehension.md) +* ~~Infix operator~~ → [Infix operator] +* [namespace] + +## is a line + +* [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 + +* ~~ 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 + +* [Ghost type](./type/advanced/phantom.md) +* request attributes +* [element] +* [call] + +## Ra line + +* [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 + +* Wildcard \ No newline at end of file diff --git a/doc/EN/syntax/quick_tour.md b/doc/EN/syntax/quick_tour.md index 12ecd719..0c5e6cf7 100644 --- a/doc/EN/syntax/quick_tour.md +++ b/doc/EN/syntax/quick_tour.md @@ -1 +1,267 @@ # Quick Tour + +The documentation below `syntax` is written with the aim of being understandable even for programming beginners. +For those who have already mastered languages ​​such as Python, Rust, Haskell, etc., it may be a bit verbose. + +So, here's an overview of the Erg grammar. +Please think that the parts not mentioned are the same as Python. + +## variables, constants + +Variables are defined with `=`. As with Haskell, variables once defined cannot be changed. However, it can be shadowed in another scope. + +``` 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 +PI = 3.141592653589793 +match random.random!(0..10): + PIs: + log "You get PI, it's a miracle!" +``` + +## declaration + +Unlike Python, only the variable type can be declared first. +Of course, the declared type and the type of the object actually assigned to must be compatible. + +``` erg +i: Int +i = 10 +``` + +## Functions + +You can define it just like in Haskell. + +``` erg +fib0 = 0 +fib1 = 1 +fibn = fib(n - 1) + fib(n - 2) +``` + +An anonymous function can be defined like this: + +``` erg +i -> i + 1 +assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4] +``` + +## operator + +The Erg-specific operators are: + +### mutating operator (!) + +It's like `ref` in Ocaml. + +``` erg +i = !0 +i.update! x -> x + 1 +assert i == 1 +``` + +## procedures + +Subroutines with side effects are called procedures and are marked with `!`. + +``` erg +print! 1 # 1 +``` + +## generic function (polycorrelation) + +``` erg +id|T|(x: T): T = x +id(1): Int +id("a"): Str +``` + +## Records + +You can use the equivalent of records in ML-like languages ​​(or object literals in JS). + +``` erg +p = {x = 1; y = 2} +``` + +## Ownership + +Ergs are owned by mutable objects (objects mutated with the `!` operator) and cannot be rewritten from multiple places. + +``` erg +i = !0 +j = i +assert j == 0 +i#MoveError +``` + +Immutable objects, on the other hand, can be referenced from multiple places. + +## Visibility + +Prefixing a variable with `.` makes it a public variable and allows it to be referenced from external modules. + +``` erg +# foo.er +.x = 1 +y = 1 +``` + +``` erg +foo = import "foo" +assert foo.x == 1 +foo.y # VisibilityError +``` + +## pattern matching + +### variable pattern + +``` erg +# basic assignments +i = 1 +# with type +i: Int = 1 +# functions +fn x = x + 1 +fn: Int -> Int = x -> x + 1 +``` + +### Literal patterns + +``` erg +# if `i` cannot be determined to be 1 at compile time, TypeError occurs. +# shorthand of `_: {1} = i` +1 = i +# simple pattern matching +match x: + 1 -> "1" + 2 -> "2" + _ -> "other" +# fibonacci function +fib0 = 0 +fib1 = 1 +fibn: Nat = fibn-1 + fibn-2 +``` + +### constant pattern + +``` erg +PI = 3.141592653589793 +E = 2.718281828459045 +num = PI +name = match num: + PI -> "pi" + E -> "e" + _ -> "unnamed" +``` + +### discard (wildcard) pattern + +``` 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] +assert j == [2, 3, 4] +first|T|(fst: T, ...rest: T) = fst +assert first(1, 2, 3) == 1 +``` + +### Tuple pattern + +``` erg +(i, j) = (1, 2) +((k, l), _) = ((1, 2), (3, 4)) +# If not nested, () can be omitted (1, 2 are treated as (1, 2)) +m, n = 1, 2 +``` + +### array pattern + +``` erg +length[] = 0 +length[_, ...rest] = 1 + lengthrest +``` + +#### record pattern + +``` erg +{sin; cos; tan; ...} = import "math" +{*} = import "math" # import all + +person = {name = "John Smith"; age = 20} +age = match person: + {name = "Alice"; _} -> 7 + {_; age} -> age +``` + +### Data class pattern + +``` erg +Point = Inherit {x = Int; y = Int} +p = Point::{x = 1; y = 2} +Point::{x; y} = p +``` + +## Comprehensions + +``` erg +odds = [i | i <- 1..100; i % 2 == 0] +``` + +## class + +Erg does not support multiple/multilevel inheritance. + +## Traits + +They are similar to Rust traits, but in a more literal sense, allowing composition and decoupling, and treating attributes and methods as equals. +Also, it does not involve implementation. + +``` 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. + ... +``` + +## patch + +You can give implementations to classes and traits. + +## Sieve type + +A predicate expression can be type-restricted. + +``` erg +Nat = {I: Int | I >= 0} +``` + +## parametric type with value (dependent type) + +``` erg +a: [Int; 3] +b: [Int; 4] +a + b: [Int; 7] +``` \ No newline at end of file diff --git a/doc/EN/syntax/type/14_dependent.md b/doc/EN/syntax/type/14_dependent.md index 3108fd7c..c7ec3eb6 100644 --- a/doc/EN/syntax/type/14_dependent.md +++ b/doc/EN/syntax/type/14_dependent.md @@ -1,37 +1,37 @@ -# Dependent Types +# dependent type -Dependent types are one of the most important features of Erg. -Dependent types are types that take values as arguments. Normal polymorphic types can take only types as arguments, but dependent types loosen that restriction. +Dependent types are a feature that can be said to be the biggest feature of Erg. +A dependent type is a type that takes a value as an argument. Ordinary polymorphic types can take only types as arguments, but dependent types relax that restriction. -Dependent types, such as `[T; N]`(`Array(T, N)`), are equivalent. -This type depends not only on the type `T` of the contents, but also on the number `N` of the contents. `N` contains objects of type `Nat`. +Dependent types are equivalent to `[T; N]` (`Array(T, N)`). +This type is determined not only by the content type `T` but also by the number of contents `N`. `N` contains an object of type `Nat`. -```erg -a1 = [1, 2, 3]. -assert a1 in [Nat; 3]. +``` 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]. +assert a1 in [Nat; 4] +assert a1 + a2 in [Nat; 7] ``` -If the type object passed as a function argument is related to a return type, write the following +If the type object passed in the function argument is related to the return type, write: -```erg +``` 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. -Dependent types already exist in some languages, but Erg has the unique feature of allowing you to define procedural methods on dependent types. +Dependent types themselves exist in existing languages, but Erg has the feature of defining procedural methods on dependent types. -```erg -x = 1 +``` erg +x=1 f x = print! f::x, module::x -# Phantom types have an attribute called Phantom that has the same value as the type argument +# The Phantom type has an attribute called Phantom whose value is the same as the type argument T X: Int = Class Impl := Phantom X T(X). x self = self::Phantom @@ -39,36 +39,36 @@ T(X). T(1).x() # 1 ``` -Type arguments of variable-dependent types can be transitioned by applying methods. -Transitions are specified with `~>`. +Type arguments of mutable dependent types can be transitioned by method application. +Transition specification is done with `~>`. -```erg -# Note that `Id` is an immutable type and cannot be transitioned. -VM!(State: {"stopped", "running"}! := _, Id: Nat := _) = Class(... State). +``` 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.initialize_something!() self::set_phantom!("running") -# You can also cut out each type argument (only within the defined module) -VM!.new() = VM!(!" stopped", 1).new() -VM!("running" ~> "running").stop! ref! self = +# You can also cut out by type argument (only in the module where it's defined) +VM!.new() = VM!(!"stopped", 1).new() +VM!("running" ~> "running").stop!ref!self = self.close_something!() - self::set_phantom!("stopped")) + self::set_phantom!("stopped") vm = VM!.new() vm.start!() vm.stop!() -vm.stop!() # TypeError: VM! stopped", 1) doesn't have .stop! -# TypeError: VM! running", 1) has .stop! +vm.stop!() # TypeError: VM!(!"stopped", 1) doesn't have .stop!() +# hint: VM!(!"running", 1) has .stop!() ``` -You can also create dependent types by incorporating or inheriting from existing types. +You can also embed or inherit existing types to create dependent types. -```erg -MyArray(T, N) = Inherit [T; N]. +``` erg +MyArray(T, N) = Inherit[T; N] -# type of self: Self(T, N) in conjunction with .array! +# The type of self: Self(T, N) changes in conjunction with .array MyStruct!(T, N: Nat!) = Class {.array: [T; !N]} -``` +``` \ No newline at end of file diff --git a/doc/EN/syntax/type/18_mut.md b/doc/EN/syntax/type/18_mut.md index e6a9c083..63ab9719 100644 --- a/doc/EN/syntax/type/18_mut.md +++ b/doc/EN/syntax/type/18_mut.md @@ -1,54 +1,54 @@ # Mutable Type -> __Warning__: The information in this section is out of date and contains some errors. +> __Warning__: The information in this section is old and contains some errors. -In Erg, by default, all types are immutable, i.e., their internal state cannot be updated. -However, variable types can of course be defined. Variable types are declared with `!`. +By default all types in Erg are immutable, i.e. their internal state cannot be updated. +But you can of course also define mutable types. Variable types are declared with `!`. -```erg +``` erg Person! = Class({name = Str; age = Nat!}) -Person! +Person!. greet! ref! self = print! "Hello, my name is {self::name}. I am {self::age}." - inc_age! ref! self = self::name.update! old -> old + 1 + inc_age!ref!self = self::name.update!old -> old + 1 ``` -To be precise, types whose base type is a variable type or a composite type that contains a variable type must end the type name with `!`! Types without `!` may exist in the same namespace and be treated as separate types. -In the example above, the `.age` attribute is variable and the `.name` attribute is immutable. If any one attribute is variable, the whole is a variable type. +To be precise, a type whose base type is a mutable type, or a composite type containing mutable types, must have a `!` at the end of the type name. Types without `!` can exist in the same namespace and are treated as separate types. +In the example above, the `.age` attribute is mutable and the `.name` attribute is immutable. If even one attribute is mutable, the whole is mutable. -A variable type can define procedural methods to rewrite instances, but just because it has procedural methods does not necessarily make it a variable type. For example, the array type `[T; N]` implements a `sample!` method that randomly selects elements, but this of course does not make destructive changes to the array. +Mutable types can define procedural methods that rewrite instances, but having procedural methods does not necessarily make them mutable. For example, the array type `[T; N]` implements a `sample!` method that randomly selects an element, but of course does not destructively modify the array. -Destructive manipulation of variable type objects is done primarily via the `.update!` method. The `.update!` method is a higher-order procedure that applies the function `f` to `self` to update it. +Destructive operations on mutable objects are primarily done via the `.update!` method. The `.update!` method is a higher-order procedure that updates `self` by applying the function `f`. -```erg +``` 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`. +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 invariantizes the value and performs the operation. +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 polymorphic invariant types, the type parameter `T` of a type is implicitly assumed to be an invariant type. +In a polymorphic immutable type the type argument `T` of the type is implicitly assumed to be immutable. -```erg +``` erg # ImmutType < Type -K T: ImmutType = Class ... -K! T: Type = Class ... +KT: ImmutType = Class ... +K!T: Type = Class ... ``` -In the standard library, mutable types `T!` are often based on immutable types `T`. However, `T!` and `T` types have no special linguistic relationship, and may not be constructed as such [1](#1) . +In the standard library, variable `(...)!` types are often based on immutable `(...)` types. However, `T!` and `T` types have no special linguistic relationship, and may not be constructed as such [1](#1) . Note that there are several types of object mutability. Below we will review the immutable/mutable semantics of the built-in collection types. @@ -60,20 +60,20 @@ Below we will review the immutable/mutable semantics of the built-in collection ## mutable types [T!; N] # can change contents one by one [T; !N] # variable length, content is immutable but can be modified by adding/deleting elements -[!T; N] # The content is an immutable object, but it can be replaced with an object whose type has been changed. -[!T; !N] # type and length can be changed. -[T!; !N] # contents and length can be changed. -[T!; N] # contents and type can be changed. -[T!; !N] # any variable operation can be performed +[!T; N] # The content is an immutable object, but it can be replaced by a different type (actually replaceable by not changing the type) +[!T; !N] # type and length can be changed +[T!; !N] # content and length can be changed +[!T!; N] # content and type can be changed +[!T!; !N] # Can perform all sorts of mutable operations ``` -Of course, it is not necessary to memorize and use all of these. -For variable array types, all you have to do is append `!`, and for practical use, `[T; N]`, `[T!; N]`, `[T; !N]`, and `[T!; !N]` can cover most cases. +Of course, you don't have to memorize and use all of them. +For variable array types, just add `!` to the part you want to be variable, and practically `[T; N]`, `[T!; N]`, `[T; !N]`, ` [T!; !N]` can cover most cases. -These array types are sugar-coated, and the actual types are as follows. +These array types are syntactic sugar, the actual types are: -```erg -# There are actually 4 types. +``` erg +# actually 4 types [T; N] = Array(T, N) [T; !N] = Array!(T, !N) [!T; N] = ArrayWithMutType!(!T, N) @@ -83,81 +83,81 @@ These array types are sugar-coated, and the actual types are as follows. [!T!; !N] = ArrayWithMutTypeAndLength!(!T!, !N) ``` -Note that type changeable means this. +This is what it means to be able to change the type. -```erg -a = [1, 2, 3].into [!Nat; 3]. +``` erg +a = [1, 2, 3].into [!Nat; 3] a.map!(_ -> "a") -a: [!Str; 3]. +a: [!Str; 3] ``` The same is true for other collection types. -```erg -## tuple types +``` erg +# tuple type ## immutable types -(T, U) ## immutable types: number of elements, contents unchangeable +(T, U) # No change in number of elements, contents cannot be changed ## mutable types -(T!, U) # number of elements immutable, first element can be changed -(T, U)! # number of elements invariant, contents can be replaced +(T!, U) # constant number of elements, first element can be changed +(T, U)! # No change in number of elements, content can be replaced ... ``` -```erg -## set types +``` erg +# Set type ## immutable types -{T; N} ## number of immutable elements, contents cannot be changed +{T; N} # number of immutable elements, contents cannot be changed ## mutable types -{T!; N} ## number of immutable types, contents can be changed (one by one) -{T; N}! ## variable number of elements, contents are unchangeable, but can be changed by adding or deleting elements, and the type inside can be changed. -{T!; N}! # variable number of elements, contents can be changed +{T!; N} # number of immutable elements, content can be changed (one by one) +{T; N}! # Number of variable elements, content cannot be changed +{T!; N}! # Number of variable elements, content can be changed ... ``` -```erg -# dictionary types. +``` erg +# Dictionary type ## immutable types -{K: V} ## invariant length, contents cannot be changed +{K: V} # immutable length, contents cannot be changed ## mutable types -{K: V!} ## invariant length, can change values (one by one) -{K: V}! ## variable length, cannot change content, but can add/delete elements, can change type inside +{K: V!} # constant length, values ​​can be changed (one by one) +{K: V}! # Variable length, content cannot be changed, but can be added or deleted by adding or removing elements, content type can also be changed ... ``` -```erg -# Record type. +``` erg +# Record type ## immutable types -{x = Int; y = Str} ## cannot change content +{x = Int; y = Str} # content cannot be changed ## mutable types -{x = Int!; y = Str} # The value of x can be changed -{x = Int; y = Str}! ## can replace any instance of {x = Int; y = Str}! +{x = Int!; y = Str} # can change the value of x +{x = Int; y = Str}! # replace any instance of {x = Int; y = Str} ... ``` -If `T = (...)` and simply `T! = (...)!`, The type `(...)` is called a simple structural type. A simple structural type can also be said to be a type that (semantically) has no internal structure. -Arrays, tuples, sets, dictionaries, and record types are not all simple structure types, but Int and sieve types are. +A type `(...)` that simply becomes `T! = (...)!` when `T = (...)` is called a simple structured type. A simple structured type can also be said (semantically) to be a type that has no internal structure. +Arrays, tuples, sets, dictionaries, and record types are all non-simple structured types, but Int and Sieve types are. -```erg -## refinement type -## enumerated types -{1, 2, 3} # one of 1, 2, 3, cannot change -{1, 2, 3}! ## any of 1, 2, or 3, can be changed -## Interval type -1..12 # one of 1~12, cannot be changed -1..12! # any of 1~12, can be changed -## Sieve type (general form) -{I: Int | I % 2 == 0} # even type, cannot change +``` 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 notation above is recommended +{I: Int | I % 2 == 0}! # Exactly the same type as above, but the above notation is preferred ``` -From the above explanation, a variable type is not only one that is variable itself, but also one whose internal type is variable. -Types such as `{x: Int!}` and `[Int!; 3]` are internal variable types in which the inner object is variable and not the instance itself. +From the above explanation, mutable types include not only those that are themselves mutable, but also those whose internal types are mutable. +Types such as `{x: Int!}` and `[Int!; 3]` are internal mutable types where the object inside is mutable and the instance itself is not mutable. -Types that have an internal structure and the type constructor itself is `! In the case of the type `K!(T, U)` with `! Local modifications are also possible. -However, since it is desirable to keep modification privileges as local as possible, it is better to use `K(T!, U)` when only `T` can be changed. -And in the case of type `T!`, which has no internal structure, this instance is simply a replaceable `T` box. The type cannot be changed by methods. +For a type `K!(T, U)` that has internal structure and has a `!` on the type constructor itself, `*self` can change the whole object. Local changes are also possible. +However, it is desirable to keep the change authority as local as possible, so if only `T` can be changed, it is better to use `K(T!, U)`. +And for the type `T!` which has no internal structure, this instance is simply a box of `T` which can be swapped. A method cannot change the type. --- -1 It is intentional that `T!` and `T` types have no special linguistic relationship. It is a design. If there is a relationship, for example, if the `T`/`T!` type exists in the namespace, it will not be possible to introduce the `T!`/`T` type from another module. Also, the mutable type is not uniquely defined for the immutable type. Given the definition `T = (U, V)`, the possible variable subtypes of `T!` are `(U!, V)` and `(U, V!)`. [↩](#f1) +1 It is intentional that `T!` and `T` types have no special linguistic relationship. It's a design. If there is a relationship, for example, if the `T`/`T!` type exists in the namespace, it will not be possible to introduce the `T!`/`T` type from another module. Also, the mutable type is not uniquely defined for the immutable type. Given the definition `T = (U, V)`, the possible variable subtypes of `T!` are `(U!, V)` and `(U, V!)`. [↩](#f1) \ No newline at end of file diff --git a/doc/EN/syntax/type/19_bound.md b/doc/EN/syntax/type/19_bound.md index 42de3272..90411ac4 100644 --- a/doc/EN/syntax/type/19_bound.md +++ b/doc/EN/syntax/type/19_bound.md @@ -1,18 +1,18 @@ # Type Bound -A type boundary is a condition on the type specification. The guard (guard clause) is the function that makes this possible. -In addition to function signatures and anonymous function signatures, sieve types can also use this feature. -The guard is described after the return type. +Type bounds add conditions to type specifications. A function that realizes this is a guard (guard clause). +This feature is available for function signatures, anonymous function signatures, as well as sieve types. +Guards are written after the return type. -## Predicate Expressions (Predicate) +## Predicate -The condition that a variable satisfies can be specified by an expression (predicate) that returns a `Bool`. -You can use [value object](./08_value.md) and operators. Compile-time functions may be supported in future versions. +You can specify the condition that the variable satisfies with an expression (predicate expression) that returns `Bool`. +Only [value objects](./08_value.md) and operators can be used. Compile-time functions may be supported in future versions. -```erg +``` 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/EN/syntax/type/advanced.md b/doc/EN/syntax/type/advanced.md index 6849961d..1fdeed74 100644 --- a/doc/EN/syntax/type/advanced.md +++ b/doc/EN/syntax/type/advanced.md @@ -1,2 +1 @@ -The following sections describe more advanced type systems. Beginners do not need to read the entire section. - +In the following, we will discuss more advanced type systems. Beginners do not have to read all the sections. \ No newline at end of file diff --git a/doc/EN/syntax/type/advanced/GADTs.md b/doc/EN/syntax/type/advanced/GADTs.md index f869085e..ee5da587 100644 --- a/doc/EN/syntax/type/advanced/GADTs.md +++ b/doc/EN/syntax/type/advanced/GADTs.md @@ -1,8 +1,8 @@ # Generalized Algebraic Data Types (GADTs) -Erg can create Generalized Algebraic Data Types (GADTs) by classifying Or (Union) types. +Erg can create Generalized Algebraic Data Types (GADTs) by classifying Or types. -```erg +``` 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) @@ -10,7 +10,7 @@ List. nil|T|() = Self(T).new Nil(T).new() cons head, rest | T = Self(T).new Cons(T).new(head, rest) head self = match self: - {head; ...} : Cons _ -> head + {head; ...}: Cons_ -> head _: Nil -> panic "empty list" {nil; cons; ...} = List @@ -18,17 +18,17 @@ print! cons(1, cons(2, nil())).head() # 1 print! nil.head() # RuntimeError: "empty list" ``` -not `List(T).nil() = ...`, but `List.nil|T|() = ...`. This is because the type specification is no longer needed when using it. +The reason we say `List.nil|T|() = ...` instead of `List(T).nil() = ...` is that we don't need to specify the type when using it. -```erg +``` erg i = List.nil() _: List Int = cons 1, i ``` -The `List T` defined here is a GADTs, but it is a naive implementation and does not demonstrate the true value of GADTs. -For example, the `.head` method above will give a runtime error if the contents are empty, but this check can be done at compile time. +The `List T` defined here is GADTs, but it's a naive implementation and doesn't show the true value of GADTs. +For example, the `.head` method above will throw a runtime error if the body is empty, but this check can be done at compile time. -```erg +``` erg List: (Type, {"Empty", "Nonempty"}) -> Type List T, "Empty" = Class(Impl := Phantom T) List T, "Nonempty" = Class {head = T; rest = List(T, _)}, Impl := Unpack @@ -43,10 +43,10 @@ print! cons(1, cons(2, nil())).head() # 1 print! nil().head() # TypeError ``` -The GADTs example often described is a list whose contents can be judged as empty or not by type, as shown above. -Erg allows for further refinement, defining a list with length. +An example of GADTs that is often explained on the street is a list that can judge whether the contents are empty or not by type as above. +Erg can be further refined to define a list with length. -```erg +``` 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 @@ -56,11 +56,11 @@ List. List(_, N | N >= 1). head {head; ...} = head List(_, N | N >= 2). - pair {head = first; rest = {head = second; ...}} = [first, second]. + pair {head = first; rest = {head = second; ...}} = [first, second] {nil; cons; ...} = List -print! cons(1, cons(2, nil)).pair() # [1, 2]. -cons(1, nil).pair() # TypeError -cons(1, nil).head() # 1 -print! nil.head() # TypeError -``` +print! cons(1, cons(2, nil)).pair() # [1, 2] +print! cons(1, nil).pair() # TypeError +print! cons(1, nil).head() # 1 +print! nil. head() # TypeError +``` \ No newline at end of file diff --git a/doc/EN/syntax/type/advanced/_rank2type.md b/doc/EN/syntax/type/advanced/_rank2type.md new file mode 100644 index 00000000..11b4afcd --- /dev/null +++ b/doc/EN/syntax/type/advanced/_rank2type.md @@ -0,0 +1,142 @@ +# rank-2 polymorphism + +> __Warning__: This document is out of date and contains errors in general. + +Erg allows you to define functions that accept various types such as `id|T|(x: T): T = x`, ie polycorrelations. +So, can we define a function that accepts polycorrelations? +For example, a function like this (note that this definition is erroneous): + +``` 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 +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 +# 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 +id x = x +id: |T: Type| T -> T +``` + +A universal type has special rules for association with the function type constructor `->`, and the semantics of the type are completely different depending on the way of association. + +Think about this in terms of simple one-argument functions. + +``` 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 +# id: |T: Type| T -> T +id x = x +# same type as `f1` +take_univq_f_and_return_i(_: (|T: Type| T -> T), i: Int): Int = i +# same type as `f2` +take_arbit_f_and_return_i|T: Type|(_: T -> T, i: Int): Int = i +# same type as `f3` +take_i_and_return_univq_f(_: Int): (|T: Type| T -> T) = id +# same type as `f4` +take_i_and_return_arbit_f|T: Type|(_: Int): (T -> T) = id +``` + +After applying it, you will notice the difference. + +``` 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 +``` + +An open polycorrelation function type is specifically called an __arbitrary function type__. Arbitrary function types have an infinite number of possibilities: `Int -> Int`, `Str -> Str`, `Bool -> Bool`, `|T: Type| T -> T`, ... be. +On the other hand, there is only one closed (returning an object of the same type as the argument) polymorphic type `|T: Type| T -> T`. Such types are specifically called __polymorphic function types__. +In other words, `f1` can be passed `x: Int -> x+1`, `x: Bool -> not x`, `x -> x`, etc. = `f1` is a polycorrelated number Yes, but you can only pass `x -> x` etc. to `f2` = `f2` is not __a polycorrelation__. +But the types of functions like `f2` are clearly different from normal types, and we need new concepts to handle them well. That is the "rank" of the type. + +Regarding the definition of rank, types that are not quantified, such as `Int`, `Str`, `Bool`, `T`, `Int -> Int`, `Option Int`, etc., are treated as "rank 0". + +``` erg +# K is a polynomial kind such as Option +R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0) +``` + +Next, types with first-order universal quantification, such as `|T| T -> T`, or types that include them in the return value type are “rank 1”. +In addition, types with second-order universal quantification (types that have rank 1 types as arguments such as `(|T| T -> T) -> Int`) or types that include them in the return type are called "rank 2 ”. +The above is repeated to define the “Rank N” type. Also, the rank-N types include all types with a rank of N or less. Therefore, a type with mixed ranks has the same rank as the highest among them. + +``` 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 + (|T: Type| T -> T) -> (|U: Type| U -> U) +=> R1 -> R1 +=> R1 -> R2 +=> R2 + +Option(|T: Type| T -> T) +=> Option(R1) +=> K(R1) +=> R1 +``` + +By definition, `tuple_map` is a rank-2 type. + +``` erg +tuple_map: + ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) +=> (R1, R0) -> R0 +=> R1 -> R2 +=> R2 +``` + +Erg can handle types up to rank 2 (because rank N types include all types with rank N or less, to be exact, all Erg types are rank 2 types). Attempting to construct a function of more types is an error. +For example, all functions that handle polycorrelations as they are require specification of other argument types. Also, such a function is not configurable. + +``` 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)) +``` + +It is known that types with rank 3 or higher are theoretically undecidable by type inference. However, most practical needs can be covered by the rank 2 type. \ No newline at end of file diff --git a/doc/EN/syntax/type/advanced/default_param.md b/doc/EN/syntax/type/advanced/default_param.md index e8108ea6..d18a9e02 100644 --- a/doc/EN/syntax/type/advanced/default_param.md +++ b/doc/EN/syntax/type/advanced/default_param.md @@ -1,8 +1,8 @@ -# Function type with default parameter +# Function type with default arguments -First, let's look at an example of the use of default parameters. +First, let's look at an example of using default arguments. -```erg +``` erg f: (Int, Int, z := Int) -> Int f(x, y, z := 0) = x + y + z @@ -11,18 +11,18 @@ g(x, y, z := 0, w := 1) = x + y + z + w fold: ((Int, Int) -> Int, [Int], acc := Int) -> Int fold(f, [], acc) = acc -fold(f, arr, acc := 0) = fold(f, arr[1...]) , f(acc, arr[0])) +fold(f, arr, acc := 0) = fold(f, arr[1..], f(acc, arr[0])) assert fold(f, [1, 2, 3]) == 6 assert fold(g, [1, 2, 3]) == 8 ``` -The parameters after `:=` are default parameters. +Arguments after `:=` are default arguments. The subtyping rules are as follows. -```erg +``` erg ((X, y := Y) -> Z) <: (X -> Z) -((X, y := Y, ...) -> Z) -> Z) <: ((X, ...) -> Z) +((X, y := Y, ...) -> Z) <: ((X, ...) -> Z) ``` -The first means that a function with a default parameter is identical to a function without it. -The second means that any default parameter can be omitted. +The first means that a function with default arguments can be identified with a function without. +The second means that any default argument can be omitted. \ No newline at end of file diff --git a/doc/EN/syntax/type/advanced/keyword_param.md b/doc/EN/syntax/type/advanced/keyword_param.md index debadb33..45db64bc 100644 --- a/doc/EN/syntax/type/advanced/keyword_param.md +++ b/doc/EN/syntax/type/advanced/keyword_param.md @@ -1,26 +1,26 @@ # Function type with keyword arguments -```erg +``` 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 +``` 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 eliminated or replaced. -However, it is not possible to do both at the same time. -That is, `(x: T, y: U) -> V` cannot be cast to `(U, T) -> V`. -Note that keyword arguments are only available in top-level tuples, not in arrays or nested tuples. +This means that keyword arguments can be deleted or replaced. +But you can't do both at the same time. +That is, you cannot cast `(x: T, y: U) -> V` to `(U, T) -> V`. +Note that keyword arguments are attached only to top-level tuples, and not to arrays or nested tuples. -```erg +``` 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/EN/syntax/type/advanced/kind.md b/doc/EN/syntax/type/advanced/kind.md index 9639faf5..64cd1f35 100644 --- a/doc/EN/syntax/type/advanced/kind.md +++ b/doc/EN/syntax/type/advanced/kind.md @@ -9,7 +9,7 @@ Note that `->` itself, which is an anonymous function operator, can also be seen Also note that a kind that is not an atomic kind is not a type. Just as `-1` is a number but `-` is not, `Option Int` is a type but `Option` is not. `Option` etc. are sometimes called type constructors. -```erg +``` erg assert not Option in Type assert Option in Type -> Type ``` @@ -17,7 +17,7 @@ assert Option in Type -> Type So code like the following will result in an error: In Erg, methods can only be defined in atomic kinds, and the name `self` cannot be used anywhere other than the first argument of a method. -```erg +``` erg #K is an unary kind K: Type -> Type K T = Class... @@ -32,7 +32,7 @@ Examples of binary or higher kinds are `{T: U}`(: `(Type, Type) -> Type`), `(T, There is also a zero-term kind `() -> Type`. This is sometimes equated with an atomic kind in type theory, but is distinguished in Erg. An example is `Class`. -```erg +``` erg Nil = Class() ``` @@ -40,23 +40,23 @@ Nil = Class() There is also a partial type relation, or rather a partial kind relation, between multinomial kinds. -```erg +``` 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. -```console +``` erg ∀T. L T <: K T <=> L <: K ``` -## Higher-order Kind +## higher kind There is also a higher-order kind. This is a kind of the same concept as a higher-order function, a kind that receives a kind itself. `(Type -> Type) -> Type` is a higher kind. Let's define an object that belongs to a higher kind. -```erg +``` erg IntContainerOf K: Type -> Type = K Int assert IntContainerOf Option == Option Int assert IntContainerOf Result == Result Int @@ -65,30 +65,30 @@ assert IntContainerOf in (Type -> Type) -> Type The bound variables of a polynomial kind are usually denoted as K, L, ..., where K is K for Kind. -## Set kind +## set kind In type theory, there is the concept of a record. This is almost the same as the Erg record [2](#2). -```erg +``` 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} ``` 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}} ``` 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} ``` @@ -96,7 +96,7 @@ Pointy = {Point} An important property of record kind is that if `T: |T|` and `U <: T` then `U: |T|`. This is also evident from the fact that enums are actually syntactic sugar for sieve types. -```erg +``` 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} @@ -105,7 +105,7 @@ This is also evident from the fact that enums are actually syntactic sugar for s `U <: T` in type constraints is actually syntactic sugar for `U: |T|`. A kind that is a set of such types is commonly called a set kind. Setkind also appears in the Iterator pattern. -```erg +``` erg Iterable T = Trait { .Iterator = {Iterator} .iter = Self(T).() -> Self.Iterator T @@ -114,7 +114,7 @@ Iterable T = Trait { ## Type inference for polynomial kinds -```erg +``` erg Container K: Type -> Type, T: Type = Patch K(T, T) Container (K). f self = ... @@ -146,4 +146,4 @@ In this case, patches are selected according to the following priority criteria. 1 In type theory notation, `*=>*` [↩](#f1) -2 There are subtle differences such as visibility. [↩](#f2) +2 There are subtle differences such as visibility. [↩](#f2) \ No newline at end of file diff --git a/doc/EN/syntax/type/advanced/marker_trait.md b/doc/EN/syntax/type/advanced/marker_trait.md index 2c3af3f8..17b8326b 100644 --- a/doc/EN/syntax/type/advanced/marker_trait.md +++ b/doc/EN/syntax/type/advanced/marker_trait.md @@ -1,20 +1,20 @@ # Marker Trait -A marker trait is a trait with no required attributes. That is, it can be Impl without implementing a method. -It may seem meaningless without the required attribute, but it registers the information that it belongs to that trait, so that patch methods can be used and the compiler can give it special treatment. +Marker traits are traits without required attributes. That is, you can Impl without implementing any method. +It seems meaningless without the required attribute, but since the information that it belongs to the trait is registered, you can use the patch method or get special treatment by the compiler. -All marker traits are encompassed by the `Marker` trait. -The `Light` provided in the standard is a kind of marker trait. +All marker traits are subsumed by the `Marker` trait. +`Light` provided as standard is a kind of marker trait. -```erg +``` erg Light = Subsume Marker ``` -```erg +``` erg Person = Class {.name = Str; .age = Nat} and Light ``` -```erg +``` erg M = Subsume Marker MarkedInt = Inherit Int, Impl := M @@ -24,8 +24,8 @@ assert i + 1 == 2 assert i in M ``` -The marker class can also be removed with the `Excluding` argument. +Marker classes can also be excluded with the `Excluding` argument. -```erg +``` erg NInt = Inherit MarkedInt, Impl := N, Excluding: M -``` +``` \ No newline at end of file diff --git a/doc/EN/syntax/type/advanced/special.md b/doc/EN/syntax/type/advanced/special.md index 12f164a8..8fa6825b 100644 --- a/doc/EN/syntax/type/advanced/special.md +++ b/doc/EN/syntax/type/advanced/special.md @@ -1,22 +1,22 @@ -# Special Type(Self, Super) +# Special types (Self, Super) -`Self` represents itself types. It can be used simply as an alias, however note that its meaning changes in derived types (it refers to the derived own type). +`Self` represents its own type. You can just use it as an alias, but note that the meaning changes in derived types (refers to the own type). -```erg +``` 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 types of base classes. The method itself refers to the base class, however the instance uses its own type. +`Super` represents the type of the base class. The method itself refers to the base class, but the instance uses its own type. -```erg +``` erg @Inheritable C = Class() @@ -25,15 +25,15 @@ D. new_super() = Super.new() new_c() = C.new() -classof D.new_super() # D -classof D.new_c() # C +classof D. new_super() # D +classof D. new_c() # C ``` -## Special Type Variable +## special type variables -`Self` and `Super` can be used as type variables in structural types and traits. It refers to a class, which is a subtype of that type. That is, `Self` in type `T` means `Self <: T`. +`Self` and `Super` can be used as type variables in structured types and traits. This refers to classes that are subtypes of that type. That is, `Self` in type `T` means `Self <: T`. -```erg +``` erg Add R = Trait { .AddO = Type .`_+_`: Self, R -> Self.AddO @@ -48,4 +48,4 @@ assert 1 in Add(Int, Int) assert 1 in ClosedAdd assert Int < Add(Int, Int) assert Int < ClosedAdd -``` +``` \ No newline at end of file diff --git a/doc/EN/syntax/type/advanced/typeof.md b/doc/EN/syntax/type/advanced/typeof.md new file mode 100644 index 00000000..ab16bb84 --- /dev/null +++ b/doc/EN/syntax/type/advanced/typeof.md @@ -0,0 +1,65 @@ +# Typeof, classof + +`Typeof` is a function that can peek into Erg's type inference system, and its behavior is complex. + +``` 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} +``` + +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 +i: Int = ... +assert Typeof(i) == {__valueclass_tag__ = Phantom Int} +s: Str = ... +assert Typeof(s) == {__valueclass_tag__ = Phantom Str} +``` + +`Typeof` outputs only structured types. I explained that structured types include attribute types, sieve types, and (true) algebraic types. +These are independent types (inference precedence exists) and inference conflicts do not occur. +Attribute types and algebraic types can span multiple classes, while sieve types are subtypes of a single class. +Erg infers object types as sieve types as much as possible, and when that is not possible, expands sieve base classes to structured types (see below). + +## structured + +All classes can be converted to derived types. This is called __structuring__. The structured type of a class can be obtained with the `Structure` function. +If a class is defined with `C = Class T` (all classes are defined in this form) then `Structure(C) == T`. + +``` 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 structured +# You can't actually define a record with __valueclass_tag__, but conceptually +assert Structure(Int) == {__valueclass_tag__ = Phantom Int} +assert Structure(Str) == {__valueclass_tag__ = Phantom Str} +assert Structure((Nat, Nat)) == {__valueclass_tag__ = Phantom(Tuple(Nat, Nat))} +assert Structure(Nat -> Nat) == {__valueclass_tag__ = Phantom(Func(Nat, Nat))} +# Marker classes are also record types with __valueclass_tag__ +M = Inherit Marker +assert Structure(M) == {__valueclass_tag__ = Phantom M} +D = Inherit(C and M) +assert Structure(D) == {i = Int; __valueclass_tag__ = Phantom M} +E = Inherit(Int and M) +assert Structure(E) == {__valueclass_tag__ = Phantom(And(Int, M))} +F = Inherit(E not M) +assert Structure(F) == {__valueclass_tag__ = Phantom Int} +``` \ No newline at end of file diff --git a/doc/EN/syntax/type/advanced/variance.md b/doc/EN/syntax/type/advanced/variance.md new file mode 100644 index 00000000..6a7bec59 --- /dev/null +++ b/doc/EN/syntax/type/advanced/variance.md @@ -0,0 +1,143 @@ +# variation + +Erg can subtype polymorphic types, but there are some caveats. + +First, consider the inclusion relation of ordinary polymorphic types. In general, there is a container `K` and a type `A, B` to which it assigns, and when `A < B`, `K A < K B`. +For example, `Option Int < Option Object`. Therefore, methods defined in `Option Object` can also be used in `Option Int`. + +Consider the typical polymorphic type `Array!(T)`. +Note that this time it's not `Array!(T, N)` because we don't care about the number of elements. +Now, the `Array!(T)` type has methods called `.push!` and `.pop!`, which mean adding and removing elements, respectively. Here is the type: + +Array.push!: Self(T).(T) => NoneType +Array.pop!: Self(T).() => T + +As can be intuitively understood, + +* `Array!(Object).push!(s)` is OK when `s: Str` (just upcast `Str` to `Object`) +* When `o: Object`, `Array!(Str).push!(o)` is NG +* `Array!(Object).pop!().into(Str)` is NG +* `Array!(Str).pop!().into(Object)` is OK + +is. In terms of the type system, this is + +* (Self(Object).(Object) => NoneType) < (Self(Str).(Str) => NoneType) +* (Self(Str).() => Str) < (Self(Object).() => Object) + +means + +The former may seem strange. Even though `Str < Object`, the inclusion relation is reversed in the function that takes it as an argument. +In type theory, such a relation (the type relation of `.push!`) is called contravariant, and vice versa, the type relation of `.pop!` is called covariant. +In other words, function types are contravariant with respect to their argument types and covariant with respect to their return types. +It sounds complicated, but as we saw earlier, it's a reasonable rule if you apply it to an actual example. +If you still don't quite get it, consider the following. + +One of Erg's design principles is "large input types, small output types". This is precisely the case for function mutability. +Looking at the rules above, the larger the input type, the smaller the overall type. +This is because general-purpose functions are clearly rarer than special-purpose functions. +And the smaller the output type, the smaller the whole. + +As a result, the above policy is equivalent to saying "minimize the type of the function". + +## Immutability + +Erg has another modification. It is non-variance. +This is a modification that built-in types such as `SharedCell! T!` have. This means that for two types `T!, U!` where `T! != U!`, casts between `SharedCell! T!` and `SharedCell! means that +This is because `SharedCell! T!` is a shared reference. See [shared references](shared.md) for details. + +## Mutated generic type + +A universal type variable can specify its upper and lower bounds. + +``` 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 U} +``` + +Here is an example of code that uses a variable specification. + +``` 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 +``` + +## 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 +... +List T = Class {head = T; rest = Cons T} +List(T). + # List T can be pushed U if T > U + push|U|(self, x: U): List T = Self. new {head = x; rest = self} + # List T can be List U if T < U + upcast(self, U): List U = self +``` + +Even in this case, the Erg compiler does a good job of inferring the upper and lower types of `U`. +Note, however, that the Erg compiler doesn't understand the semantics of methods. The compiler simply infers and derives type relationships mechanically according to how variables and type variables are used. + +As written in the comments, the type `U` put in the `head` of `List T` is a subclass of `T` (`T: Int`, such as `Nat`). That is, it is inferred as `U <: T`. This constraint changes the argument type of `.push{U}` upcast `(List(T), U) -> List(T) to (List(T), T) -> List(T)`( e.g. disallow `List(Int).push{Object}`). Note, however, that the `U <: T` constraint does not alter the type containment of the function. The fact that `(List(Int), Object) -> List(Int) to (List(Int), Int) -> List(Int)` does not change, just in `.push` method It means that the cast cannot be performed. +Similarly, a cast from `List T` to `List U` is possible subject to the constraint `U :> T`, so the variation specification is inferred. This constraint changes the return type of `.upcast(U)` to upcast `List(T) -> List(T) to List(T) -> List(T)` (e.g. `List(Object) .upcast(Int)`) is prohibited. + +Now let's see what happens if we allow this upcast. +Let's invert the denaturation designation. + +``` 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`. +# TypeWarning: `U` in the `.upcast` cannot take anything other than `U == T`. Replace `U` with `T`. +``` + +Both the constraint `U <: T` and the modification specification `U :> T` are satisfied only when `U == T`. So this designation doesn't make much sense. +Only "upcasts such that `U == T`" = "upcasts that do not change where `U`" are actually allowed. + +## Appendix: Modification of user-defined types + +Mutations of user-defined types are immutable by default. However, you can also specify mutability with the `Inputs/Outputs` marker trait. +If you specify `Inputs(T)`, the type is contravariant with respect to `T`. +If you specify `Outputs(T)`, the type is covariant with respect to `T`. + +``` erg +K T = Class(...) +assert not K(Str) <= K(Object) +assert not K(Str) >= K(Object) + +InputStream T = Class ..., Impl := Inputs(T) +# A stream that accepts Objects can also be considered to accept Strs +assert InputStream(Str) > InputStream(Object) + +OutputStream T = Class ..., Impl := Outputs(T) +# A stream that outputs a Str can also be considered to output an Object +assert OutputStream(Str) < OutputStream(Object) +``` \ No newline at end of file diff --git a/doc/EN/syntax/type/advanced/widening.md b/doc/EN/syntax/type/advanced/widening.md new file mode 100644 index 00000000..7d0a9b47 --- /dev/null +++ b/doc/EN/syntax/type/advanced/widening.md @@ -0,0 +1,92 @@ +# Type Widening + +For example, define the polycorrelation coefficient as follows. + +``` 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 +assert ids(1, 2) == (1, 2) +assert ids(1, 2.0) == (1.0, 2.0) +ids(1, "a") #TypeError +``` + +Now, what about types that have different derived types? + +``` erg +i: Int or Str +j: Int or NoneType +ids(i, j) # ? +``` + +Before explaining this, we have to focus on the fact that Erg's type system doesn't actually look at (runtime) classes. + +``` 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 +``` + +I don't see the class because it may not be seen exactly, because in Erg the class of an object belongs to runtime information. +For example, the class of an `Int or Str` type object is either `Int` or `Str`, but you can only know which one it is by executing it. +Of course, the class of an object of type `Int` is defined as `Int`, but in this case as well, what is visible from the type system is the structural type `{__valueclass_tag__ = Int}` of `Int`. + +Now let's go back to another structured type example. In conclusion, the above code will result in a TypeError as the type does not match. +However, if you do type expansion with type annotations, compilation will pass. + +``` 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 +``` + +`A and B` have the following possibilities. + +* `A and B == A`: when `A <: B` or `A == B`. +* `A and B == B`: when `A :> B` or `A == B`. +* `A and B == {}`: when `!(A :> B)` and `!(A <: B)`. + +`A or B` has the following possibilities. + +* `A or B == A`: when `A :> B` or `A == B`. +* `A or B == B`: when `A <: B` or `A == B`. +* `A or B` is irreducible (independent types): if `!(A :> B)` and `!(A <: B)`. + +## Type widening in subroutine definitions + +Erg defaults to an error if return types do not match. + +``` erg +parse_to_int s: Str = + if not s.is_numeric(): + do parse_to_int::return error("not numeric") + ... # return Int object +# TypeError: mismatched types of return values +# 3 | do parse_to_int::return error("not numeric") +# └─ Error +# 4 | ... +# └ Int +``` + +In order to solve this, it is necessary to explicitly specify the return type as Or type. + +``` 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/EN/tools/build.md b/doc/EN/tools/build.md new file mode 100644 index 00000000..e8df33b7 --- /dev/null +++ b/doc/EN/tools/build.md @@ -0,0 +1,14 @@ +# build subcommand + +The build subcommand builds the package. +The steps performed in the default build are as follows: + +1. Inspect code in comments/documentation (md files under doc). +2. Compile the code needed for the package. +3. For application packages, generate batch files or shell scripts equivalent to commands. +4. Run the test. + +The deliverables after the build is completed are output to the following directory. + +* During debug build: build/debug +* For release build: build/release \ No newline at end of file diff --git a/doc/EN/tools/env.md b/doc/EN/tools/env.md new file mode 100644 index 00000000..19673686 --- /dev/null +++ b/doc/EN/tools/env.md @@ -0,0 +1,7 @@ +# env subcommand + +The env subcommand specifies the erg execution environment. +Create a new execution environment with `erg env new [env name]`. An interactive tool opens, and when you specify an erg version, that version of erg will be installed (if it already exists, it will be used), and you will be able to use it as a new environment. +You can switch the environment with `erg env switch [env name]`. +The created environment can be edited with `erg env edit` to pre-install packages and specify dependencies for other languages. +The biggest feature of this command is that `erg env export` can output the information that reproduces the environment as `[env name].env.er` file. This allows you to immediately start developing in the same environment as others. Furthermore, `erg env publish` can publish the environment like a package. \ No newline at end of file diff --git a/doc/EN/tools/fmt.md b/doc/EN/tools/fmt.md new file mode 100644 index 00000000..49f22b63 --- /dev/null +++ b/doc/EN/tools/fmt.md @@ -0,0 +1,6 @@ +# fmt + +Code formatting can be done with the fmt subcommand. +Commonly used flags are: + +* explicit-type: Automatically completes where the type specification is omitted. \ No newline at end of file diff --git a/doc/EN/tools/index.md b/doc/EN/tools/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/EN/tools/install.md b/doc/EN/tools/install.md new file mode 100644 index 00000000..0343a0ca --- /dev/null +++ b/doc/EN/tools/install.md @@ -0,0 +1,10 @@ +# install subcommand + +You can install packages registered on the registry site with install. +The basic usage is the same as package managers such as cargo. + +## Convenience functions + +* If there is a package name with a similar name and the number of downloads is more than 10 times that of that one, a suggestion will appear that you may have entered it incorrectly. This prevents typo squatting. +* If the package size is large (more than 50MB), display the size and suggest if you really want to install it. +* Suggest an alternative package if the package is duplicated. \ No newline at end of file diff --git a/doc/EN/tools/pack.md b/doc/EN/tools/pack.md new file mode 100644 index 00000000..ae02aa88 --- /dev/null +++ b/doc/EN/tools/pack.md @@ -0,0 +1,100 @@ +# package manager + +Erg comes standard with a package manager, which you can invoke with the `pack` subcommand. +The following are typical options. + +* `erg pack init`: Initialize the current directory as a package. A `package.er` file and a `src` directory are generated. Specifying `app` will result in an executable package, `lib` will result in a library package, and `hybrid` will result in both packages. If `--license` is specified, the license file will be placed automatically. +* `erg pack build`: Build a package. With `--release` the tests are run and optimized. Artifacts are placed in `build/debug` or `build/release`. +* `erg pack install`: Install a package. In the case of libraries, `src` is placed in `.erg/lib`, and applications are placed in `.erg/app` as shell scripts. Optimize with `--release`. +* `erg pack run`: Build the package and run the application (app package only). +* `erg pack clean`: Delete the contents of the build directory. +* `erg pack test`: Run a package test. See [test.md](./test.md) for details. +* `erg pack publish`: Publish/release the package. You will need a GitHub account and public key. + +This document explains how to manage your own packages. +See [install.md](./install.md) if you want to install or search for external packages. +Also see [package_system.md](../syntax/33_package_system.md) for the Erg package system. + +## Standard directory structure for the whole package (for application packages) + +```console +/package # package root directory + /build # Directory to store build results + /debug # Artifacts during debug build + /release # Artifacts of release build + /doc # Documents (in addition, by dividing into subdirectories such as `en`, `ja` etc., it is possible to correspond to each language) + /src # source code + /main.er # file that defines the main function + /tests # Directory to store (black box) test files + /package.er # file that defines package settings +``` + +##package.er + +`erg pack init` will generate `package.er` file like below. `package.er` describes the configuration of the package. +Below is an example of `package.er`. + +``` 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) +``` + +## Semantic versioning + +Erg packages are versioned based on [semantic versioning](https://semver.org/lang/en/). +Semantic versioning is roughly specified in the format `x.y.z` (x, y, z are integers greater than or equal to 0). +The meaning of each number is as follows. + +* x: major version (increase by 1 when updating breaking compatibility) +* y: minor version (increase by 1 when performing compatible updates (API addition, deprecation, etc.), bug fixes etc. are handled by patch version upgrade) +* z: patch version (increase by 1 when minor changes to fix bugs or maintain compatibility are made, serious fixes that break compatibility are handled by major version upgrades) + +However, changes in version `0.*.*` are always incompatible by default. If you want to upgrade while maintaining compatibility, specify `-compatible` after it (Erg's own rule). For example, if you want to add functions while maintaining compatibility with `0.2.1`, that is, if you want to upgrade to `0.3.0`, specify `0.3.0-compatible`. Also specify `0.2.2-compatible` if you have fixed bugs. +That version will then be considered compatible with the previous version. +This works even if you want to upgrade `0.*.*` to `1.0.0`. That is, `1.0.0-compatible` is compatible with the previous version `0.y.z`. + +Semantic versioning is very important when generating lockfiles. Lockfiles are files generated to keep dependencies compatible, so that newer releases of dependents depend on older packages unless explicitly updated. +Lockfiles are useful when multiple people are developing a package that has dependent packages. It also saves local storage by allowing packages that depend on them to reuse packages if they are compatible. + +Erg's package manager strictly enforces these rules and will reject package updates that violate them. +The Erg package manager works with version control systems (such as git) to detect code differences and verify the correctness of versioning when a package is published. +Specifically, the package manager looks at the types of the API. A change is considered compatible if the type is a subtype of an older version (note that this is not a full verification; type-compatible but semantically-incompatible significant changes are possible, it is the developer's job to determine this). + +Furthermore, since the entire package repository is registered in the registry, even developers cannot update the package without going through the package manager. +Also, packages can be deprecated but not removed. + +### Appendix: Semantic Versioning Issues and Countermeasures + +There are (at least) two known problems with semantic versioning. +First, semantic versioning can be too restrictive. +With semantic versioning, a single incompatible API change increments the major version of the entire package. +When this happens, things like "I wanted to try a new API, but I have to deal with another incompatible API change, so I won't upgrade". +Second, semantic versioning can promise too much. +As mentioned in the previous section, "compatible changes" to APIs are not theoretically provable. If you specify that you want a package with version `1.0.1`, you can instead use any package between `1.0.1` and `2.0.0` in terms of semantic versioning (`1.0.0` is It can't be used because a bug has been fixed), but there is a possibility that the build will not succeed due to unintended use of the API by the package developer. + +Erg addresses this issue by allowing different versions of a package to be used at the same time (by renaming). This makes it possible to continue using the ver1 API while partially introducing the ver2 API. +Additionally, although it's not a very desirable state, if only a certain minor version of the API can be used without bugs, it's possible to leave it alone and move on to the next version. + +## publish + +Packages can be published with the `publish` subcommand. Publishing requires a GitHub account. +Packages are registered with `(owner_name)/(package_name)` by default. If you meet certain conditions (number of downloads, frequency of maintenance, etc.), you can apply to register an alias that omits the owner name. +Note that package names are case-insensitive and delimiters such as `_` and `-` are not distinguished. \ No newline at end of file diff --git a/doc/EN/tools/repl.md b/doc/EN/tools/repl.md new file mode 100644 index 00000000..b22166c8 --- /dev/null +++ b/doc/EN/tools/repl.md @@ -0,0 +1,15 @@ +#REPL + +Running the `erg` command with no arguments invokes the REPL. It can also be invoked with the `repl` subcommand. +Additionally, you can specify the following flags: + +* typed: Show objects and their types. + +```console +$ erg repl --typed +Erg interpreter ... (tags/?:, ...) on ... +>>> 1 +1: {1} +>>> id x = x +id = : |T: Type| T -> T +``` \ No newline at end of file diff --git a/doc/EN/tools/test.md b/doc/EN/tools/test.md new file mode 100644 index 00000000..6e449ac8 --- /dev/null +++ b/doc/EN/tools/test.md @@ -0,0 +1,45 @@ +# test subcommand + +The erg command has a subcommand called test, which supports test implementation and execution. + +## Test decorator (@Test) + +Erg tests the `@Test` subroutine in the `tests` directory in the package or in the `*.test.er` file with the `erg test` command. +`tests` subroutines are in charge of black-box testing (not testing private functions), and `*.test.er` subroutines are in charge of white-box testing (testing private functions as well). + +``` erg +# tests/test1.er +{add; ...} = import "foo" + +@Test +test_1_plus_n(n: Nat) = + assert add(1, n) == n + 1 +``` + +The execution result is displayed as a summary and can be output in various file formats (.md, .csv, etc.). + +## Doc Test + +In Erg, `#` and `#[` are comment lines, but `##` and `#[[` are doc comments, and comments can be displayed as markdown from editors such as VSCode. +Furthermore, the source code in the doc comment is automatically tested with the erg test command if erg is specified. +Below is an example test. + +``` erg +VMs =... + ... + #[[ + 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 = + ... + ... +``` + +Mock objects (mock objects) used for testing are defined in the `tests/mock` module. \ No newline at end of file diff --git a/doc/JA/compiler/architecture.md b/doc/JA/compiler/architecture.md index 78d5e5a5..971362c4 100644 --- a/doc/JA/compiler/architecture.md +++ b/doc/JA/compiler/architecture.md @@ -1,42 +1,42 @@ -# Architecture of `ergc` +# ergc のアーキテクチャ -## 1. Scan an Erg script (.er) and generate a `TokenStream` (parser/lex.rs) +## 1. Erg スクリプト (.er) をスキャンし、`TokenStream` (parser/lex.rs) を生成します -* parser/lexer/Lexer generates `TokenStream` (this is an iterator of Token, TokenStream can be generated by lexer.collect()) - * `Lexer` is constructed from `Lexer::new` or `Lexer::from_str`, where `Lexer::new` reads the code from a file or command option. - * `Lexer` can generate tokens sequentially as an iterator; if you want to get a `TokenStream` all at once, use `Lexer::lex`. - * `Lexer` outputs `LexError`s as errors, but `LexError` does not have enough information to display itself. If you want to display the error, use the `LexerRunner` to convert the error. - * `LexerRunner` can also be used if you want to use `Lexer` as standalone; `Lexer` is just an iterator and does not implement the `Runnable` trait. - * `Runnable` is implemented by `LexerRunner`, `ParserRunner`, `Compiler`, and `VirtualMachine`. +* parser/lexer/Lexer は `TokenStream` を生成します (これは Token のイテレータです。TokenStream は lexer.collect() によって生成できます) + * `Lexer` は `Lexer::new` または `Lexer::from_str` から構築されます。`Lexer::new` はファイルまたはコマンド オプションからコードを読み取ります。 + ※ Lexer はイテレータとしてトークンを順次生成できるので、一度に TokenStream を取得したい場合は Lexer::lex を使う。 + * `Lexer` は `LexError` をエラーとして出力しますが、`LexError` 自体には表示するだけの情報がありません。エラーを表示したい場合は、`LexerRunner` を使用してエラーを変換します。 + * `Lexer` をスタンドアロンとして使用する場合は、`LexerRunner` も使用できます。`Lexer` は単なるイテレータであり、`Runnable` トレイトを実装していません。 + * Runnable は、 LexerRunner 、 ParserRunner 、 Compiler 、および VirtualMachine によって実装されます。 -## 2. Convert `TokenStream` -> `AST` (parser/parse.rs) +## 2. `TokenStream` を変換 -> `AST` (parser/parse.rs) -* `Parser`, like `Lexer`, has two constructors, `Parser::new` and `Parser::from_str`, and `Parser::parse` will give the `AST`. -* `AST` is the wrapper type of `Vec`. It is for "Abstract Syntax Tree". +* `Parser` は `Lexer` と同様に `Parser::new` と `Parser::from_str` の 2 つのコンストラクタを持ち、`Parser::parse` は `AST` を返します。 +※`AST`は`Vec`のラッパー型で、「抽象構文木」用です。 -### 2.5 Desugaring `AST` +### 2.5 `AST`の脱糖 -* expand nested vars (`Desugarer::desugar_nest_vars_pattern`) -* desugar multiple pattern definition syntax (`Desugarer::desugar_multiple_pattern_def`) +* ネストされた変数を展開 (`Desugarer::desugar_nest_vars_pattern`) +* desugar 複数パターン定義構文 (`Desugarer::desugar_multiple_pattern_def`) -## 3. Type checking & inference, Convert `AST` -> `HIR` (compiler/lower.rs) +## 3. 型チェックと推論、 `AST` -> `HIR` を変換 (compiler/lower.rs) -* `HIR` has every variable's type information. It is for "High-level Intermediate Representation". -* `HIR` only holds the type of the variable, but that's enough. In extreme cases, this is because Erg has only conversion (or operator) applications. If we know the type of the conversion, we have already know the type of the object of the argument. -* `ASTLowerer` can be constructed in the same way as `Parser` and `Lexer`. -* `ASTLowerer::lower` will output a tuple of `HIR` and `CompileWarnings` if no errors occur. -* `ASTLowerer` is owned by `Compiler`. Unlike conventional structures, `ASTLowerer` handles code contexts and is not a one-time disposable. -* If the result of type inference is incomplete (if there is an unknown type variable), an error will occur during name resolution. +* `HIR` は、すべての変数の型情報を持っています. これは、「高レベルの中間表現」用です. +* `HIR` は変数の型しか保持していないが、それで十分. 極端な場合、これは Erg が変換 (または演算子) のアプリケーションしか持たないためです. 変換の型がわかれば、変数の型もわかっています.引数のオブジェクト。 +※ ASTLowerer は Parser や Lexer と同じように構築できます。 +* `ASTLowerer::lower` は、エラーが発生しなければ、`HIR` と `CompileWarnings` のタプルを出力します。 +* `ASTLowerer` は `Compiler` によって所有されています. `ASTLowerer` は従来の構造体とは異なり、コード コンテキストを処理し、1 回限りの使い捨てではありません。 +※型推論の結果が不完全な場合(未知の型変数がある場合)、名前解決時にエラーが発生します。 -## 4. Check side-effects (compiler/effectcheck.rs) +## 4. 副作用のチェック (compiler/effectcheck.rs) -## 4. Check ownerships (compiler/memcheck.rs) +## 4. 所有権の確認 (compiler/memcheck.rs) -## 5. Generate Bytecode (`CodeObj`) from `HIR` (compiler/codegen.rs) +## 5. `HIR` からバイトコード (`CodeObj`) を生成 (compiler/codegen.rs) -* From the type information of the expression, name resolution of the quantified subroutines will be performed. +※式の型情報から、量化されたサブルーチンの名前解決を行います。 -## (6. (Future plans) Convert Bytecode -> LLVM IR) +## (6. (今後の予定) バイトコード変換 -> LLVM IR) -* Bytecode is stack-based, whereas LLVM IR is register-based. - There will be several more layers of intermediate processes for this conversion process. +* バイトコードはスタックベースですが、LLVM IR はレジスタベースです。 + この変換プロセスには、さらにいくつかの中間プロセスのレイヤーがあります。 \ No newline at end of file diff --git a/doc/JA/compiler/parsing.md b/doc/JA/compiler/parsing.md index aa6ed05c..47811ebb 100644 --- a/doc/JA/compiler/parsing.md +++ b/doc/JA/compiler/parsing.md @@ -6,7 +6,7 @@ Ergの文法において特異なのは、space-sensitive(空白による区別 これは、`()`の省略による表現力の低下を補うためである。同様の文法は同じく`()`を省略可能なNimでも見られる。 ```erg -f +1 == f(+1) +f + 1 == f(+1) f + 1 == `+`(f, 1) f (1,) == f((1,)) f(1,) == f(1) diff --git a/doc/JA/syntax/type/04_class.md b/doc/JA/syntax/type/04_class.md index b0f2ea05..cbd1464a 100644 --- a/doc/JA/syntax/type/04_class.md +++ b/doc/JA/syntax/type/04_class.md @@ -233,7 +233,7 @@ print! C.new({i = 1}).bar # ## データクラスとの違い -クラスには、レコードクラスに`Class`を通した通常のクラスと、レコードクラスを継承(`Inherit`)したデータクラスがあります。 +クラスには、レコードを要求型とする`Class`を通した通常のクラスと、レコードを継承(`Inherit`)したデータクラスがあります。 データクラスはレコードの機能を受け継いでおり、分解代入ができる、`==`や`hash`がデフォルトで実装されているなどの特徴があります。 逆に独自の同値関係やフォーマット表示を定義したい場合は通常のクラスを使用するとよいでしょう。 @@ -245,9 +245,9 @@ print! c # c == d # TypeError: `==` is not implemented for `C` D = Inherit {i = Int} -e = D.new {i = 1} -f = D.new {i = 2} -print! e # D{i = 1} +e = D::{i = 1} # e = D.new {i = 1}と同じ +f = D::{i = 2} +print! e # D(i = 1) assert e != f ``` @@ -288,4 +288,4 @@ assert T.foo == Foo

Previous | Next -

+

\ No newline at end of file diff --git a/doc/zh_CN/API/consts.md b/doc/zh_CN/API/consts.md new file mode 100644 index 00000000..b42e2f5b --- /dev/null +++ b/doc/zh_CN/API/consts.md @@ -0,0 +1,13 @@ +# 内置常量 + +## True + +## False + +## None + +## Ellipsis + +## NotImplemented + +## Inf diff --git a/doc/zh_CN/API/funcs.md b/doc/zh_CN/API/funcs.md new file mode 100644 index 00000000..3dee7041 --- /dev/null +++ b/doc/zh_CN/API/funcs.md @@ -0,0 +1,121 @@ +# 功能 + +## 基本功能 + +### 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_CN/API/index.md b/doc/zh_CN/API/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/API/modules/external/alstruct.md b/doc/zh_CN/API/modules/external/alstruct.md new file mode 100644 index 00000000..1635c852 --- /dev/null +++ b/doc/zh_CN/API/modules/external/alstruct.md @@ -0,0 +1,57 @@ +# 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_CN/API/modules/repl.md b/doc/zh_CN/API/modules/repl.md new file mode 100644 index 00000000..9b7c5a92 --- /dev/null +++ b/doc/zh_CN/API/modules/repl.md @@ -0,0 +1,24 @@ +# 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_CN/API/modules/status.md b/doc/zh_CN/API/modules/status.md new file mode 100644 index 00000000..83199149 --- /dev/null +++ b/doc/zh_CN/API/modules/status.md @@ -0,0 +1,6 @@ +# 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_CN/API/modules/unit.md b/doc/zh_CN/API/modules/unit.md new file mode 100644 index 00000000..214c4033 --- /dev/null +++ b/doc/zh_CN/API/modules/unit.md @@ -0,0 +1,73 @@ +# 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_CN/API/modules/unsound.md b/doc/zh_CN/API/modules/unsound.md new file mode 100644 index 00000000..90221567 --- /dev/null +++ b/doc/zh_CN/API/modules/unsound.md @@ -0,0 +1,24 @@ +# 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_CN/API/operators.md b/doc/zh_CN/API/operators.md new file mode 100644 index 00000000..5c767571 --- /dev/null +++ b/doc/zh_CN/API/operators.md @@ -0,0 +1,64 @@ +# 操作员 + +## 中缀运算符 + +### `_+_`|R; O; A <: Add(R, O)|(x: A, y: R) -> O + +执行加法。 + +### `_-_`|R; O; S <: Sub(R, O)|(x: S, y: R) -> O + +执行减法。 + +### `*`|R; O; M <: Mul R, O|(x: M, y: R) -> O + +执行乘法。 + +### `/`|R; O; D <: Div(R, O)|(x: D, y: R) -> O + +进行除法。 + +## 中缀字母运算符 + +### `and`(x: Bool, y: Bool) -> Bool + +执行 and 操作。 + +### `or`(x: Bool, y: Bool) -> Bool + +执行 and 操作。 + +## 前缀运算符 + +### `+_`|T <: Num|(x: T) -> T + +默认与 id 相同。 + +### `-_`|T <: Num|(x: T) -> T.Neg + +例如 Nat.`-`: Nat -> Neg 和返回值不同。 + +### `!`|T <: Immut|(x: T) -> `T!` + +从不可变对象创建可变对象。 +该运算符本身不是程序性的,可以在函数内部使用。 + +### `..`|T <: Ord|(x: T) -> Range T + +在 x 的末尾创建一个没有下限的 Range 对象。 +x..x 仅返回 x 作为迭代器。 + +### `..<`|T <: Ord|(x: T) -> Range T + +x.. Range T + +创建一个从 x 开始没有上限的 Range 对象。 + +### |T <: Ord|(x: T)`<..` -> Range T \ No newline at end of file diff --git a/doc/zh_CN/API/procs.md b/doc/zh_CN/API/procs.md new file mode 100644 index 00000000..dfbdcff9 --- /dev/null +++ b/doc/zh_CN/API/procs.md @@ -0,0 +1,39 @@ +# 过程 + +## 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_CN/API/special.md b/doc/zh_CN/API/special.md new file mode 100644 index 00000000..2a362bd0 --- /dev/null +++ b/doc/zh_CN/API/special.md @@ -0,0 +1,175 @@ +# 特殊形式 + +特殊形式是不能在 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_CN/API/types.md b/doc/zh_CN/API/types.md new file mode 100644 index 00000000..7d564d92 --- /dev/null +++ b/doc/zh_CN/API/types.md @@ -0,0 +1,262 @@ +# 内置 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_CN/API/types/classes/Array!(T).md b/doc/zh_CN/API/types/classes/Array!(T).md new file mode 100644 index 00000000..1d020183 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Array!(T).md @@ -0,0 +1,3 @@ +# Array! T + +表示可变长度数组的类型。在编译时长度未知时使用。 有一个语法糖叫做` [t]!`。在`Array! T = ArrayWithMutLength! T, !_`中被定义 \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Array(T).md b/doc/zh_CN/API/types/classes/Array(T).md new file mode 100644 index 00000000..c186d029 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Array(T).md @@ -0,0 +1,3 @@ +# Array T: Type + +由`Array T = ArrayWithLen T, _`定义。 有一种语法糖叫做`[T]`。 \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md b/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md new file mode 100644 index 00000000..3c1f20d1 --- /dev/null +++ b/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md @@ -0,0 +1,34 @@ +# 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}] +``` diff --git a/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md new file mode 100644 index 00000000..b219a60f --- /dev/null +++ b/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md @@ -0,0 +1,26 @@ +# 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 diff --git a/doc/zh_CN/API/types/classes/Class.md b/doc/zh_CN/API/types/classes/Class.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/API/types/classes/Complex.md b/doc/zh_CN/API/types/classes/Complex.md new file mode 100644 index 00000000..521b5b56 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Complex.md @@ -0,0 +1,14 @@ +# Complex + +表示复数的类型。 在 Erg 中表示数字的类型,例如 Float、Int 和 Nat,通常在顶部有这种类型 + +## supers + +Num and Norm + +## methods + +* abs +* conjugate +* imag +* real diff --git a/doc/zh_CN/API/types/classes/Dict!.md b/doc/zh_CN/API/types/classes/Dict!.md new file mode 100644 index 00000000..0c5fa58e --- /dev/null +++ b/doc/zh_CN/API/types/classes/Dict!.md @@ -0,0 +1,7 @@ +# Dict! K, V + +表示字典(哈希Map)的类型。 有一个语法糖叫做`{K: V}` + +## methods + +* invert!(self) -> Self! V, K diff --git a/doc/zh_CN/API/types/classes/Either.md b/doc/zh_CN/API/types/classes/Either.md new file mode 100644 index 00000000..900cc4d3 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Either.md @@ -0,0 +1,12 @@ +# Either L, R = L or R + +表示L或R的类型。 您可以将其视为Or类型的二元形式 + +## methods + +* orl +* orr +* andl +* andr +* mapl +* mapr diff --git a/doc/zh_CN/API/types/classes/Float.md b/doc/zh_CN/API/types/classes/Float.md new file mode 100644 index 00000000..02fe7aa8 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Float.md @@ -0,0 +1,21 @@ +# 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位数划分。没有自变量 diff --git a/doc/zh_CN/API/types/classes/Function(N).md b/doc/zh_CN/API/types/classes/Function(N).md new file mode 100644 index 00000000..0955f2ec --- /dev/null +++ b/doc/zh_CN/API/types/classes/Function(N).md @@ -0,0 +1,9 @@ +# 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_CN/API/types/classes/Inf.md b/doc/zh_CN/API/types/classes/Inf.md new file mode 100644 index 00000000..0e7e02b9 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Inf.md @@ -0,0 +1,7 @@ +# 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 +``` diff --git a/doc/zh_CN/API/types/classes/Interval.md b/doc/zh_CN/API/types/classes/Interval.md new file mode 100644 index 00000000..001d85d6 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Interval.md @@ -0,0 +1,18 @@ +# 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_CN/API/types/classes/Iterator.md b/doc/zh_CN/API/types/classes/Iterator.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/API/types/classes/Kind(N).md b/doc/zh_CN/API/types/classes/Kind(N).md new file mode 100644 index 00000000..4a72aec9 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Kind(N).md @@ -0,0 +1,5 @@ +# Kind N: Nat + +```erg +Kind N: Nat = (Type; N) -> Type +``` diff --git a/doc/zh_CN/API/types/classes/Matrix.md b/doc/zh_CN/API/types/classes/Matrix.md new file mode 100644 index 00000000..902029b2 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Matrix.md @@ -0,0 +1,7 @@ +# Matrix T: Num, Shape: [M, N] + +表示矩阵的类型。 它继承自 Tensor[M, N] + +## def + +Inherit Tensor T, [M, N] diff --git a/doc/zh_CN/API/types/classes/Module.md b/doc/zh_CN/API/types/classes/Module.md new file mode 100644 index 00000000..03b89e9f --- /dev/null +++ b/doc/zh_CN/API/types/classes/Module.md @@ -0,0 +1,3 @@ +# Module + +## methods diff --git a/doc/zh_CN/API/types/classes/Nat.md b/doc/zh_CN/API/types/classes/Nat.md new file mode 100644 index 00000000..afa30251 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Nat.md @@ -0,0 +1,18 @@ +# Nat + +表示自然数的类型。 用于数组索引和范围类型 + +## def + +```erg +Nat = 0.._ +``` + +## methods + +* times!(self, p: () => NoneType) -> NoneType + +```erg +100.times! () => + print! "hello!" +``` diff --git a/doc/zh_CN/API/types/classes/Neg.md b/doc/zh_CN/API/types/classes/Neg.md new file mode 100644 index 00000000..7005a062 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Neg.md @@ -0,0 +1,8 @@ +# Neg + +表示负整数的类型。 Pos和Neg和{0} == Int +它还具有一些值得注意的属性,例如不被零除和 Neg * Neg == Pos + +## def + +Inf<..-1 diff --git a/doc/zh_CN/API/types/classes/Never.md b/doc/zh_CN/API/types/classes/Never.md new file mode 100644 index 00000000..2f0cdd15 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Never.md @@ -0,0 +1,13 @@ +# 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_CN/API/types/classes/NonZero.md b/doc/zh_CN/API/types/classes/NonZero.md new file mode 100644 index 00000000..9a7d53b7 --- /dev/null +++ b/doc/zh_CN/API/types/classes/NonZero.md @@ -0,0 +1,30 @@ +# 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 diff --git a/doc/zh_CN/API/types/classes/Object.md b/doc/zh_CN/API/types/classes/Object.md new file mode 100644 index 00000000..963f58f1 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Object.md @@ -0,0 +1,7 @@ +# Object + +它是所有类型的超类型 + +## methods + +* __sizeof__: Nat diff --git a/doc/zh_CN/API/types/classes/Operator.md b/doc/zh_CN/API/types/classes/Operator.md new file mode 100644 index 00000000..0b26bbe9 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Operator.md @@ -0,0 +1,7 @@ +# Operator [...T], O + +是运算符的类型 + +## def + +Inherit Func [...T], O diff --git a/doc/zh_CN/API/types/classes/Option.md b/doc/zh_CN/API/types/classes/Option.md new file mode 100644 index 00000000..6eeb18b0 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Option.md @@ -0,0 +1,21 @@ +# 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 diff --git a/doc/zh_CN/API/types/classes/Pos.md b/doc/zh_CN/API/types/classes/Pos.md new file mode 100644 index 00000000..44831482 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Pos.md @@ -0,0 +1,8 @@ +# Pos + +Pos是一种表示正数(大于或等于1的整数)的类型。 +由于不包括0,因此具有消除被零除的可能性等优点。 + +## Def + +`Pos = 1.._` diff --git a/doc/zh_CN/API/types/classes/Ratio.md b/doc/zh_CN/API/types/classes/Ratio.md new file mode 100644 index 00000000..58b4211b --- /dev/null +++ b/doc/zh_CN/API/types/classes/Ratio.md @@ -0,0 +1,5 @@ +# 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类型之前,请进行真实的性能测试。 业余爱好者无条件偏爱较轻的模具。 diff --git a/doc/zh_CN/API/types/classes/Record.md b/doc/zh_CN/API/types/classes/Record.md new file mode 100644 index 00000000..4ff1126e --- /dev/null +++ b/doc/zh_CN/API/types/classes/Record.md @@ -0,0 +1,14 @@ +# 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} +``` diff --git a/doc/zh_CN/API/types/classes/Result.md b/doc/zh_CN/API/types/classes/Result.md new file mode 100644 index 00000000..de89e41c --- /dev/null +++ b/doc/zh_CN/API/types/classes/Result.md @@ -0,0 +1,7 @@ +# Result T, E + +```erg +Result T, E <: Error = Either T, E +``` + +和 `Option` 一样,它代表“一个可能失败的值”,但它可以有失败的上下文。 用法与`Either`几乎相同。 \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Str!.md b/doc/zh_CN/API/types/classes/Str!.md new file mode 100644 index 00000000..af0f1ee7 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Str!.md @@ -0,0 +1,3 @@ +# StrWithLen! N: Nat! = Inherit StrWithLen N + +表示可变长度字符串的类型 diff --git a/doc/zh_CN/API/types/classes/Str.md b/doc/zh_CN/API/types/classes/Str.md new file mode 100644 index 00000000..9b4f21b8 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Str.md @@ -0,0 +1,9 @@ +# Str + +(不变长度)表示字符串的类型。 简单的 `Str` 类型是删除了字符数的 `StrWithLen N` 类型(`Str = StrWithLen _`) + +## methods + +* isnumeric + +返回字符串是否为阿拉伯数字。 使用 `isunicodenumeric` 判断汉字数字和其他表示数字的字符(注意此行为与 Python 不同)。 \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/StrWithLen.md b/doc/zh_CN/API/types/classes/StrWithLen.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/API/types/classes/Subroutine.md b/doc/zh_CN/API/types/classes/Subroutine.md new file mode 100644 index 00000000..2350098c --- /dev/null +++ b/doc/zh_CN/API/types/classes/Subroutine.md @@ -0,0 +1,19 @@ +# Subroutine + +Func和Proc的基本类型。 + +## methods + +* return + +中断子程序并返回指定的值。 用于快速逃离嵌套 + +```erg +f x = + for 0..10, i -> + if i == 5: + do + f::return i + do + log i +``` diff --git a/doc/zh_CN/API/types/classes/Tensor.md b/doc/zh_CN/API/types/classes/Tensor.md new file mode 100644 index 00000000..131bb3c8 --- /dev/null +++ b/doc/zh_CN/API/types/classes/Tensor.md @@ -0,0 +1,24 @@ +# 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 diff --git a/doc/zh_CN/API/types/classes/TransCell(T).md b/doc/zh_CN/API/types/classes/TransCell(T).md new file mode 100644 index 00000000..078be645 --- /dev/null +++ b/doc/zh_CN/API/types/classes/TransCell(T).md @@ -0,0 +1,12 @@ +# 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 +``` diff --git a/doc/zh_CN/API/types/classes/Tuple.md b/doc/zh_CN/API/types/classes/Tuple.md new file mode 100644 index 00000000..b9b7667e --- /dev/null +++ b/doc/zh_CN/API/types/classes/Tuple.md @@ -0,0 +1,27 @@ +# 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 + ``` diff --git a/doc/zh_CN/API/types/classes/Type.md b/doc/zh_CN/API/types/classes/Type.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/API/types/classes/Vector.md b/doc/zh_CN/API/types/classes/Vector.md new file mode 100644 index 00000000..f9a159ed --- /dev/null +++ b/doc/zh_CN/API/types/classes/Vector.md @@ -0,0 +1,3 @@ +# Vector T: Num, N: Nat + +表示向量的类型。与同名的Rust和C++类型不同,这种类型只处理数字。 \ No newline at end of file diff --git a/doc/zh_CN/API/types/patches/BinOp.md b/doc/zh_CN/API/types/patches/BinOp.md new file mode 100644 index 00000000..b10cd654 --- /dev/null +++ b/doc/zh_CN/API/types/patches/BinOp.md @@ -0,0 +1,7 @@ +# BinOp L, R, O + +二元运算符的类型 + +## Patches + +Operator [L, R], O diff --git a/doc/zh_CN/API/types/patches/UnaryOp.md b/doc/zh_CN/API/types/patches/UnaryOp.md new file mode 100644 index 00000000..e06e07af --- /dev/null +++ b/doc/zh_CN/API/types/patches/UnaryOp.md @@ -0,0 +1,7 @@ +# UnaryOp T, O + +一元运算符的类型 + +## def + +Operator [T], O diff --git a/doc/zh_CN/API/types/traits/Add(R,O).md b/doc/zh_CN/API/types/traits/Add(R,O).md new file mode 100644 index 00000000..bf735100 --- /dev/null +++ b/doc/zh_CN/API/types/traits/Add(R,O).md @@ -0,0 +1,34 @@ +# 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 +``` diff --git a/doc/zh_CN/API/types/traits/Div(R,O).md b/doc/zh_CN/API/types/traits/Div(R,O).md new file mode 100644 index 00000000..b0b5adf0 --- /dev/null +++ b/doc/zh_CN/API/types/traits/Div(R,O).md @@ -0,0 +1,9 @@ +# Div R, O + +如果除以零没有错误,请使用“SafeDiv” + +```erg +Div R, O = Trait { + .`/` = Self.(R) -> O or Panic +} +``` diff --git a/doc/zh_CN/API/types/traits/Eq.md b/doc/zh_CN/API/types/traits/Eq.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/API/types/traits/Into.md b/doc/zh_CN/API/types/traits/Into.md new file mode 100644 index 00000000..53c8e9a8 --- /dev/null +++ b/doc/zh_CN/API/types/traits/Into.md @@ -0,0 +1,11 @@ +# Into T + +一种类型,表明它可以被类型转换为类型T。 +即使Self和T之间没有继承关系,也是在关系可以相互转换的时候定义的。 +与继承不同,没有隐式转换。您必须始终调用 `.into` 方法。 + +## methods + +* into(self, T) -> T + + 変換を行います。 diff --git a/doc/zh_CN/API/types/traits/Iterable.md b/doc/zh_CN/API/types/traits/Iterable.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/API/types/traits/Num.md b/doc/zh_CN/API/types/traits/Num.md new file mode 100644 index 00000000..5745c5ce --- /dev/null +++ b/doc/zh_CN/API/types/traits/Num.md @@ -0,0 +1,16 @@ +# 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_CN/API/types/traits/Ord.md b/doc/zh_CN/API/types/traits/Ord.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/API/types/traits/SafeDiv(R,O).md b/doc/zh_CN/API/types/traits/SafeDiv(R,O).md new file mode 100644 index 00000000..54c3a1b1 --- /dev/null +++ b/doc/zh_CN/API/types/traits/SafeDiv(R,O).md @@ -0,0 +1,8 @@ +# SafeDiv R, O + +```erg +SafeDiv R, O = Subsume Div, { + @Override + .`/` = Self.(R) -> O +} +``` diff --git a/doc/zh_CN/API/types/traits/Sample.md b/doc/zh_CN/API/types/traits/Sample.md new file mode 100644 index 00000000..93629a6a --- /dev/null +++ b/doc/zh_CN/API/types/traits/Sample.md @@ -0,0 +1,31 @@ +# 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} +``` diff --git a/doc/zh_CN/API/types/traits/Seq.md b/doc/zh_CN/API/types/traits/Seq.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/API/types/traits/Show.md b/doc/zh_CN/API/types/traits/Show.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/API/types/traits/Unpack.md b/doc/zh_CN/API/types/traits/Unpack.md new file mode 100644 index 00000000..259beb3a --- /dev/null +++ b/doc/zh_CN/API/types/traits/Unpack.md @@ -0,0 +1,13 @@ +# 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 +``` diff --git a/doc/zh_CN/compiler/TODO_hint.md b/doc/zh_CN/compiler/TODO_hint.md new file mode 100644 index 00000000..3844f83f --- /dev/null +++ b/doc/zh_CN/compiler/TODO_hint.md @@ -0,0 +1,4 @@ +# 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_CN/compiler/TODO_recov_suggest.md b/doc/zh_CN/compiler/TODO_recov_suggest.md new file mode 100644 index 00000000..cf919c9f --- /dev/null +++ b/doc/zh_CN/compiler/TODO_recov_suggest.md @@ -0,0 +1,11 @@ +# 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_CN/compiler/TODO_warn.md b/doc/zh_CN/compiler/TODO_warn.md new file mode 100644 index 00000000..bc503a9f --- /dev/null +++ b/doc/zh_CN/compiler/TODO_warn.md @@ -0,0 +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)? diff --git a/doc/zh_CN/compiler/abandoned.md b/doc/zh_CN/compiler/abandoned.md new file mode 100644 index 00000000..2aca11d1 --- /dev/null +++ b/doc/zh_CN/compiler/abandoned.md @@ -0,0 +1,10 @@ +# 废弃/拒绝的语言规范 + +## 重载(临时多态性) + +被放弃了,因为它可以用参数+子类型多态来代替,并且与Python的语义不兼容。 有关详细信息,请参阅 [overload](../syntax/type/overloading.md) 文章。 + +## 具有显式生命周期的所有权系统 + +原计划引入 Rust 之类的所有权系统,但由于与 Python 的语义不兼容以及需要引入生命周期注解等复杂规范而被放弃,并且所有不可变对象都是 RC。托管的可变对象现在只有一个所有权. +Dyne 没有 C# 和 Nim 那样的 GIL,策略是允许值对象和低级操作在安全范围内。 \ No newline at end of file diff --git a/doc/zh_CN/compiler/architecture.md b/doc/zh_CN/compiler/architecture.md new file mode 100644 index 00000000..1088dbce --- /dev/null +++ b/doc/zh_CN/compiler/architecture.md @@ -0,0 +1,42 @@ +# `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` 和 `VirtualMachine` 实现。 + +## 2. 转换 `TokenStream` -> `AST` (parser/parse.rs) + +* `Parser` 和 `Lexer` 一样,有两个构造函数,`Parser::new` 和 `Parser::from_str`,而 `Parser::parse` 会给出 `AST`。 +* `AST` 是 `Vec` 的包装器类型。 + +### 2.5 脱糖 `AST` + +* 扩展嵌套变量 (`Desugarer::desugar_nest_vars_pattern`) +* desugar 多模式定义语法(`Desugarer::desugar_multiple_pattern_def`) + +## 3. 类型检查和推断,转换 `AST` -> `HIR` (compiler/lower.rs) + +* `HIR` 有每个变量的类型信息。它是用于“高级中间表示”的。 +* `HIR` 只保存变量的类型,但这已经足够了。在极端情况下,这是因为 Erg 只有转换(或运算符)应用程序的参数对象。 +* `ASTLower` 可以用与`Parser` 和`Lexer` 相同的方式构造。 +* 如果没有错误发生,`ASTLowerer::lower` 将输出 `HIR` 和 `CompileWarnings` 的元组。 +* `ASTLowerer`归`Compiler`所有。与传统结构不同,`ASTLowerer`处理代码上下文并且不是一次性的。 +* 如果类型推断的结果不完整(如果存在未知类型变量),名称解析时会出错。 + +## 4. 检查副作用(compiler/effectcheck.rs) + +## 4. 检查所有权(compiler/memcheck.rs) + +## 5. 从`HIR`(compiler/codegen.rs)生成字节码(`CodeObj`) + +* 根据表达式的类型信息,将执行量化子程序的名称解析。 + +##(6.(未来计划)转换字节码 -> LLVM IR) + +* 字节码是基于堆栈的,而 LLVM IR 是基于寄存器的。 + 这个转换过程会多出几层中间过程。 \ No newline at end of file diff --git a/doc/zh_CN/compiler/errors.md b/doc/zh_CN/compiler/errors.md new file mode 100644 index 00000000..6e241f3c --- /dev/null +++ b/doc/zh_CN/compiler/errors.md @@ -0,0 +1,131 @@ +# 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 diff --git a/doc/zh_CN/compiler/hir.md b/doc/zh_CN/compiler/hir.md new file mode 100644 index 00000000..837b51a4 --- /dev/null +++ b/doc/zh_CN/compiler/hir.md @@ -0,0 +1,148 @@ +# 高レベル中間表現(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_CN/compiler/index.md b/doc/zh_CN/compiler/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/compiler/inference.md b/doc/zh_CN/compiler/inference.md new file mode 100644 index 00000000..f5e8571e --- /dev/null +++ b/doc/zh_CN/compiler/inference.md @@ -0,0 +1,436 @@ +# 类型推理算法 + +> :本节正在编辑中,可能包含某些错误。 + +以下是使用的表示方法。 + + +```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) +``` diff --git a/doc/zh_CN/compiler/overview.md b/doc/zh_CN/compiler/overview.md new file mode 100644 index 00000000..2da9366e --- /dev/null +++ b/doc/zh_CN/compiler/overview.md @@ -0,0 +1,36 @@ +# 概览 + +介绍每个图层的工作方式以及特别重要的函数和方法。 + +## 1. 词法分析 + +* 执行词法分析。(作为迭代器实现)是词法分析的主要逻辑。将输出作为分析的结果。 + +## 2. 语法分析 + +* 执行解析。尤其重要的是。作为分析的结果,将输出,它是的集合。 + +## 3. 脱糖 + +* 进行脱糖。将输出。 + +## 4. 类型检查/类型推理 + +* 用于输入数据。类型检查主要通过进行。特别重要的是(确定子类型关系),(对类型变量进行单一化/半单一化)和(定义嵌入式 API)。将输出作为分析的结果。 + +## 5. 副作用检查 + +* 。 + +## 6. 所有权检查 + +* 。 + +## 7. 字节码生成 + +* 将转换为保留字节码和执行设置。尤其重要的是。 + +--- + +* 所有这些操作都由作为外立面进行总结。 +* 生成的字节码当然由 Python 执行,但它被称为。 diff --git a/doc/zh_CN/compiler/parsing.md b/doc/zh_CN/compiler/parsing.md new file mode 100644 index 00000000..54e8a20e --- /dev/null +++ b/doc/zh_CN/compiler/parsing.md @@ -0,0 +1,31 @@ +# 解析 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 个是左边值。 diff --git a/doc/zh_CN/compiler/refinement_subtyping.md b/doc/zh_CN/compiler/refinement_subtyping.md new file mode 100644 index 00000000..c761154d --- /dev/null +++ b/doc/zh_CN/compiler/refinement_subtyping.md @@ -0,0 +1,155 @@ +# 筛子型 + +筛型是指以下类型。 + + +```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 +``` diff --git a/doc/zh_CN/compiler/trait_method_resolving.md b/doc/zh_CN/compiler/trait_method_resolving.md new file mode 100644 index 00000000..1dcd995e --- /dev/null +++ b/doc/zh_CN/compiler/trait_method_resolving.md @@ -0,0 +1,86 @@ +# 解决修补程序方法 + +是大于 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 +``` diff --git a/doc/zh_CN/compiler/transpile.md b/doc/zh_CN/compiler/transpile.md new file mode 100644 index 00000000..49305a56 --- /dev/null +++ b/doc/zh_CN/compiler/transpile.md @@ -0,0 +1,91 @@ +# 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 +``` diff --git a/doc/zh_CN/compiler/type_var_normalization.md b/doc/zh_CN/compiler/type_var_normalization.md new file mode 100644 index 00000000..1e79cd43 --- /dev/null +++ b/doc/zh_CN/compiler/type_var_normalization.md @@ -0,0 +1,35 @@ +# 归一化 + +* 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` diff --git a/doc/zh_CN/dev_guide/branches.md b/doc/zh_CN/dev_guide/branches.md new file mode 100644 index 00000000..0e426275 --- /dev/null +++ b/doc/zh_CN/dev_guide/branches.md @@ -0,0 +1,31 @@ +# 分支机构命名和运营策略 + +* 基本上,开发是在一个分支中进行的(单回购开发)。只有在必须断开分支才能工作的情况下,才创建分支或分支。 + +## main + +* 主要开发分支 +* 必须满足以下条件 + +* 编译成功 + +## beta(目前不创建) + +* 最新的 Beta 版本 +* 必须满足以下条件 + +* 编译成功 +* 所有测试都会成功 + +## feature-* + +* 开发特定功能的分支 +* 切开 main + +* 没有条件 + +## issue-* + +* 解决特定 issue 的分支 + +* 没有条件 diff --git a/doc/zh_CN/dev_guide/build_features.md b/doc/zh_CN/dev_guide/build_features.md new file mode 100644 index 00000000..c517ec24 --- /dev/null +++ b/doc/zh_CN/dev_guide/build_features.md @@ -0,0 +1,17 @@ +# `erg` build features + +## debug + +进入调试模式。由此,在 Erg 内部的举动被逐次记录表示出来。独立于 Rust 的标志。 + +## japanese + +系统语言为日语。Erg 内的选项、帮助(如 help、copyright、license)和错误显示都保证为日语。 + +## simplified_chinese + +系统语言为简体中文。 + +## traditional_chinese + +系统语言为繁体中文。 diff --git a/doc/zh_CN/dev_guide/directories.md b/doc/zh_CN/dev_guide/directories.md new file mode 100644 index 00000000..9a5dca1a --- /dev/null +++ b/doc/zh_CN/dev_guide/directories.md @@ -0,0 +1,25 @@ +# Erg 存储库目录结构 + + +```console + └─┬ assets: 画像など + ├─ CODE_OF_CONDUCT: 行動規範 + ├─┬ compiler + │ ├─ erg_common: 共通のユーティリティ + │ ├─ erg_compiler + │ └─ erg_parser: パーサー + ├─┬ doc + │ ├─┬ EN + │ │ ├─ 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_CN/dev_guide/doc_guideline.md b/doc/zh_CN/dev_guide/doc_guideline.md new file mode 100644 index 00000000..21108c16 --- /dev/null +++ b/doc/zh_CN/dev_guide/doc_guideline.md @@ -0,0 +1,13 @@ +# 格式 + +所有不符合以下规则的文档都是修正的对象。 + +* 代码注释或内部文档以这种方式编写。 +* 向外部(普通用户)展示的文档要用简单易懂的语言书写。 +* 文档中首次出现的术语必须同时记录定义、含义或链接。 +* ()作为补充,仅用于理解正文所必需的句子,而非理解正文所必需的句子则使用脚注。 +* 如果文档内容过期,则根据进行更新。 + +--- + +1脚注的写法参照此。 diff --git a/doc/zh_CN/dev_guide/env.md b/doc/zh_CN/dev_guide/env.md new file mode 100644 index 00000000..3e1cd98c --- /dev/null +++ b/doc/zh_CN/dev_guide/env.md @@ -0,0 +1,19 @@ +# 开发环境 + +## 需要安装的内容 + +* 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 diff --git a/doc/zh_CN/dev_guide/faq_syntax.md b/doc/zh_CN/dev_guide/faq_syntax.md new file mode 100644 index 00000000..f33d5696 --- /dev/null +++ b/doc/zh_CN/dev_guide/faq_syntax.md @@ -0,0 +1,108 @@ +# Erg design's "Why" and Answers + +## 为什么有产权体系,GC 也让它共存? + +因为 Erg 推出所有权系统的动机并不是为了 Rust 那样的“不依赖 GC 的内存管理”。最初,由于 Erg 是一种语言,目前已被 Python 字节码删除,因此最终仍使用 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はFile型 + f.read_all!() + +# tryプロシージャで例外のような捕捉処理も可能 +try!: + do! + s = read_file!()? + print! s + e => + # エラー発生時に実行するブロック + print! e + exit 1 +``` + +在引入 Python 函数时,缺省情况下,所有函数都被视为包含异常,返回类型为。如果你知道不调度异常,请在中指明。 + +此外,Erg 没有引入异常机制的另一个原因是它计划引入并行编程的功能。这是因为异常机制与并行执行不兼容(例如,如果并行执行导致多个异常,则很难处理)。 + +## Erg 似乎消除了 Python 被认为是坏做法的功能,但为什么没有取消继承? + +Python 的库中有一些类设计为继承,如果完全取消继承,这些操作就会出现问题。然而,由于 Erg 的类默认为 final,并且原则上禁止多重和多层继承,因此继承的使用相对安全。 + +## 为什么多相关数的子类型推理默认指向记名特雷特? + +默认情况下,指向结构托盘会使类型指定变得复杂,并且可能会混合程序员的非预期行为。 + + +```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_CN/dev_guide/i18n_messages.md b/doc/zh_CN/dev_guide/i18n_messages.md new file mode 100644 index 00000000..3b1afc5f --- /dev/null +++ b/doc/zh_CN/dev_guide/i18n_messages.md @@ -0,0 +1,55 @@ +# Multilingualization of Messages + +Erg 正在推动消息(开始、选项、文档、提示、警告、错误消息等)的多语言化。如果你不熟悉 Rust 或 Erg,也可以参与此项目。请务必配合。 + +以下是多语种方法的说明。 + +## 查找 + +在 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"), +), +``` + +另外,英语是默认设置,一定要排在最后。部分是 Rust 的格式化功能,允许你将变量的内容()嵌入到字符串中。 + +## Build + +现在,我们使用选项构建它。 + +screenshot_i18n_messages + +你做到了! + +## FAQ + +Q:像这样的指定是什么意思?A:{RED} 及更高版本将显示为红色。重新启动交互渲染。 + +Q:如果想添加自己的语言,该如何替换部分?答:目前支持以下语言。 + +* english(默认设置) +* 日语。 +* 简体中文 +* 繁体中文 + +如果你想添加其他语言,请提出请求。 diff --git a/doc/zh_CN/dev_guide/index.md b/doc/zh_CN/dev_guide/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/dev_guide/rust_code_guideline.md b/doc/zh_CN/dev_guide/rust_code_guideline.md new file mode 100644 index 00000000..0545e5f5 --- /dev/null +++ b/doc/zh_CN/dev_guide/rust_code_guideline.md @@ -0,0 +1,23 @@ +# Rust 代码准则 + +## 本地规则 + +* 用于调试的输出使用(释放时所需的输出处理也使用等)。 +* 未使用或内部(专用和仅用于特定功能)的变量方法以一个开头。如果想避免与保留字的冲突,则在后面加上一个。 + +## 鼓励代码 + +* 定义并使用特定于域的 Enum,而不是数字枚举和 bool。 +* 存取修饰符为必要的最小限度。即使公开时也优先使用和。 +* for 表达式中的 iterable 对象显式转换为迭代器(,而不是)。 +* 延迟评估。例如,当不是文字时,使用而不是。 + +## 不鼓励的代码 + +* 经常使用 return type overloading。具体来说,经常使用不明确的的代码。这是因为型推论结果有时违反直觉。在这种情况下,建议使用代替。 +* 经常使用。这实质上引起了与继承相同的问题。 + +## 根据上下文判断不同的代码 + +* 定义未使用的 helper 方法。 +* 经常使用,。在某些情况下,有些人别无选择,只能这样做。 diff --git a/doc/zh_CN/dev_guide/terms.md b/doc/zh_CN/dev_guide/terms.md new file mode 100644 index 00000000..fc7a4f18 --- /dev/null +++ b/doc/zh_CN/dev_guide/terms.md @@ -0,0 +1,831 @@ +# 术语词典 + +## 符号 + +### ! + +过程或附加在标识符末尾的标记,以指示其为可变类型。或者变量运算符。 + +### ../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 的属性。特别是由特雷特自动实现的属性。 + +### 应用 + +将参数传递给函数对象以获得评估结果。 + +### 装饰器../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 + +## 和行 + +### 通配符 diff --git a/doc/zh_CN/dev_guide/unify_terms.md b/doc/zh_CN/dev_guide/unify_terms.md new file mode 100644 index 00000000..4cb5b2bc --- /dev/null +++ b/doc/zh_CN/dev_guide/unify_terms.md @@ -0,0 +1,80 @@ +# 术语统一 + +## 可见性、可见性 + +使用“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 的无名函数不是匿名的,所以不使用匿名函数。 diff --git a/doc/zh_CN/faq_general.md b/doc/zh_CN/faq_general.md new file mode 100644 index 00000000..74358eed --- /dev/null +++ b/doc/zh_CN/faq_general.md @@ -0,0 +1,27 @@ +# 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 继承了面向表达式和特雷特,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 说,语言的名称越短越好),并且具有相应的高格格不入性,因此决定了这一点。 diff --git a/doc/zh_CN/faq_technical.md b/doc/zh_CN/faq_technical.md new file mode 100644 index 00000000..d868873a --- /dev/null +++ b/doc/zh_CN/faq_technical.md @@ -0,0 +1,25 @@ +# 技术常见问题解答 + +本节回答了使用 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 的地方输入浮点的规范)可能是类型错误。 diff --git a/doc/zh_CN/improved_points.md b/doc/zh_CN/improved_points.md new file mode 100644 index 00000000..72761c78 --- /dev/null +++ b/doc/zh_CN/improved_points.md @@ -0,0 +1,46 @@ +# 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 +``` + +## 特雷特 + +就像 Java 的界面一样,它可以进行基于合约的编程。 + +Python 也有一个抽象基类,但这种结构与静态定型结合在一起可以发挥最大的作用。 + +## 静态解析依赖关系 + +防止长时间运行后模块不足而导致错误等导致的游戏体验。 + +## 内置包管理器 + +使用标准化的目录结构和构建文件进行可重复的构建。当然,还会生成锁定文件并对其进行版本控制。我们不需要对 anaconda,pyenv,poetry,每个项目进行取舍和组合。 diff --git a/doc/zh_CN/index.md b/doc/zh_CN/index.md new file mode 100644 index 00000000..db3516f8 --- /dev/null +++ b/doc/zh_CN/index.md @@ -0,0 +1,25 @@ +# Index + +## [API/](./API/index.md) + + Ergの組み込みまたは標準ライブラリで提供されるサブルーチン、型、定数等の仕様が記述されている。 + +## [compiler/](./compiler/index.md) + + Ergコンパイラ(Centimetre)の設計について解説されている。 + +## [dev_guide/](./dev_guide/index.md) + + プロジェクトの開発方針、コントリビューションの仕方などが解説されている。 + +## [python/](./python/index.md) + + Ergを開発する上で必要となるPythonの知識が解説されている。 + +## [syntax/](./syntax/00_basic.md) + + Ergの文法が解説されている。 + +## [tools/](./tools/index.md) + + Ergの周辺ツール、コマンドオプションの使い方などが解説されている。 diff --git a/doc/zh_CN/migration_from_py.md b/doc/zh_CN/migration_from_py.md new file mode 100644 index 00000000..0ee9f06c --- /dev/null +++ b/doc/zh_CN/migration_from_py.md @@ -0,0 +1,28 @@ +# 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() +``` diff --git a/doc/zh_CN/python/bytecode_instructions.md b/doc/zh_CN/python/bytecode_instructions.md new file mode 100644 index 00000000..32e580eb --- /dev/null +++ b/doc/zh_CN/python/bytecode_instructions.md @@ -0,0 +1,106 @@ +# 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 对应函数内部闭包函数捕获的变量。复制后,原始变量保持不变。 diff --git a/doc/zh_CN/python/bytecode_specification.md b/doc/zh_CN/python/bytecode_specification.md new file mode 100644 index 00000000..5cd9034f --- /dev/null +++ b/doc/zh_CN/python/bytecode_specification.md @@ -0,0 +1,70 @@ +# 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 diff --git a/doc/zh_CN/python/class_system.md b/doc/zh_CN/python/class_system.md new file mode 100644 index 00000000..daa825ca --- /dev/null +++ b/doc/zh_CN/python/class_system.md @@ -0,0 +1,95 @@ +# 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 +``` diff --git a/doc/zh_CN/python/index.md b/doc/zh_CN/python/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md new file mode 100644 index 00000000..319b137e --- /dev/null +++ b/doc/zh_CN/syntax/00_basic.md @@ -0,0 +1,121 @@ +# 基本信息 + +> :此文档尚未完成。未进行校样(文体、正确链接等)。此外,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 +

diff --git a/doc/zh_CN/syntax/01_literal.md b/doc/zh_CN/syntax/01_literal.md new file mode 100644 index 00000000..2e5bfc1f --- /dev/null +++ b/doc/zh_CN/syntax/01_literal.md @@ -0,0 +1,165 @@ +# 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 +

diff --git a/doc/zh_CN/syntax/02_name.md b/doc/zh_CN/syntax/02_name.md new file mode 100644 index 00000000..8bc44707 --- /dev/null +++ b/doc/zh_CN/syntax/02_name.md @@ -0,0 +1,169 @@ +# 变量 + +变量是代数的一种。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 +

diff --git a/doc/zh_CN/syntax/03_declaration.md b/doc/zh_CN/syntax/03_declaration.md new file mode 100644 index 00000000..2cdffa57 --- /dev/null +++ b/doc/zh_CN/syntax/03_declaration.md @@ -0,0 +1,48 @@ +# 声明 + +声明是指定要使用的变量类型的语法。可以在代码中的任何地方声明,但不能只声明变量。必须始终初始化。赋值后声明可以检查类型是否与赋值对象匹配。 + + +```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 +

diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md new file mode 100644 index 00000000..ed9d9e43 --- /dev/null +++ b/doc/zh_CN/syntax/04_function.md @@ -0,0 +1,306 @@ +# 函数 + +函数是一个块,它接受参数并对其进行处理,然后将其作为返回值返回。定义如下。 + + +```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 +

diff --git a/doc/zh_CN/syntax/05_builtin_funcs.md b/doc/zh_CN/syntax/05_builtin_funcs.md new file mode 100644 index 00000000..a843467c --- /dev/null +++ b/doc/zh_CN/syntax/05_builtin_funcs.md @@ -0,0 +1,52 @@ +# 内置函数 + +## 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 +

diff --git a/doc/zh_CN/syntax/06_operator.md b/doc/zh_CN/syntax/06_operator.md new file mode 100644 index 00000000..20b655e6 --- /dev/null +++ b/doc/zh_CN/syntax/06_operator.md @@ -0,0 +1,30 @@ +# 运算符 + +运算符(操作符)是表示运算的符号。运算符(操作数)位于运算符的右侧(左),在 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 +

diff --git a/doc/zh_CN/syntax/07_side_effect.md b/doc/zh_CN/syntax/07_side_effect.md new file mode 100644 index 00000000..85944adf --- /dev/null +++ b/doc/zh_CN/syntax/07_side_effect.md @@ -0,0 +1,123 @@ +# 副作用和过程 + +到目前为止,我一直没有解释中的含义,现在我终于明白了它的含义。这个!直截了当地表示此对象是具有“副作用”的“过程”。过程对函数产生了一种称为“副作用”的效果。 + + +```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 +

diff --git a/doc/zh_CN/syntax/08_procedure.md b/doc/zh_CN/syntax/08_procedure.md new file mode 100644 index 00000000..28a74bcd --- /dev/null +++ b/doc/zh_CN/syntax/08_procedure.md @@ -0,0 +1,12 @@ +# 过程 + +处理可变对象时需要过程,但如果变量对象是参数,则不一定是过程。 + + +```erg +peek_str s: Str! = log s +``` + +

+ Previous | Next +

diff --git a/doc/zh_CN/syntax/09_builtin_procs.md b/doc/zh_CN/syntax/09_builtin_procs.md new file mode 100644 index 00000000..6b731630 --- /dev/null +++ b/doc/zh_CN/syntax/09_builtin_procs.md @@ -0,0 +1,13 @@ +# 内置过程 + +## id! + +返回对象的唯一标识号。在纯 Erg 语义中,结构相同的对象之间没有差异,但实际上,对象在内存中的位置是不同的。返回表示此位置的数字。 + + +```erg +``` + +

+ Previous | Next +

diff --git a/doc/zh_CN/syntax/10_array.md b/doc/zh_CN/syntax/10_array.md new file mode 100644 index 00000000..067f9564 --- /dev/null +++ b/doc/zh_CN/syntax/10_array.md @@ -0,0 +1,56 @@ +# 排列 + +数组是最基本的。集合是可以在内部包含多个对象的对象。 + + +```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 +

diff --git a/doc/zh_CN/syntax/11_tuple.md b/doc/zh_CN/syntax/11_tuple.md new file mode 100644 index 00000000..ec52e918 --- /dev/null +++ b/doc/zh_CN/syntax/11_tuple.md @@ -0,0 +1,125 @@ +# 元 + +元组类似于数组,但可以包含不同类型的对象。这样的收藏称为非等质收藏。与此相对,等质集合包括数组和集合。 + + +```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 +

diff --git a/doc/zh_CN/syntax/12_dict.md b/doc/zh_CN/syntax/12_dict.md new file mode 100644 index 00000000..04d4d305 --- /dev/null +++ b/doc/zh_CN/syntax/12_dict.md @@ -0,0 +1,71 @@ +# 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 +

diff --git a/doc/zh_CN/syntax/13_record.md b/doc/zh_CN/syntax/13_record.md new file mode 100644 index 00000000..fbbebec9 --- /dev/null +++ b/doc/zh_CN/syntax/13_record.md @@ -0,0 +1,198 @@ +# 记录 + +记录是一个集合,它具有通过键访问的 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 +

diff --git a/doc/zh_CN/syntax/14_set.md b/doc/zh_CN/syntax/14_set.md new file mode 100644 index 00000000..648b9d0a --- /dev/null +++ b/doc/zh_CN/syntax/14_set.md @@ -0,0 +1,50 @@ +# 集 + +集代表一个集合,在数据结构上是重复的、没有顺序的数组。 + + +```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 +

diff --git a/doc/zh_CN/syntax/15_type.md b/doc/zh_CN/syntax/15_type.md new file mode 100644 index 00000000..f793b020 --- /dev/null +++ b/doc/zh_CN/syntax/15_type.md @@ -0,0 +1,7 @@ +# 类型 + +类型在 Erg 中是一个非常重要的功能,因此我们提供了。请看那边。 + +

+ Previous | Next +

diff --git a/doc/zh_CN/syntax/16_iterator.md b/doc/zh_CN/syntax/16_iterator.md new file mode 100644 index 00000000..4bda6cf0 --- /dev/null +++ b/doc/zh_CN/syntax/16_iterator.md @@ -0,0 +1,91 @@ +# 迭 + +迭代器是用于检索容器元素的对象。 + + +```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 +

diff --git a/doc/zh_CN/syntax/17_mutability.md b/doc/zh_CN/syntax/17_mutability.md new file mode 100644 index 00000000..4ac7a2cc --- /dev/null +++ b/doc/zh_CN/syntax/17_mutability.md @@ -0,0 +1,92 @@ +# 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 +

diff --git a/doc/zh_CN/syntax/18_ownership.md b/doc/zh_CN/syntax/18_ownership.md new file mode 100644 index 00000000..3deed98a --- /dev/null +++ b/doc/zh_CN/syntax/18_ownership.md @@ -0,0 +1,103 @@ +# 所有权制度 + +由于 Erg 是以 Python 为主机语言的语言,因此管理内存的方式依赖于 Python 的处理系统。然而,从语义上讲,Erg 的内存管理与 Python 的内存管理不同。显著的区别体现在所有权制度和禁止循环引用。 + +## 所有权 + +Erg 有一个所有权系统受到拉斯特的影响。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 +

diff --git a/doc/zh_CN/syntax/19_visibility.md b/doc/zh_CN/syntax/19_visibility.md new file mode 100644 index 00000000..6ebbb9bd --- /dev/null +++ b/doc/zh_CN/syntax/19_visibility.md @@ -0,0 +1,199 @@ +# 可见性(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 +

diff --git a/doc/zh_CN/syntax/20_naming_rule.md b/doc/zh_CN/syntax/20_naming_rule.md new file mode 100644 index 00000000..59640a40 --- /dev/null +++ b/doc/zh_CN/syntax/20_naming_rule.md @@ -0,0 +1,52 @@ +# 命名规则 + +如果要将变量用作常量表达式,则必须以大写字母开头。两个以上的字符可以是小写的。 + + +```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 +

diff --git a/doc/zh_CN/syntax/21_lambda.md b/doc/zh_CN/syntax/21_lambda.md new file mode 100644 index 00000000..81b02c5a --- /dev/null +++ b/doc/zh_CN/syntax/21_lambda.md @@ -0,0 +1,102 @@ +# 匿名函数(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 +

diff --git a/doc/zh_CN/syntax/22_subroutine.md b/doc/zh_CN/syntax/22_subroutine.md new file mode 100644 index 00000000..fd6d79ae --- /dev/null +++ b/doc/zh_CN/syntax/22_subroutine.md @@ -0,0 +1,65 @@ +# 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 +

diff --git a/doc/zh_CN/syntax/23_closure.md b/doc/zh_CN/syntax/23_closure.md new file mode 100644 index 00000000..0a89b21c --- /dev/null +++ b/doc/zh_CN/syntax/23_closure.md @@ -0,0 +1,99 @@ +# 封闭 + +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 +

diff --git a/doc/zh_CN/syntax/24_module.md b/doc/zh_CN/syntax/24_module.md new file mode 100644 index 00000000..2582cd36 --- /dev/null +++ b/doc/zh_CN/syntax/24_module.md @@ -0,0 +1,47 @@ +# 模块 + +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 +

diff --git a/doc/zh_CN/syntax/25_object_system.md b/doc/zh_CN/syntax/25_object_system.md new file mode 100644 index 00000000..d3b37693 --- /dev/null +++ b/doc/zh_CN/syntax/25_object_system.md @@ -0,0 +1,77 @@ +# 对象 + +可以分配给变量的所有数据。类具有以下属性。 + +* :返回对象的(非富)字符串表示法 +* :返回对象的大小(包括堆保留量) +* :返回对象属性的列表 +* :返回对象的散列值 +* :检索并返回对象的属性 +* :生成并返回对象的克隆(在内存中有独立实体) +* :返回对象的副本(在内存中指向相同的对象) + +## 记录 + +以记录文字()生成的对象。此对象具有基本方法,如。 + + +```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 +

diff --git a/doc/zh_CN/syntax/26_pattern_matching.md b/doc/zh_CN/syntax/26_pattern_matching.md new file mode 100644 index 00000000..96b40b64 --- /dev/null +++ b/doc/zh_CN/syntax/26_pattern_matching.md @@ -0,0 +1,203 @@ +# 模式匹配,可辩驳性 + +## 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 +

diff --git a/doc/zh_CN/syntax/27_comprehension.md b/doc/zh_CN/syntax/27_comprehension.md new file mode 100644 index 00000000..7195c95b --- /dev/null +++ b/doc/zh_CN/syntax/27_comprehension.md @@ -0,0 +1,65 @@ +# 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 +

diff --git a/doc/zh_CN/syntax/28_spread_syntax.md b/doc/zh_CN/syntax/28_spread_syntax.md new file mode 100644 index 00000000..b71ad142 --- /dev/null +++ b/doc/zh_CN/syntax/28_spread_syntax.md @@ -0,0 +1,45 @@ +# 展开分配 + +在分解赋值中,如果在变量之前放置,则所有剩余元素都可以扩展到该变量。这称为部署赋值。 + + +```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 +

diff --git a/doc/zh_CN/syntax/29_decorator.md b/doc/zh_CN/syntax/29_decorator.md new file mode 100644 index 00000000..5f7795ab --- /dev/null +++ b/doc/zh_CN/syntax/29_decorator.md @@ -0,0 +1,124 @@ +# 装饰器(修饰符) + +装饰器用于将特定的状态和行为添加到类型和函数中,或将其显式。装饰师的语法如下。 + + +```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 的特雷特相同的行为。 + + +```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 +``` + +在内部,我们只是使用特雷特的方法将其连接起来。如果发生冲突,可以使用特雷特的方法将其移除。 + + +```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 +

diff --git a/doc/zh_CN/syntax/30_error_handling.md b/doc/zh_CN/syntax/30_error_handling.md new file mode 100644 index 00000000..4bb8e220 --- /dev/null +++ b/doc/zh_CN/syntax/30_error_handling.md @@ -0,0 +1,106 @@ +# 错误处理系统 + +主要使用 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 +

diff --git a/doc/zh_CN/syntax/31_pipeline.md b/doc/zh_CN/syntax/31_pipeline.md new file mode 100644 index 00000000..be124273 --- /dev/null +++ b/doc/zh_CN/syntax/31_pipeline.md @@ -0,0 +1,32 @@ +# 流水线运算符 + +按如下方式使用管线运算符。 + + +```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 +

diff --git a/doc/zh_CN/syntax/32_integration_with_Python.md b/doc/zh_CN/syntax/32_integration_with_Python.md new file mode 100644 index 00000000..fcb7b207 --- /dev/null +++ b/doc/zh_CN/syntax/32_integration_with_Python.md @@ -0,0 +1,87 @@ +# 与 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 +

diff --git a/doc/zh_CN/syntax/33_package_system.md b/doc/zh_CN/syntax/33_package_system.md new file mode 100644 index 00000000..e0a02a7e --- /dev/null +++ b/doc/zh_CN/syntax/33_package_system.md @@ -0,0 +1,83 @@ +# 包装系统 + +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 +

diff --git a/doc/zh_CN/syntax/34_generator.md b/doc/zh_CN/syntax/34_generator.md new file mode 100644 index 00000000..8564835c --- /dev/null +++ b/doc/zh_CN/syntax/34_generator.md @@ -0,0 +1,37 @@ +# 发电机 + +生成器是在块中使用过程的特殊过程。 + + +```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 +

diff --git a/doc/zh_CN/syntax/SUMMARY.md b/doc/zh_CN/syntax/SUMMARY.md new file mode 100644 index 00000000..774c354b --- /dev/null +++ b/doc/zh_CN/syntax/SUMMARY.md @@ -0,0 +1,69 @@ +# 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_CN/syntax/container_ownership.md b/doc/zh_CN/syntax/container_ownership.md new file mode 100644 index 00000000..92bfcf5f --- /dev/null +++ b/doc/zh_CN/syntax/container_ownership.md @@ -0,0 +1,42 @@ +# 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` +``` diff --git a/doc/zh_CN/syntax/grammar.txt b/doc/zh_CN/syntax/grammar.txt new file mode 100644 index 00000000..d9dbbb2a --- /dev/null +++ b/doc/zh_CN/syntax/grammar.txt @@ -0,0 +1,88 @@ +# 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_CN/syntax/indexes.md b/doc/zh_CN/syntax/indexes.md new file mode 100644 index 00000000..0db44b64 --- /dev/null +++ b/doc/zh_CN/syntax/indexes.md @@ -0,0 +1,452 @@ +# 索引 + +この索引にないAPIについては[こちら](../API/index.md)を参照してください。 +用語の意味については[こちら](../dev_guide/terms.md)を参照。 + +## 記号 + +* ! + * !-type → [可変型](./type/mut.md) +* [#](./00_basic.md/#コメント) +* $ +* % +* & + * && +* ′ (single quote) +* () +* * + * [*-less multiplication](./01_literal.md/#less-multiplication) +* + (前置) + * +_ → + (前置) +* + (中置) +* , +* − (前置) + * −_ → − (前置) +* − (中置) + * −> +* . → [可視性] +* / +* : + * :: → [可視性] +* ; +* < + * <: + * << + * <= +* = + * == + * => +* > + * >> + * >= +* ? +* @ +* [] +* \ +* ^ + * ^^ +* _ + * _+_ → + (中置) + * _-_ → − (中置) +* `` +* {} + * {} type +* {:} +* {=} + * {=} type +* | + * || +* ~ + +## アルファベット + +### A + +* [algebraic type] +* [And] +* [and] +* [assert] +* [attribute] + +### B + +* [Base] +* [Bool] + +### C + +* [Class] + +### D + +* Deprecated +* [distinct] + +### E + +* [enum type] +* [Eq] +* [Erg] + +### F + +* [for] + +### G + +### H + +### I + +* [if] +* [import] +* [in] +* [Int] + +### J + +### K + +### L + +* let-polymorphism → [ランク1多相] +* [log] + +### M + +* [match] + +### N + +* [Nat] +* Never +* None +* None +* [Not] +* [not] + +### O + +* [Option] +* [Or] +* [or] +* [Ord] + +### P + +* panic +* [print!](./../API/procs.md#print) +* [Python] + +### Q + +### R + +* ref +* ref! +* [Result] +* [rootobj] + +### S + +* self +* [Self](./type/special.md) +* [side-effect](./07_side_effect.md) +* [Str] + +### T + +* Trait +* [True] +* [Type] +* [type] + +### U + +### V + +### W + +* [while!] + +### X + +### Y + +### Z + +## あ行 + +* [アサーション] +* 値オブジェクト +* [アタッチメントパッチ](./29_decorator.md#attach) +* アドホック多相 → [オーバーロードの禁止](./type/overloading.md) +* アトリビュート → [属性] +* アリティ +* [依存型](./type/dependent_type.md) +* イミュータブル → [不変] +* 引数(いんすう) → [引数(ひきすう)] +* インスタンス +* [インスタントブロック](./00_basic.md#式セパレータ) +* インデックス +* [インデント](./00_basic.md#インデント) +* エイリアス +* エラー + * [エラーハンドリング] +* [演算子](./06_operator.md) + * [演算子の結合強度] +* オーバーライド +* [オーバーロードの禁止](./type/overloading.md) +* オフサイドルール → [インデント](./00_basic.md#インデント) +* [オブジェクト] + * オブジェクト指向 +* オペランド → [被演算子](./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#可変状態の回避関数型プログラミング) +* 基底型 +* 記名 + * [記名型] → [クラス](./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#コンパイル時関数) +* コンマ → [,] + +## さ行 + +* 再帰 + * 再帰型 + * [再帰関数](./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#借用) +* [シャドーイング](./02_name.md#変数) +* 種 → [カインド](./type/advanced/kind.md) +* [集合] → [セット] +* 述語 + * [述語関数] +* 条件分岐 +* [所有権] +* 真偽型 → [Bool] +* シングルトン +* [シンボル] → [識別子](./02_name.md) + * [シンボル化] +* [スクリプト](./00_basic.md#スクリプト) +* スコープ +* スプレッド演算子 → [展開代入] +* [スライス](./10_array.md#スライス) +* 制御文字 +* [整数] → [Int] +* [セット](./12_set.md) +* セミコロン → [;] +* [宣言](./03_declaration.md) +* 全称 + * 全称型 → [多相型](./type/quantified.md) + * 閉じた全称型 + * 開いた全称型 + * 全称関数 → 多相関数 + * 全称量化 +* 前置演算子 +* 相互再帰 +* 添字 → [インデックス] +* [属性] + * [属性的部分型] + +## た行 + +* [代数](./02_name.md) + * [代数演算型](./type/13_algebraic.md) + * 代数的データ型 +* [代入](./02_variable.md/#代入) +* 多重 + * [多重継承](./type/07_inheritance.md/#多重継承の禁止) + * 多重代入 + * 多重定義 → [オーバーロードの禁止] +* 多相 + * [多相型](./type/quantified.md) + * 多相関数 +* 多態 → [ポリモーフィズム] +* ダックタイピング +* [タプル](./11_tuple.md) +* 単相 + * 単相化 + * 単相型 + * 単相関数 +* [遅延初期化] +* 抽出代入 +* 抽象構文木 → [AST] +* 中置演算子 +* [定数](./02_name.md/#定数) + * [定数型](./type/advanced/const.md) + * [定数式](./type/advanced/const.md) +* [定義] +* 提供属性 +* [適用] +* [デコレータ](./29_decorator.md) +* デストラクタ +* 手続き → [プロシージャ](./08_procedure.md) +* [デフォルト引数](./04_function.md/#デフォルト引数default-parameters) +* 展開 + * [展開演算子] + * [展開代入] +* [特殊形式](./../API/special.md) +* 匿名関数 → [無名関数](./20_lambda.md) +* ドット演算子(`.`) → [属性参照] +* トップ + * トップ型 → [Structural Object] + * トップクラス → [Object] +* [トレイト](./type/03_trait.md) + +## な行 + +* [内包表記](./27_comprehension.md) +* ~~中置(なかおき)演算子~~ → [中置(ちゅうち)演算子] +* [名前空間] + +## は行 + +* [配列](./10_array.md) +* [派生型](./type/variances.md/#ユーザー定義型の変性) +* [パターン(マッチ)](./26_pattern_matching.md) +* [パッケージ](./33_package_system.md) +* ハッシュマップ → [辞書](./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) +* 複素数 → [Complex] +* [浮動小数点数] → [Float] +* プライベート変数 → [非公開変数] +* ブール代数 → [Bool] +* [プロシージャ](./08_procedure.md) +* [引数](./04_function.md) +* 部分型付け → [サブタイピング] +* [不変] + * [不変オブジェクト] + * [不変型] + * [不変参照] +* [篩型](./type/12_refinement.md) +* [ブロック] +* 分解代入 +* [変数](./02_variable.md) +* ボトム + * ボトム型 → [{}] + * ボトムクラス → [Never] +* [ポリモーフィズム] + +## ま行 + +* ~~前置(まえおき)演算子~~ → 前置(ぜんち)演算子 +* [マーカー型](./type/advanced/marker_trait.md) +* [無名関数](./21_lambda.md) +* ミュータブル → [可変性] +* [ムーブ] +* メソッド +* メタキャラクタ +* [モジュール](./24_module.md) +* [文字列] → [Str] + * [文字列補間](./01_literal.md/#strリテラル) +* 戻り値 + +## や行 + +* [幽霊型](./type/advanced/phantom.md) +* 要求属性 +* [要素] +* [呼び出し] + +## ら行 + +* [ライブラリ] +* ラムダ式 → [無名関数](./20_lambda.md) +* ランク + * [ランク2多相](./type/advanced/rank2type.md) +* [リテラル](./01_literal.md) + * [リテラル識別子](./18_naming_rule.md/#リテラル識別子) +* [量化](./type/quantified.md) +* [レイアウト](./type/mut.md) +* [列挙型](./type/10_enum.md) +* [レコード](./12_record.md) + * [レコード型] + * レコード多相 → [列多相] +* [列多相] +* [ローカル変数](./19_visibility.md) + +## わ行 + +* ワイルドカード diff --git a/doc/zh_CN/syntax/quick_tour.md b/doc/zh_CN/syntax/quick_tour.md new file mode 100644 index 00000000..c572bc2f --- /dev/null +++ b/doc/zh_CN/syntax/quick_tour.md @@ -0,0 +1,287 @@ +# 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 不支持多级和多级继承。 + +## 特雷特 + +与 Rust 的特雷特类似,但更接近原意,可以合成和分离,属性和方法是对等的。也不涉及实施。 + + +```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. + ... +``` + +## 补丁 + +你可以为类和特雷特提供实现。 + +## 筛子型 + +可以在谓词表达式中限制类型。 + + +```erg +Nat = {I: Int | I >= 0} +``` + +## 包含值的参数化(从属) + + +```erg +a: [Int; 3] +b: [Int; 4] +a + b: [Int; 7] +``` diff --git a/doc/zh_CN/syntax/type/01_type_system.md b/doc/zh_CN/syntax/type/01_type_system.md new file mode 100644 index 00000000..9dc129fd --- /dev/null +++ b/doc/zh_CN/syntax/type/01_type_system.md @@ -0,0 +1,225 @@ +# 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 中,记名类型为类和特雷特。如果只是一个类/任务,则通常指的是记录类/记录任务。 + +| | 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 +

diff --git a/doc/zh_CN/syntax/type/02_basic.md b/doc/zh_CN/syntax/type/02_basic.md new file mode 100644 index 00000000..1ac552b4 --- /dev/null +++ b/doc/zh_CN/syntax/type/02_basic.md @@ -0,0 +1,170 @@ +# 类型的基本语法 + +## 类型指定 + +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 +

diff --git a/doc/zh_CN/syntax/type/03_trait.md b/doc/zh_CN/syntax/type/03_trait.md new file mode 100644 index 00000000..eda6c0b7 --- /dev/null +++ b/doc/zh_CN/syntax/type/03_trait.md @@ -0,0 +1,193 @@ +# 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 +

diff --git a/doc/zh_CN/syntax/type/04_class.md b/doc/zh_CN/syntax/type/04_class.md new file mode 100644 index 00000000..8b118e19 --- /dev/null +++ b/doc/zh_CN/syntax/type/04_class.md @@ -0,0 +1,285 @@ +# 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_CN/syntax/type/05_inheritance.md b/doc/zh_CN/syntax/type/05_inheritance.md new file mode 100644 index 00000000..fe573912 --- /dev/null +++ b/doc/zh_CN/syntax/type/05_inheritance.md @@ -0,0 +1,248 @@ +# 继承(Inheritance) + +通过继承,你可以定义一个新类,该新类将添加或特定于现有类。继承类似于特雷特中的包容。继承的类将成为原始类的子类型。 + + +```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,但有一个示例似乎是这样做的。 + +例如,(实现)的子类型似乎正在重新实现。 + + +```erg +Int = Class ..., Impl := Add() and ... +``` + +但实际上,中的的缩写,只是用覆盖。两者是不同的特雷特(,因此)。 + +## 禁止多重继承 + +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 +

diff --git a/doc/zh_CN/syntax/type/06_nst_vs_sst.md b/doc/zh_CN/syntax/type/06_nst_vs_sst.md new file mode 100644 index 00000000..950009c4 --- /dev/null +++ b/doc/zh_CN/syntax/type/06_nst_vs_sst.md @@ -0,0 +1,43 @@ +# 记名的部分型 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 +

diff --git a/doc/zh_CN/syntax/type/07_patch.md b/doc/zh_CN/syntax/type/07_patch.md new file mode 100644 index 00000000..55c08da4 --- /dev/null +++ b/doc/zh_CN/syntax/type/07_patch.md @@ -0,0 +1,223 @@ +# 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 与特雷特的关系 + +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 的特雷特听起来更方便,其实也不尽然。 + + +```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 +

diff --git a/doc/zh_CN/syntax/type/08_value.md b/doc/zh_CN/syntax/type/08_value.md new file mode 100644 index 00000000..bd2b4724 --- /dev/null +++ b/doc/zh_CN/syntax/type/08_value.md @@ -0,0 +1,38 @@ +# 值类型(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 语义学中,内存的概念不存在,因为它被放置在堆栈中,所以它是一种值类型,或者因为它是一个指针,所以它不是一种值类型,这些说法是不正确的。从根本上说,值类型是类型或其子类型。 diff --git a/doc/zh_CN/syntax/type/09_attributive.md b/doc/zh_CN/syntax/type/09_attributive.md new file mode 100644 index 00000000..1215574d --- /dev/null +++ b/doc/zh_CN/syntax/type/09_attributive.md @@ -0,0 +1,7 @@ +# 属性类型(Attributive Type) + +属性类型是包含记录和数据类、修补程序、模块等的类型。属于属性类型的类型不是值类型。 + +## 记录类型合并 + +合并的记录类型可以展平。例如,等于。 diff --git a/doc/zh_CN/syntax/type/10_interval.md b/doc/zh_CN/syntax/type/10_interval.md new file mode 100644 index 00000000..01d27148 --- /dev/null +++ b/doc/zh_CN/syntax/type/10_interval.md @@ -0,0 +1,39 @@ +# 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" +``` diff --git a/doc/zh_CN/syntax/type/11_enum.md b/doc/zh_CN/syntax/type/11_enum.md new file mode 100644 index 00000000..502507ce --- /dev/null +++ b/doc/zh_CN/syntax/type/11_enum.md @@ -0,0 +1,86 @@ +# 枚举类型 + +“枚举类型”(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 +``` diff --git a/doc/zh_CN/syntax/type/12_refinement.md b/doc/zh_CN/syntax/type/12_refinement.md new file mode 100644 index 00000000..281eab5a --- /dev/null +++ b/doc/zh_CN/syntax/type/12_refinement.md @@ -0,0 +1,75 @@ +# 筛子类型(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) = ... +``` diff --git a/doc/zh_CN/syntax/type/13_algebraic.md b/doc/zh_CN/syntax/type/13_algebraic.md new file mode 100644 index 00000000..92d63f96 --- /dev/null +++ b/doc/zh_CN/syntax/type/13_algebraic.md @@ -0,0 +1,82 @@ +# 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 类型不是真正的代数运算类型,因为它们总是可以简化。 diff --git a/doc/zh_CN/syntax/type/14_dependent.md b/doc/zh_CN/syntax/type/14_dependent.md new file mode 100644 index 00000000..8efd14ae --- /dev/null +++ b/doc/zh_CN/syntax/type/14_dependent.md @@ -0,0 +1,76 @@ +# 依赖关系 + +依赖性可以说是 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]} +``` diff --git a/doc/zh_CN/syntax/type/15_quantified.md b/doc/zh_CN/syntax/type/15_quantified.md new file mode 100644 index 00000000..b1bde16c --- /dev/null +++ b/doc/zh_CN/syntax/type/15_quantified.md @@ -0,0 +1,288 @@ +# 类型变量,量化 + +类型变量是用于指定子例程参数类型的变量,并指示其类型是可选的(非单相)。首先,作为引入类型变量的动机,让我们考虑返回输入的函数。 + + +```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 +``` diff --git a/doc/zh_CN/syntax/type/16_subtyping.md b/doc/zh_CN/syntax/type/16_subtyping.md new file mode 100644 index 00000000..cd921526 --- /dev/null +++ b/doc/zh_CN/syntax/type/16_subtyping.md @@ -0,0 +1,80 @@ +# 部分定型 + +在 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 +``` + +## 子程序的局部类型 + +子程序的参数和返回值只采用单个类。也就是说,不能将结构型和特雷特作为函数的类型直接指定。必须使用子类型指定将其指定为“作为该类型子类型的单个类”。 + + +```erg +# OK +f1 x, y: Int = x + y +# NG +f2 x, y: Add = x + y +# OK +# Aは何らかの具体的なクラス +f3 x, y: A = x + y +``` + +子程序的类型推论也遵循这个规则。当子程序中的变量中有未明示类型时,编译器首先检查该变量是否为某个类的实例,如果不是,则从作用域中的特雷特中寻找适合的变量。即使这样也找不到的话,就成为编译错误。这个错误可以通过使用结构型来消除,但是推论无名型有可能是程序员不想要的结果,所以设计成程序员明确地用来指定。 + +## 上传类 + + +```erg +i: Int +i as (Int or Str) +i as (1..10) +i as {I: Int | I >= 0} +``` diff --git a/doc/zh_CN/syntax/type/17_type_casting.md b/doc/zh_CN/syntax/type/17_type_casting.md new file mode 100644 index 00000000..77911d3e --- /dev/null +++ b/doc/zh_CN/syntax/type/17_type_casting.md @@ -0,0 +1,74 @@ +# 铸造 + +## 上投 + +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" +``` diff --git a/doc/zh_CN/syntax/type/18_mut.md b/doc/zh_CN/syntax/type/18_mut.md new file mode 100644 index 00000000..bcd9c9e5 --- /dev/null +++ b/doc/zh_CN/syntax/type/18_mut.md @@ -0,0 +1,168 @@ +# 可变类型(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类型和类型在语言上没有特殊关系,这是有意设计。如果存在关联,则会出现一些不便,例如,如果名称空间中存在类型/,则无法从另一个模块引入类型/。此外,与不可变类型相比,可变类型并不是唯一的。当定义时,变量子类型可以是 diff --git a/doc/zh_CN/syntax/type/19_bound.md b/doc/zh_CN/syntax/type/19_bound.md new file mode 100644 index 00000000..0c7c00f0 --- /dev/null +++ b/doc/zh_CN/syntax/type/19_bound.md @@ -0,0 +1,16 @@ +# 类型边界(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} +``` diff --git a/doc/zh_CN/syntax/type/advanced.md b/doc/zh_CN/syntax/type/advanced.md new file mode 100644 index 00000000..be845153 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced.md @@ -0,0 +1 @@ +以后将进一步解说高级型系统。入门的朋友不看所有的条款也没问题。 diff --git a/doc/zh_CN/syntax/type/advanced/GADTs.md b/doc/zh_CN/syntax/type/advanced/GADTs.md new file mode 100644 index 00000000..06b874e1 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/GADTs.md @@ -0,0 +1,68 @@ +# 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 +``` diff --git a/doc/zh_CN/syntax/type/advanced/_rank2type.md b/doc/zh_CN/syntax/type/advanced/_rank2type.md new file mode 100644 index 00000000..7f068403 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/_rank2type.md @@ -0,0 +1,142 @@ +# 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 级基本可以覆盖。 diff --git a/doc/zh_CN/syntax/type/advanced/default_param.md b/doc/zh_CN/syntax/type/advanced/default_param.md new file mode 100644 index 00000000..3e3f5ace --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/default_param.md @@ -0,0 +1,28 @@ +# 具有默认参数的函数类型 + +首先,看默认自变量的使用例。 + + +```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 个是可以省略任意的默认自变量的意思。 diff --git a/doc/zh_CN/syntax/type/advanced/erasure.md b/doc/zh_CN/syntax/type/advanced/erasure.md new file mode 100644 index 00000000..5c24a9c7 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/erasure.md @@ -0,0 +1,45 @@ +# 类型擦除(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) +``` diff --git a/doc/zh_CN/syntax/type/advanced/existential.md b/doc/zh_CN/syntax/type/advanced/existential.md new file mode 100644 index 00000000..89e642a9 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/existential.md @@ -0,0 +1,39 @@ +# 存在类型 + +如果有对应于应有尽有的全称型,那么自然会有对应于应有尽有的存在型。存在型并不难。只是你没有这样的意识,就已经知道了你的存在型。 + + +```erg +T: Trait +f x: T = ... +``` + +上面的特雷特被用作存在类型。相反,下面的只是特雷特,是全称类型。 + + +```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 +``` + +顺便说一下,类不称为存在类型。因为预先决定了成为那个要素的对象。存在型是指满足某一特雷特的所有类型,实际上不知道要代入什么类型。 diff --git a/doc/zh_CN/syntax/type/advanced/keyword_param.md b/doc/zh_CN/syntax/type/advanced/keyword_param.md new file mode 100644 index 00000000..537c9814 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/keyword_param.md @@ -0,0 +1,26 @@ +# 关键字参数函数类型 + + +```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 +``` diff --git a/doc/zh_CN/syntax/type/advanced/kind.md b/doc/zh_CN/syntax/type/advanced/kind.md new file mode 100644 index 00000000..43d32cf8 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/kind.md @@ -0,0 +1,157 @@ +# 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存在可视性等微妙的差异。 diff --git a/doc/zh_CN/syntax/type/advanced/marker_trait.md b/doc/zh_CN/syntax/type/advanced/marker_trait.md new file mode 100644 index 00000000..642d5cca --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/marker_trait.md @@ -0,0 +1,33 @@ +# Marker Trait + +标记托盘是没有要求属性的托盘。也就是说,不安装方法就可以 Impl。如果没有要求属性的话,似乎就没有意义了,但是因为登录了属于该特雷特的信息,所以可以使用补丁方法,编译器进行特别处理。 + +所有标记块都包含在块中。标准中提供的是一种标记托盘。 + + +```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 +``` diff --git a/doc/zh_CN/syntax/type/advanced/mut_struct.md b/doc/zh_CN/syntax/type/advanced/mut_struct.md new file mode 100644 index 00000000..6822b5f2 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/mut_struct.md @@ -0,0 +1,40 @@ +# 可变结构类型 + +型是可以插入任意的型对象进行替换的箱型。 + + +```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} +``` diff --git a/doc/zh_CN/syntax/type/advanced/newtype.md b/doc/zh_CN/syntax/type/advanced/newtype.md new file mode 100644 index 00000000..49819332 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/newtype.md @@ -0,0 +1,31 @@ +# 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 位数的先决条件。由于丢失了的所有方法,因此必须重新定义每次所需的运算。如果重新定义的成本不相称,最好使用继承。相反,你可能希望使用没有方法的特性,因此请根据具体情况选择适当的方法。 diff --git a/doc/zh_CN/syntax/type/advanced/overloading.md b/doc/zh_CN/syntax/type/advanced/overloading.md new file mode 100644 index 00000000..b32fe6e9 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/overloading.md @@ -0,0 +1,91 @@ +# 过载 + +Erg 不支持。也就是说,不能对函数卡印进行多重定义(过载)。但是,通过组合特雷特类和补丁,可以再现过载的行为。可以使用特雷特而不是特雷特类,但在这种情况下,安装的所有类型都成为对象。 + + +```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 +``` diff --git a/doc/zh_CN/syntax/type/advanced/phantom.md b/doc/zh_CN/syntax/type/advanced/phantom.md new file mode 100644 index 00000000..64622dc6 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/phantom.md @@ -0,0 +1,58 @@ +# 幽灵类型(Phantom class) + +幽灵型是只为给编译器注释而存在的标记特雷特。作为幽灵型的使用方法,来看清单的构成。 + + +```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") +``` + +通过方法或方法进行更新。这是的可变版本)标准补丁提供的方法,其用法与可变类型的相同。 diff --git a/doc/zh_CN/syntax/type/advanced/projection.md b/doc/zh_CN/syntax/type/advanced/projection.md new file mode 100644 index 00000000..e3b79ac1 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/projection.md @@ -0,0 +1,25 @@ +# 投影类型 + +投影类型表示以下代码中类似于的类型。 + + +```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 +``` diff --git a/doc/zh_CN/syntax/type/advanced/quantified_dependent.md b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md new file mode 100644 index 00000000..65d9df20 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md @@ -0,0 +1,30 @@ +# 量化依赖性 + +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] +``` diff --git a/doc/zh_CN/syntax/type/advanced/shared.md b/doc/zh_CN/syntax/type/advanced/shared.md new file mode 100644 index 00000000..ee86e003 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/shared.md @@ -0,0 +1,72 @@ +# 共享引用(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 +# $p1と$p2が同じものを指しているかは、`.addr!`で確認する +assert $p1.addr!() == $p2.addr!() +assert $p1.addr!() != $p3.addr!() +$p1.add! 1 +assert $p1 == 2 +assert $p2 == 2 +assert $p3 == 1 +``` + +类型的对象必须以开头。此外,由于其性质,它不能是常数。 + +类型也是类型的子类型,可以调用类型的方法。类型特定的方法只有。 + +一个重要的事实是,是非变态的。即,不定义不同类型参数的包含关系。 + + +```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 +``` diff --git a/doc/zh_CN/syntax/type/advanced/special.md b/doc/zh_CN/syntax/type/advanced/special.md new file mode 100644 index 00000000..d9d0eede --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/special.md @@ -0,0 +1,54 @@ +# 特殊类型(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 +``` diff --git a/doc/zh_CN/syntax/type/advanced/typeof.md b/doc/zh_CN/syntax/type/advanced/typeof.md new file mode 100644 index 00000000..9118c255 --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/typeof.md @@ -0,0 +1,61 @@ +# 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} +``` diff --git a/doc/zh_CN/syntax/type/advanced/variance.md b/doc/zh_CN/syntax/type/advanced/variance.md new file mode 100644 index 00000000..7696edfd --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/variance.md @@ -0,0 +1,128 @@ +# 退化(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) +``` diff --git a/doc/zh_CN/syntax/type/advanced/widening.md b/doc/zh_CN/syntax/type/advanced/widening.md new file mode 100644 index 00000000..c8ba5eca --- /dev/null +++ b/doc/zh_CN/syntax/type/advanced/widening.md @@ -0,0 +1,93 @@ +# 类型扩展(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 +``` + +这是为了不让子程序的返回值类型无意中混入其他类型的设计。但是,当返回值类型的选项是或等具有包含关系的类型时,向较大的类型对齐。 diff --git a/doc/zh_CN/tips.md b/doc/zh_CN/tips.md new file mode 100644 index 00000000..94df3d72 --- /dev/null +++ b/doc/zh_CN/tips.md @@ -0,0 +1,142 @@ +# 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 警告的选项(这是故意的设计)。重写代码。 diff --git a/doc/zh_CN/tools/build.md b/doc/zh_CN/tools/build.md new file mode 100644 index 00000000..ac3e8dc5 --- /dev/null +++ b/doc/zh_CN/tools/build.md @@ -0,0 +1,13 @@ +# build 子命令 + +build 子命令用于构建软件包。缺省构建过程如下所示。 + +1. 检查注释/文档(doc 以下的 md 文件)中的代码。 +2. 编译包所需的代码。 +3. 对于应用程序包,生成与命令对应的批处理文件或 shell 脚本。 +4. 运行测试。 + +构建完成后,交付项将输出到以下目录。 + +* 调试构建时:build/debug +* 版本构建时:build/release diff --git a/doc/zh_CN/tools/env.md b/doc/zh_CN/tools/env.md new file mode 100644 index 00000000..f6c50ac6 --- /dev/null +++ b/doc/zh_CN/tools/env.md @@ -0,0 +1,3 @@ +# env 子命令 + +env 子命令指定 erg 执行环境。在中创建新的运行时环境。当交互工具打开并指定 erg 版本时,将安装该版本的 erg(如果已安装,则将其用作新环境)。你可以在中切换环境。创建的环境可以在中进行编辑,可以预安装软件包或指定其他语言的依赖关系。该命令的最大特征是可以将在中再现环境的信息作为文件输出。据此,可以在与他人相同的环境下马上开始开发。并且,在中,可以像软件包那样公开环境。 diff --git a/doc/zh_CN/tools/fmt.md b/doc/zh_CN/tools/fmt.md new file mode 100644 index 00000000..8b6cfdf3 --- /dev/null +++ b/doc/zh_CN/tools/fmt.md @@ -0,0 +1,5 @@ +# fmt + +fmt 子命令允许在中设置代码格式。以下是常用的旗帜。 + +* explicit-type:自动完成省略类型的位置。 diff --git a/doc/zh_CN/tools/index.md b/doc/zh_CN/tools/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_CN/tools/install.md b/doc/zh_CN/tools/install.md new file mode 100644 index 00000000..e108a7af --- /dev/null +++ b/doc/zh_CN/tools/install.md @@ -0,0 +1,9 @@ +# install 子命令 + +install 可以安装在注册表站点注册的软件包。基本用法与包管理器(如 cargo)相同。 + +## 方便的功能 + +* 如果有名字相似的软件包名称,并且下载量比那个多 10 倍以上,就会出现错误输入的提示。由此,可以防止 typo squatting。 +* 如果软件包大小很大(50 MB 或更大),请查看大小以确定是否安装。 +* 如果软件包为 duplicated,则提示替换软件包。 diff --git a/doc/zh_CN/tools/pack.md b/doc/zh_CN/tools/pack.md new file mode 100644 index 00000000..b734adee --- /dev/null +++ b/doc/zh_CN/tools/pack.md @@ -0,0 +1,82 @@ +# 包管理器 + +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 账户来发表。缺省情况下,软件包注册为。如果满足一定的条件(下载数量,维护频率等),则可以申请注册省略所有者名称的别名。软件包名称不区分大小写和分隔符,如。 diff --git a/doc/zh_CN/tools/repl.md b/doc/zh_CN/tools/repl.md new file mode 100644 index 00000000..4781f7e0 --- /dev/null +++ b/doc/zh_CN/tools/repl.md @@ -0,0 +1,15 @@ +# REPL + +如果命令没有参数,则会调用 REPL。你也可以使用子命令启动它。还可以指定以下标志。 + +* typed:显示对象及其类型。 + + +```console +$ erg repl --typed +Erg interpreter ... (tags/?:, ...) on ... +>>> 1 +1: {1} +>>> id x = x +id = : |T: Type| T -> T +``` diff --git a/doc/zh_CN/tools/test.md b/doc/zh_CN/tools/test.md new file mode 100644 index 00000000..bc84403e --- /dev/null +++ b/doc/zh_CN/tools/test.md @@ -0,0 +1,43 @@ +# 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 = + ... + ... +``` + +测试时使用的模拟对象(嘲笑对象)定义在模块中。 From 638eb017504e649004677d88b647f3b72ce52e2b Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 08:18:45 +0800 Subject: [PATCH 02/42] Add traditional Chinese translation of documents --- doc/zh_CN/API/operators.md | 2 +- doc/zh_CN/API/types/traits/Add(R,O).md | 4 +- doc/zh_CN/dev_guide/directories.md | 44 +- doc/zh_CN/dev_guide/faq_syntax.md | 16 +- doc/zh_CN/dev_guide/terms.md | 4 +- doc/zh_CN/faq_general.md | 2 +- doc/zh_CN/improved_points.md | 2 +- doc/zh_CN/index.md | 14 +- doc/zh_CN/python/bytecode_specification.md | 4 +- doc/zh_CN/syntax/04_function.md | 2 +- doc/zh_CN/syntax/18_ownership.md | 2 +- doc/zh_CN/syntax/29_decorator.md | 4 +- doc/zh_CN/syntax/indexes.md | 686 +++++++-------- doc/zh_CN/syntax/quick_tour.md | 6 +- doc/zh_CN/syntax/type/01_type_system.md | 16 +- doc/zh_CN/syntax/type/05_inheritance.md | 6 +- doc/zh_CN/syntax/type/07_patch.md | 4 +- doc/zh_CN/syntax/type/16_subtyping.md | 4 +- doc/zh_CN/syntax/type/17_type_casting.md | 2 +- doc/zh_CN/syntax/type/18_mut.md | 2 +- doc/zh_CN/syntax/type/advanced/existential.md | 4 +- .../syntax/type/advanced/marker_trait.md | 2 +- doc/zh_CN/syntax/type/advanced/overloading.md | 2 +- doc/zh_CN/syntax/type/advanced/phantom.md | 2 +- doc/zh_CN/syntax/type/advanced/shared.md | 4 +- doc/zh_CN/syntax/type/advanced/typeof.md | 4 +- 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 | 42 + 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 | 31 + doc/zh_TW/dev_guide/build_features.md | 17 + doc/zh_TW/dev_guide/directories.md | 25 + 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 | 108 +++ 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 + 213 files changed, 12836 insertions(+), 422 deletions(-) create mode 100644 doc/zh_TW/API/consts.md create mode 100644 doc/zh_TW/API/funcs.md create mode 100644 doc/zh_TW/API/index.md create mode 100644 doc/zh_TW/API/modules/external/alstruct.md create mode 100644 doc/zh_TW/API/modules/repl.md create mode 100644 doc/zh_TW/API/modules/status.md create mode 100644 doc/zh_TW/API/modules/unit.md create mode 100644 doc/zh_TW/API/modules/unsound.md create mode 100644 doc/zh_TW/API/operators.md create mode 100644 doc/zh_TW/API/procs.md create mode 100644 doc/zh_TW/API/special.md create mode 100644 doc/zh_TW/API/types.md create mode 100644 doc/zh_TW/API/types/classes/Array!(T).md create mode 100644 doc/zh_TW/API/types/classes/Array(T).md create mode 100644 doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md create mode 100644 doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md create mode 100644 doc/zh_TW/API/types/classes/Class.md create mode 100644 doc/zh_TW/API/types/classes/Complex.md create mode 100644 doc/zh_TW/API/types/classes/Dict!.md create mode 100644 doc/zh_TW/API/types/classes/Either.md create mode 100644 doc/zh_TW/API/types/classes/Float.md create mode 100644 doc/zh_TW/API/types/classes/Function(N).md create mode 100644 doc/zh_TW/API/types/classes/Inf.md create mode 100644 doc/zh_TW/API/types/classes/Int.md create mode 100644 doc/zh_TW/API/types/classes/IntRange.md create mode 100644 doc/zh_TW/API/types/classes/Interval.md create mode 100644 doc/zh_TW/API/types/classes/Iterator.md create mode 100644 doc/zh_TW/API/types/classes/Kind(N).md create mode 100644 doc/zh_TW/API/types/classes/Matrix.md create mode 100644 doc/zh_TW/API/types/classes/Module.md create mode 100644 doc/zh_TW/API/types/classes/Nat.md create mode 100644 doc/zh_TW/API/types/classes/Neg.md create mode 100644 doc/zh_TW/API/types/classes/Never.md create mode 100644 doc/zh_TW/API/types/classes/NonZero.md create mode 100644 doc/zh_TW/API/types/classes/Object.md create mode 100644 doc/zh_TW/API/types/classes/Operator.md create mode 100644 doc/zh_TW/API/types/classes/Option.md create mode 100644 doc/zh_TW/API/types/classes/Pos.md create mode 100644 doc/zh_TW/API/types/classes/Ratio.md create mode 100644 doc/zh_TW/API/types/classes/Record.md create mode 100644 doc/zh_TW/API/types/classes/Result.md create mode 100644 doc/zh_TW/API/types/classes/Str!.md create mode 100644 doc/zh_TW/API/types/classes/Str.md create mode 100644 doc/zh_TW/API/types/classes/StrWithLen.md create mode 100644 doc/zh_TW/API/types/classes/Subroutine.md create mode 100644 doc/zh_TW/API/types/classes/Tensor.md create mode 100644 doc/zh_TW/API/types/classes/TransCell(T).md create mode 100644 doc/zh_TW/API/types/classes/Tuple.md create mode 100644 doc/zh_TW/API/types/classes/Type.md create mode 100644 doc/zh_TW/API/types/classes/Vector.md create mode 100644 doc/zh_TW/API/types/patches/BinOp.md create mode 100644 doc/zh_TW/API/types/patches/UnaryOp.md create mode 100644 doc/zh_TW/API/types/traits/Add(R,O).md create mode 100644 doc/zh_TW/API/types/traits/Div(R,O).md create mode 100644 doc/zh_TW/API/types/traits/Eq.md create mode 100644 doc/zh_TW/API/types/traits/Into.md create mode 100644 doc/zh_TW/API/types/traits/Iterable.md create mode 100644 doc/zh_TW/API/types/traits/Num.md create mode 100644 doc/zh_TW/API/types/traits/Ord.md create mode 100644 doc/zh_TW/API/types/traits/SafeDiv(R,O).md create mode 100644 doc/zh_TW/API/types/traits/Sample.md create mode 100644 doc/zh_TW/API/types/traits/Seq.md create mode 100644 doc/zh_TW/API/types/traits/Show.md create mode 100644 doc/zh_TW/API/types/traits/Unpack.md create mode 100644 doc/zh_TW/compiler/TODO_hint.md create mode 100644 doc/zh_TW/compiler/TODO_recov_suggest.md create mode 100644 doc/zh_TW/compiler/TODO_warn.md create mode 100644 doc/zh_TW/compiler/abandoned.md create mode 100644 doc/zh_TW/compiler/architecture.md create mode 100644 doc/zh_TW/compiler/errors.md create mode 100644 doc/zh_TW/compiler/hir.md create mode 100644 doc/zh_TW/compiler/index.md create mode 100644 doc/zh_TW/compiler/inference.md create mode 100644 doc/zh_TW/compiler/overview.md create mode 100644 doc/zh_TW/compiler/parsing.md create mode 100644 doc/zh_TW/compiler/refinement_subtyping.md create mode 100644 doc/zh_TW/compiler/trait_method_resolving.md create mode 100644 doc/zh_TW/compiler/transpile.md create mode 100644 doc/zh_TW/compiler/type_var_normalization.md create mode 100644 doc/zh_TW/dev_guide/branches.md create mode 100644 doc/zh_TW/dev_guide/build_features.md create mode 100644 doc/zh_TW/dev_guide/directories.md create mode 100644 doc/zh_TW/dev_guide/doc_guideline.md create mode 100644 doc/zh_TW/dev_guide/env.md create mode 100644 doc/zh_TW/dev_guide/faq_syntax.md create mode 100644 doc/zh_TW/dev_guide/i18n_messages.md create mode 100644 doc/zh_TW/dev_guide/index.md create mode 100644 doc/zh_TW/dev_guide/rust_code_guideline.md create mode 100644 doc/zh_TW/dev_guide/terms.md create mode 100644 doc/zh_TW/dev_guide/unify_terms.md create mode 100644 doc/zh_TW/faq_general.md create mode 100644 doc/zh_TW/faq_technical.md create mode 100644 doc/zh_TW/improved_points.md create mode 100644 doc/zh_TW/index.md create mode 100644 doc/zh_TW/migration_from_py.md create mode 100644 doc/zh_TW/python/bytecode_instructions.md create mode 100644 doc/zh_TW/python/bytecode_specification.md create mode 100644 doc/zh_TW/python/class_system.md create mode 100644 doc/zh_TW/python/index.md create mode 100644 doc/zh_TW/syntax/00_basic.md create mode 100644 doc/zh_TW/syntax/01_literal.md create mode 100644 doc/zh_TW/syntax/02_name.md create mode 100644 doc/zh_TW/syntax/03_declaration.md create mode 100644 doc/zh_TW/syntax/04_function.md create mode 100644 doc/zh_TW/syntax/05_builtin_funcs.md create mode 100644 doc/zh_TW/syntax/06_operator.md create mode 100644 doc/zh_TW/syntax/07_side_effect.md create mode 100644 doc/zh_TW/syntax/08_procedure.md create mode 100644 doc/zh_TW/syntax/09_builtin_procs.md create mode 100644 doc/zh_TW/syntax/10_array.md create mode 100644 doc/zh_TW/syntax/11_tuple.md create mode 100644 doc/zh_TW/syntax/12_dict.md create mode 100644 doc/zh_TW/syntax/13_record.md create mode 100644 doc/zh_TW/syntax/14_set.md create mode 100644 doc/zh_TW/syntax/15_type.md create mode 100644 doc/zh_TW/syntax/16_iterator.md create mode 100644 doc/zh_TW/syntax/17_mutability.md create mode 100644 doc/zh_TW/syntax/18_ownership.md create mode 100644 doc/zh_TW/syntax/19_visibility.md create mode 100644 doc/zh_TW/syntax/20_naming_rule.md create mode 100644 doc/zh_TW/syntax/21_lambda.md create mode 100644 doc/zh_TW/syntax/22_subroutine.md create mode 100644 doc/zh_TW/syntax/23_closure.md create mode 100644 doc/zh_TW/syntax/24_module.md create mode 100644 doc/zh_TW/syntax/25_object_system.md create mode 100644 doc/zh_TW/syntax/26_pattern_matching.md create mode 100644 doc/zh_TW/syntax/27_comprehension.md create mode 100644 doc/zh_TW/syntax/28_spread_syntax.md create mode 100644 doc/zh_TW/syntax/29_decorator.md create mode 100644 doc/zh_TW/syntax/30_error_handling.md create mode 100644 doc/zh_TW/syntax/31_pipeline.md create mode 100644 doc/zh_TW/syntax/32_integration_with_Python.md create mode 100644 doc/zh_TW/syntax/33_package_system.md create mode 100644 doc/zh_TW/syntax/34_generator.md create mode 100644 doc/zh_TW/syntax/SUMMARY.md create mode 100644 doc/zh_TW/syntax/container_ownership.md create mode 100644 doc/zh_TW/syntax/grammar.txt create mode 100644 doc/zh_TW/syntax/indexes.md create mode 100644 doc/zh_TW/syntax/quick_tour.md create mode 100644 doc/zh_TW/syntax/type/01_type_system.md create mode 100644 doc/zh_TW/syntax/type/02_basic.md create mode 100644 doc/zh_TW/syntax/type/03_trait.md create mode 100644 doc/zh_TW/syntax/type/04_class.md create mode 100644 doc/zh_TW/syntax/type/05_inheritance.md create mode 100644 doc/zh_TW/syntax/type/06_nst_vs_sst.md create mode 100644 doc/zh_TW/syntax/type/07_patch.md create mode 100644 doc/zh_TW/syntax/type/08_value.md create mode 100644 doc/zh_TW/syntax/type/09_attributive.md create mode 100644 doc/zh_TW/syntax/type/10_interval.md create mode 100644 doc/zh_TW/syntax/type/11_enum.md create mode 100644 doc/zh_TW/syntax/type/12_refinement.md create mode 100644 doc/zh_TW/syntax/type/13_algebraic.md create mode 100644 doc/zh_TW/syntax/type/14_dependent.md create mode 100644 doc/zh_TW/syntax/type/15_quantified.md create mode 100644 doc/zh_TW/syntax/type/16_subtyping.md create mode 100644 doc/zh_TW/syntax/type/17_type_casting.md create mode 100644 doc/zh_TW/syntax/type/18_mut.md create mode 100644 doc/zh_TW/syntax/type/19_bound.md create mode 100644 doc/zh_TW/syntax/type/advanced.md create mode 100644 doc/zh_TW/syntax/type/advanced/GADTs.md create mode 100644 doc/zh_TW/syntax/type/advanced/_rank2type.md create mode 100644 doc/zh_TW/syntax/type/advanced/default_param.md create mode 100644 doc/zh_TW/syntax/type/advanced/erasure.md create mode 100644 doc/zh_TW/syntax/type/advanced/existential.md create mode 100644 doc/zh_TW/syntax/type/advanced/keyword_param.md create mode 100644 doc/zh_TW/syntax/type/advanced/kind.md create mode 100644 doc/zh_TW/syntax/type/advanced/marker_trait.md create mode 100644 doc/zh_TW/syntax/type/advanced/mut_struct.md create mode 100644 doc/zh_TW/syntax/type/advanced/newtype.md create mode 100644 doc/zh_TW/syntax/type/advanced/overloading.md create mode 100644 doc/zh_TW/syntax/type/advanced/phantom.md create mode 100644 doc/zh_TW/syntax/type/advanced/projection.md create mode 100644 doc/zh_TW/syntax/type/advanced/quantified_dependent.md create mode 100644 doc/zh_TW/syntax/type/advanced/shared.md create mode 100644 doc/zh_TW/syntax/type/advanced/special.md create mode 100644 doc/zh_TW/syntax/type/advanced/typeof.md create mode 100644 doc/zh_TW/syntax/type/advanced/variance.md create mode 100644 doc/zh_TW/syntax/type/advanced/widening.md create mode 100644 doc/zh_TW/tips.md create mode 100644 doc/zh_TW/tools/build.md create mode 100644 doc/zh_TW/tools/env.md create mode 100644 doc/zh_TW/tools/fmt.md create mode 100644 doc/zh_TW/tools/index.md create mode 100644 doc/zh_TW/tools/install.md create mode 100644 doc/zh_TW/tools/pack.md create mode 100644 doc/zh_TW/tools/repl.md create mode 100644 doc/zh_TW/tools/test.md diff --git a/doc/zh_CN/API/operators.md b/doc/zh_CN/API/operators.md index 5c767571..0df302ea 100644 --- a/doc/zh_CN/API/operators.md +++ b/doc/zh_CN/API/operators.md @@ -1,4 +1,4 @@ -# 操作员 +# 运算符 ## 中缀运算符 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 bf735100..230d4f5c 100644 --- a/doc/zh_CN/API/types/traits/Add(R,O).md +++ b/doc/zh_CN/API/types/traits/Add(R,O).md @@ -14,7 +14,7 @@ Add R = Trait { `_+_`(l: Add(R, O), r: R): O = l.`_+_` r ``` -わざわざこの定義があるのは、`+`をメソッドではなく関数として取り扱えるようにである。 +这个定义的目的是让 `+` 可以被视为一个函数而不是一个方法 ```erg assert [1, 2, 3].fold(0, `_+_`) == 6 @@ -23,7 +23,7 @@ call op, x, y = op(x, y) assert call(`_+_`, 1, 2) == 3 ``` -加算はこのように型付けされる。 +加法是这样输入的。 ```erg f: |O: Type; A <: Add(Int, O)| A -> O diff --git a/doc/zh_CN/dev_guide/directories.md b/doc/zh_CN/dev_guide/directories.md index 9a5dca1a..8e5c340e 100644 --- a/doc/zh_CN/dev_guide/directories.md +++ b/doc/zh_CN/dev_guide/directories.md @@ -1,25 +1,25 @@ -# Erg 存储库目录结构 +# Erg存储表结构 ```console - └─┬ assets: 画像など - ├─ CODE_OF_CONDUCT: 行動規範 - ├─┬ compiler - │ ├─ erg_common: 共通のユーティリティ - │ ├─ erg_compiler - │ └─ erg_parser: パーサー - ├─┬ doc - │ ├─┬ EN - │ │ ├─ API: Erg標準API - │ │ ├─ compiler: コンパイラの実装に関して - │ │ ├─ dev_guide: 開発・貢献者向けガイド - │ │ ├─ python: Ergの開発に必要なPythonの知識 - │ │ ├─ syntax: Ergの文法 - │ │ └─ tools: Ergのコマンドラインツールに関して - │ └─┬ JA - │ ... - ├─ examples: サンプルコード - ├─ library: Ergスクリプトによるライブラリ - ├─ src: main.rsとドライバの置かれたディレクトリ - └─ tests: テストコード -``` + └─┬资产:图片等 + ├─ CODE_OF_CONDUCT:行为准则 + ├─┬编译器 + │ ├─ erg_common:通用工具 + │ ├─ erg_compiler + │ └─ erg_parser:解析器 + ├─┬文档 + │ ├─┬ CN + │ │ ├─ API:Erg标准API + │ │ ├─ 编译器:关于编译器实现 + │ │ ├─ dev_guide:开发者和贡献者指南 + │ │ ├─ python:Erg开发必备的Python知识 + │ │ ├─ 语法:Erg语法 + │ │ └─ 工具:Erg命令行工具 + │ └─┬ JA + │ ... + ├─ 示例:示例代码 + ├─ library:Erg脚本库 + ├─ src:main.rs和驱动所在目录 + └─ tests:测试代码 +``` \ 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 f33d5696..a22cf325 100644 --- a/doc/zh_CN/dev_guide/faq_syntax.md +++ b/doc/zh_CN/dev_guide/faq_syntax.md @@ -1,8 +1,8 @@ # Erg design's "Why" and Answers -## 为什么有产权体系,GC 也让它共存? +## 为什么拥有所有权系统仍然同时使用GC? -因为 Erg 推出所有权系统的动机并不是为了 Rust 那样的“不依赖 GC 的内存管理”。最初,由于 Erg 是一种语言,目前已被 Python 字节码删除,因此最终仍使用 GC。Erg 引入产权系统的目标是“可变状态的局部化”。在 Erg 中,可变对象具有所有权概念。这是根据共享可变状态容易成为 bug 的温床,甚至是类型安全性的侵犯(详见)来判断的。 +因为 Erg 推出所有权系统的动机并不是为了 Rust 那样的“不依赖 GC 的内存管理”。最初,由于 Erg 是一种语言,目前使用 Python VM,因此最终仍使用 GC。Erg 引入产权系统的目标是“可变状态的局部化”。在 Erg 中,可变对象具有所有权概念。这是根据共享可变状态容易成为 bug 的温床,甚至是类型安全性的侵犯(详见)来判断的。 ## 为什么类型参数周围的括号不是 <> 或 []? @@ -12,13 +12,13 @@ ```erg # []版 id[T: Type] [t]: [T] = t -y = id[Int] # これは関数? +y = id[Int] # 这是一个功能吗? # <>版 id {t: T} = t y = (id 1) # これはタプル? # {}版 id{T: Type} {t: T} = t -y = id{Int} # これは関数? +y = id{Int} # 这是一个功能吗? # ||版 id|T: Type| t: T = t y = id|Int| # OK @@ -53,16 +53,16 @@ assert S.i == Int ```erg read_file!() = - f = open!("foo.txt")? # 失敗したらエラーをすぐさま返すので、fはFile型 + f = open!("foo.txt")? # 如果失败则立即返回错误,所以 f 是文件类型 f.read_all!() -# tryプロシージャで例外のような捕捉処理も可能 +# 也可以使用 try 过程捕获类似的异常 try!: do! s = read_file!()? print! s e => - # エラー発生時に実行するブロック + # 发生错误时执行的块 print! e exit 1 ``` @@ -75,7 +75,7 @@ try!: Python 的库中有一些类设计为继承,如果完全取消继承,这些操作就会出现问题。然而,由于 Erg 的类默认为 final,并且原则上禁止多重和多层继承,因此继承的使用相对安全。 -## 为什么多相关数的子类型推理默认指向记名特雷特? +## 为什么多相关数的子类型推理默认指向记名trait? 默认情况下,指向结构托盘会使类型指定变得复杂,并且可能会混合程序员的非预期行为。 diff --git a/doc/zh_CN/dev_guide/terms.md b/doc/zh_CN/dev_guide/terms.md index fc7a4f18..bb7d1b9c 100644 --- a/doc/zh_CN/dev_guide/terms.md +++ b/doc/zh_CN/dev_guide/terms.md @@ -629,7 +629,7 @@ x = ### 授课属性 -可用作 API 的属性。特别是由特雷特自动实现的属性。 +可用作 API 的属性。特别是由trait自动实现的属性。 ### 应用 @@ -643,7 +643,7 @@ x = f x = ... ``` -的糖衣语法,或者。大约等于。本身只是一个高阶子程序。 +的语法糖,或者。大约等于。本身只是一个高阶子程序。 ### 析构 diff --git a/doc/zh_CN/faq_general.md b/doc/zh_CN/faq_general.md index 74358eed..dfd1e6f4 100644 --- a/doc/zh_CN/faq_general.md +++ b/doc/zh_CN/faq_general.md @@ -10,7 +10,7 @@ ## Erg 受到了什么语言的影响? -双手也受到无数种语言的影响,其中受影响特别强烈的是 Python/Rust/Nim/Haskell。Python 继承了许多与越位规则兼容的语义学,Rust 继承了面向表达式和特雷特,Nim 继承了过程,Haskell 继承了函数型编程相关的功能。 +双手也受到无数种语言的影响,其中受影响特别强烈的是 Python/Rust/Nim/Haskell。Python 继承了许多与越位规则兼容的语义学,Rust 继承了面向表达式和trait,Nim 继承了过程,Haskell 继承了函数型编程相关的功能。 ## 可以调用 Python 的语言包括 Julia。你为什么做 Erg? diff --git a/doc/zh_CN/improved_points.md b/doc/zh_CN/improved_points.md index 72761c78..18256623 100644 --- a/doc/zh_CN/improved_points.md +++ b/doc/zh_CN/improved_points.md @@ -31,7 +31,7 @@ i = 257 assert i is not 257 ``` -## 特雷特 +## trait 就像 Java 的界面一样,它可以进行基于合约的编程。 diff --git a/doc/zh_CN/index.md b/doc/zh_CN/index.md index db3516f8..87cf57ae 100644 --- a/doc/zh_CN/index.md +++ b/doc/zh_CN/index.md @@ -1,25 +1,25 @@ -# Index +# 指数 ## [API/](./API/index.md) - Ergの組み込みまたは標準ライブラリで提供されるサブルーチン、型、定数等の仕様が記述されている。 + 描述 Erg 的内置或标准库提供的子程序、类型、常量等的规范。 ## [compiler/](./compiler/index.md) - Ergコンパイラ(Centimetre)の設計について解説されている。 + 解释了 Erg 编译器(厘米)的设计。 ## [dev_guide/](./dev_guide/index.md) - プロジェクトの開発方針、コントリビューションの仕方などが解説されている。 + 项目的开发方针、贡献方式等进行了说明。 ## [python/](./python/index.md) - Ergを開発する上で必要となるPythonの知識が解説されている。 + 解释了开发 Erg 所需的 Python 知识。 ## [syntax/](./syntax/00_basic.md) - Ergの文法が解説されている。 + Erg语法解释。 ## [tools/](./tools/index.md) - Ergの周辺ツール、コマンドオプションの使い方などが解説されている。 + Erg的外围工具,如何使用命令选项等进行了说明。 \ 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 5cd9034f..8b96fc9b 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 了?) +* 如果我使用ascii以外的字符,它会变成PyUnicode吗? +* "あ", "𠮷“,”和“α”是PyUnicode(不再使用?) * 0 byte: 0x73 (means 's') * 1~4 byte: length of string diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md index ed9d9e43..a500538c 100644 --- a/doc/zh_CN/syntax/04_function.md +++ b/doc/zh_CN/syntax/04_function.md @@ -299,7 +299,7 @@ f(a, b) # TypeError: f() takes 1 positional argument but 2 were given f((a, b)) # OK ``` -函数类型实际上是的糖衣语法。 +函数类型实际上是的语法糖。

Previous | Next diff --git a/doc/zh_CN/syntax/18_ownership.md b/doc/zh_CN/syntax/18_ownership.md index 3deed98a..14607388 100644 --- a/doc/zh_CN/syntax/18_ownership.md +++ b/doc/zh_CN/syntax/18_ownership.md @@ -4,7 +4,7 @@ ## 所有权 -Erg 有一个所有权系统受到拉斯特的影响。Rust 的所有权系统通常被称为晦涩难懂,但 Erg 的所有权系统被简化为直观。Erg 拥有的所有权,一旦失去所有权,就无法查看该对象。 +Erg 有一个所有权系统受到Rust的影响。Rust 的所有权系统通常被称为晦涩难懂,但 Erg 的所有权系统被简化为直观。Erg 拥有的所有权,一旦失去所有权,就无法查看该对象。 ```erg diff --git a/doc/zh_CN/syntax/29_decorator.md b/doc/zh_CN/syntax/29_decorator.md index 5f7795ab..ed7207e8 100644 --- a/doc/zh_CN/syntax/29_decorator.md +++ b/doc/zh_CN/syntax/29_decorator.md @@ -70,7 +70,7 @@ C. ## Attach -指定默认情况下随托盘一起提供的附件曲面片。这样,你就可以重现与 Rust 的特雷特相同的行为。 +指定默认情况下随托盘一起提供的附件曲面片。这样,你就可以重现与 Rust 的trait相同的行为。 ```erg @@ -99,7 +99,7 @@ assert Int.AddO == Int assert Odd.AddO == Even ``` -在内部,我们只是使用特雷特的方法将其连接起来。如果发生冲突,可以使用特雷特的方法将其移除。 +在内部,我们只是使用trait的方法将其连接起来。如果发生冲突,可以使用trait的方法将其移除。 ```erg diff --git a/doc/zh_CN/syntax/indexes.md b/doc/zh_CN/syntax/indexes.md index 0db44b64..ba4811be 100644 --- a/doc/zh_CN/syntax/indexes.md +++ b/doc/zh_CN/syntax/indexes.md @@ -1,43 +1,43 @@ -# 索引 +# 指数 -この索引にないAPIについては[こちら](../API/index.md)を参照してください。 -用語の意味については[こちら](../dev_guide/terms.md)を参照。 +有关不在此索引中的 API,请参阅 [此处](../API/index.md)。 +有关术语,请参见 [此处](../dev_guide/terms.md)。 -## 記号 +## 象征 -* ! - * !-type → [可変型](./type/mut.md) -* [#](./00_basic.md/#コメント) -* $ -* % +* ! + * !-type → [可变类型](./type/mut.md) +* [#](./00_basic.md/#comment) +*$ +*% * & * && -* ′ (single quote) +* ′(单引号) * () * * - * [*-less multiplication](./01_literal.md/#less-multiplication) -* + (前置) - * +_ → + (前置) -* + (中置) + * [*-less 乘法](./01_literal.md/#less-multiplication) +* + (前缀) + * +_ → + (前缀) +* + (中缀) * , -* − (前置) - * −_ → − (前置) -* − (中置) - * −> -* . → [可視性] +* −(前缀) + * −_ → − (前缀) +* −(中缀) + * 减号;> +* . → [可见性] * / * : - * :: → [可視性] + * :: → [可见性] * ; -* < +* < * <: - * << - * <= + * << + * <= * = * == * => * > - * >> + *>> * >= * ? * @ @@ -46,120 +46,120 @@ * ^ * ^^ * _ - * _+_ → + (中置) - * _-_ → − (中置) -* `` + * _+_ → +(中缀) + * _-_ → −(中缀) +*`` * {} - * {} type + * {} 类型 * {:} * {=} - * {=} type + * {=} 类型 * | * || * ~ -## アルファベット +## 字母 -### A +### 一个 -* [algebraic type] -* [And] -* [and] -* [assert] -* [attribute] +* [代数类型] +* [和] +* [和] +* [断言] +* [属性] -### B +###B -* [Base] -* [Bool] +* [根据] +* [布尔] -### C +### C -* [Class] +* [班级] -### D +###D -* Deprecated -* [distinct] +*已弃用 +* [清楚的] -### E +###E -* [enum type] -* [Eq] -* [Erg] +* [枚举类型] +*[方程式] +*[erg] -### F +###F -* [for] +*[为了] -### G +###G -### H +###H -### I +### 我 -* [if] -* [import] -* [in] -* [Int] +*[如果] +* [进口] +* [在] +* [诠释] -### J +###J -### K +###K -### L +### 大号 -* let-polymorphism → [ランク1多相] -* [log] +* let-polymorphism → [rank 1 多态性] +* [日志] -### M +###M -* [match] +* [匹配] -### N +###N -* [Nat] -* Never -* None -* None -* [Not] -* [not] +*[纳特] +* 绝不 +*没有任何 +*没有任何 +*[不是] +* [不是] -### O +###O -* [Option] -* [Or] -* [or] -* [Ord] +* [选项] +* [或者] +* [或者] +*[订购] -### P +###P -* panic -* [print!](./../API/procs.md#print) -* [Python] +* 恐慌 +* [打印!](./../API/procs.md#print) +*[Python] ### Q ### R -* ref -* ref! -* [Result] -* [rootobj] +* 参考 +* 参考! +* [结果] +* [根对象] ### S -* self -* [Self](./type/special.md) -* [side-effect](./07_side_effect.md) -* [Str] +* 自己 +* [自我](./type/special.md) +* [副作用](./07_side_effect.md) +* [力量] ### T -* Trait -* [True] -* [Type] -* [type] +* 特质 +* [真的] +* [类型] +* [类型] ### U @@ -167,7 +167,7 @@ ### W -* [while!] +* [尽管!] ### X @@ -175,278 +175,278 @@ ### Z -## あ行 +## 一行 -* [アサーション] -* 値オブジェクト -* [アタッチメントパッチ](./29_decorator.md#attach) -* アドホック多相 → [オーバーロードの禁止](./type/overloading.md) -* アトリビュート → [属性] -* アリティ -* [依存型](./type/dependent_type.md) -* イミュータブル → [不変] -* 引数(いんすう) → [引数(ひきすう)] -* インスタンス -* [インスタントブロック](./00_basic.md#式セパレータ) -* インデックス -* [インデント](./00_basic.md#インデント) -* エイリアス -* エラー - * [エラーハンドリング] -* [演算子](./06_operator.md) - * [演算子の結合強度] -* オーバーライド -* [オーバーロードの禁止](./type/overloading.md) -* オフサイドルール → [インデント](./00_basic.md#インデント) -* [オブジェクト] - * オブジェクト指向 -* オペランド → [被演算子](./06_operator.md) -* オペレーター → [演算子](./06_operator.md) +* [断言] +* 值对象 +* [附件补丁](./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#可変状態の回避関数型プログラミング) -* 基底型 -* 記名 - * [記名型] → [クラス](./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#コンパイル時関数) -* コンマ → [,] +* [种类](./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) +* 递归 + * 递归 + * [递归函数](./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#借用) -* [シャドーイング](./02_name.md#変数) -* 種 → [カインド](./type/advanced/kind.md) -* [集合] → [セット] -* 述語 - * [述語関数] -* 条件分岐 -* [所有権] -* 真偽型 → [Bool] -* シングルトン -* [シンボル] → [識別子](./02_name.md) - * [シンボル化] -* [スクリプト](./00_basic.md#スクリプト) -* スコープ -* スプレッド演算子 → [展開代入] -* [スライス](./10_array.md#スライス) -* 制御文字 -* [整数] → [Int] -* [セット](./12_set.md) -* セミコロン → [;] -* [宣言](./03_declaration.md) -* 全称 - * 全称型 → [多相型](./type/quantified.md) - * 閉じた全称型 - * 開いた全称型 - * 全称関数 → 多相関数 - * 全称量化 -* 前置演算子 -* 相互再帰 -* 添字 → [インデックス] +* 泛型 → [通用类型] +* 发电机 +* [投影类型] +* 借用 → [参考](./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/#代入) -* 多重 - * [多重継承](./type/07_inheritance.md/#多重継承の禁止) - * 多重代入 - * 多重定義 → [オーバーロードの禁止] + * [代数类型](./type/13_algebraic.md) + * 代数数据类型 +* [赋值](./02_variable.md/#assignment) +* 多 + * [多重继承](./type/07_inheritance.md/#禁止多重继承) + * 多重赋值 + * 重载 → [不重载] * 多相 - * [多相型](./type/quantified.md) - * 多相関数 -* 多態 → [ポリモーフィズム] -* ダックタイピング -* [タプル](./11_tuple.md) -* 単相 - * 単相化 - * 単相型 - * 単相関数 -* [遅延初期化] -* 抽出代入 -* 抽象構文木 → [AST] -* 中置演算子 -* [定数](./02_name.md/#定数) - * [定数型](./type/advanced/const.md) - * [定数式](./type/advanced/const.md) -* [定義] -* 提供属性 -* [適用] -* [デコレータ](./29_decorator.md) -* デストラクタ -* 手続き → [プロシージャ](./08_procedure.md) -* [デフォルト引数](./04_function.md/#デフォルト引数default-parameters) -* 展開 - * [展開演算子] - * [展開代入] -* [特殊形式](./../API/special.md) -* 匿名関数 → [無名関数](./20_lambda.md) -* ドット演算子(`.`) → [属性参照] -* トップ - * トップ型 → [Structural Object] - * トップクラス → [Object] -* [トレイト](./type/03_trait.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) -* ~~中置(なかおき)演算子~~ → [中置(ちゅうち)演算子] -* [名前空間] +* [理解](./27_comprehension.md) +* ~~中缀运算符~~ → [中缀运算符] +* [命名空间] -## は行 +## 是一行 -* [配列](./10_array.md) -* [派生型](./type/variances.md/#ユーザー定義型の変性) -* [パターン(マッチ)](./26_pattern_matching.md) -* [パッケージ](./33_package_system.md) -* ハッシュマップ → [辞書](./11_dict.md) -* [パッチ](./type/07_patch.md) -* パブリック変数 → [公開変数](./19_visibility.md) -* パラメーター → [引数](./04_function.md) -* [パラメトリック多相](./type/overloading.md) -* [反変](./type/advanced/variance.md) -* 比較 - * [比較演算子] - * [比較可能型] -* [非公開変数](./19_visibility.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) -* 複素数 → [Complex] -* [浮動小数点数] → [Float] -* プライベート変数 → [非公開変数] -* ブール代数 → [Bool] -* [プロシージャ](./08_procedure.md) -* [引数](./04_function.md) -* 部分型付け → [サブタイピング] -* [不変] - * [不変オブジェクト] - * [不変型] - * [不変参照] -* [篩型](./type/12_refinement.md) -* [ブロック] -* 分解代入 -* [変数](./02_variable.md) -* ボトム - * ボトム型 → [{}] - * ボトムクラス → [Never] -* [ポリモーフィズム] +* 复数 → [复数] +* [浮动] → [浮动] +* 私有变量 → [私有变量] +* 布尔代数 → [布尔] +* [程序](./08_procedure.md) +* [参数](./04_function.md) +* 部分输入 → [子输入] +* [不可变] + * [不可变对象] + * [不可变类型] + * [不可变引用] +* [筛子类型](./type/12_refinement.md) +* [堵塞] +* 解构赋值 +* [变量](./02_variable.md) +* 底部 + * 底部类型 → [{}] + * 底层 → [从不] +* [多态性] -## ま行 +## 马线 -* ~~前置(まえおき)演算子~~ → 前置(ぜんち)演算子 -* [マーカー型](./type/advanced/marker_trait.md) -* [無名関数](./21_lambda.md) -* ミュータブル → [可変性] -* [ムーブ] -* メソッド -* メタキャラクタ -* [モジュール](./24_module.md) -* [文字列] → [Str] - * [文字列補間](./01_literal.md/#strリテラル) -* 戻り値 +* ~~ 前缀运算符 ~~ → 前缀运算符 +* [标记类型](./type/advanced/marker_trait.md) +* [匿名函数](./21_lambda.md) +* 可变 → [可变] +* [移动] +* 方法 +* 元字符 +* [模块](./24_module.md) +* [字符串] → [字符串] + * [字符串插值](./01_literal.md/#str 字面量) +* 返回值 -## や行 +## 或行 -* [幽霊型](./type/advanced/phantom.md) -* 要求属性 -* [要素] -* [呼び出し] +* [幽灵类型](./type/advanced/phantom.md) +* 请求属性 +* [元素] +* [称呼] -## ら行 +## 拉线 -* [ライブラリ] -* ラムダ式 → [無名関数](./20_lambda.md) -* ランク - * [ランク2多相](./type/advanced/rank2type.md) -* [リテラル](./01_literal.md) - * [リテラル識別子](./18_naming_rule.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) +* [布局](./type/mut.md) +* [枚举](./type/10_enum.md) +* [记录](./12_record.md) + * [记录类型] + * 记录多态 → [列多态] +* [列多态] +* [局部变量](./19_visibility.md) -## わ行 +## 线 -* ワイルドカード +* 通配符 \ 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 c572bc2f..a2a75af5 100644 --- a/doc/zh_CN/syntax/quick_tour.md +++ b/doc/zh_CN/syntax/quick_tour.md @@ -247,9 +247,9 @@ odds = [i | i <- 1..100; i % 2 == 0] Erg 不支持多级和多级继承。 -## 特雷特 +## trait -与 Rust 的特雷特类似,但更接近原意,可以合成和分离,属性和方法是对等的。也不涉及实施。 +与 Rust 的trait类似,但更接近原意,可以合成和分离,属性和方法是对等的。也不涉及实施。 ```erg @@ -266,7 +266,7 @@ Point. ## 补丁 -你可以为类和特雷特提供实现。 +你可以为类和trait提供实现。 ## 筛子型 diff --git a/doc/zh_CN/syntax/type/01_type_system.md b/doc/zh_CN/syntax/type/01_type_system.md index 9dc129fd..ddae11a1 100644 --- a/doc/zh_CN/syntax/type/01_type_system.md +++ b/doc/zh_CN/syntax/type/01_type_system.md @@ -28,17 +28,17 @@ o2 = D.new {.public = 2} # InitializationError: class 'D' requires attribute 'pr Erg 中的所有对象都已输入。最高类型是,它实现了等(它们不是请求方法,也不能覆盖这些属性)。Erg 类型系统采用结构子类型(Structural subtyping,SST)。系统输入的类型称为“结构类型”(Structural type)。有三种结构类型:Attributive(属性类型)/Refinement(筛子类型)/Algebraic(代数类型)。 -| | Record | Enum |Interval| Union | Intersection | Diff | +| | Record | Enum | Interval | Union | Intersection | Diff | | --------- | ----------- | ---------- | -------------- | ----------- | ------------ | ------------ | -| kind | Attributive | Refinement |Refinement| Algebraic | Algebraic | Algebraic | -| generator | record | set |range operator| or operator | and operator | not operator | +| 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 中,记名类型为类和特雷特。如果只是一个类/任务,则通常指的是记录类/记录任务。 +也可以使用 Nominal subtyping(Nominal subtyping,NST),将 SST 类型转换为 NST 类型称为“类型记名”(Nominalization)。这种类型称为“记名类型”(Nominal type)。在 Erg 中,记名类型为类和trait。如果只是一个类/任务,则通常指的是记录类/记录任务。 -| | Type | Abstraction |Subtyping procedure| +| | Type | Abstraction | Subtyping procedure | | --- | -------------- | ---------------- | ------------------- | -| NST | NominalType | Trait |Inheritance| -| SST | StructuralType | Structural Trait |(Implicit)| +| NST | NominalType | Trait | Inheritance | +| SST | StructuralType | Structural Trait | (Implicit) | 表示整个记名类型的类型()和整个结构类型的类型()是整个类型的类型()的子类型。 @@ -107,7 +107,7 @@ Point2D = {.x = Int; .y = Int} ## 类型类、数据类型(等效) -如前所述,Erg 中的“类型”大致是指一组对象。以下是要求(中置运算符)的类型的定义。是一个所谓的类型参数,它包含实现的类型(类),如。在其他语言中,类型参数具有特殊的符号(通用、模板等),但在 Erg 中,类型参数的定义方式与常规参数的定义方式相同。类型参数也可以不是类型对象。例如,序列类型是的糖衣语法。如果类型实现被覆盖,则用户必须显式选择。 +如前所述,Erg 中的“类型”大致是指一组对象。以下是要求(中置运算符)的类型的定义。是一个所谓的类型参数,它包含实现的类型(类),如。在其他语言中,类型参数具有特殊的符号(通用、模板等),但在 Erg 中,类型参数的定义方式与常规参数的定义方式相同。类型参数也可以不是类型对象。例如,序列类型是的语法糖。如果类型实现被覆盖,则用户必须显式选择。 ```erg diff --git a/doc/zh_CN/syntax/type/05_inheritance.md b/doc/zh_CN/syntax/type/05_inheritance.md index fe573912..3c78393d 100644 --- a/doc/zh_CN/syntax/type/05_inheritance.md +++ b/doc/zh_CN/syntax/type/05_inheritance.md @@ -1,6 +1,6 @@ # 继承(Inheritance) -通过继承,你可以定义一个新类,该新类将添加或特定于现有类。继承类似于特雷特中的包容。继承的类将成为原始类的子类型。 +通过继承,你可以定义一个新类,该新类将添加或特定于现有类。继承类似于trait中的包容。继承的类将成为原始类的子类型。 ```erg @@ -116,7 +116,7 @@ Inherited!. 但这一规范并不能完全解决覆盖问题。编译器无法检测覆盖是否修复了问题。创建派生类的程序员有责任修改替代的影响。应尽可能定义别名方法。 -### 替换特雷特(类似于) +### 替换trait(类似于) 你不能在继承过程中替换 TRAIT,但有一个示例似乎是这样做的。 @@ -127,7 +127,7 @@ Inherited!. Int = Class ..., Impl := Add() and ... ``` -但实际上,中的的缩写,只是用覆盖。两者是不同的特雷特(,因此)。 +但实际上,中的的缩写,只是用覆盖。两者是不同的trait(,因此)。 ## 禁止多重继承 diff --git a/doc/zh_CN/syntax/type/07_patch.md b/doc/zh_CN/syntax/type/07_patch.md index 55c08da4..395adf29 100644 --- a/doc/zh_CN/syntax/type/07_patch.md +++ b/doc/zh_CN/syntax/type/07_patch.md @@ -132,7 +132,7 @@ NumStrRev. # hint: `Str` (superclass of `NumericStr`) is associated with `Reverse` by `StrReverse` ``` -## Appendix:Rust 与特雷特的关系 +## Appendix:Rust 与trait的关系 Erg 修补程序相当于 Rust 的 impl 块(后置)。 @@ -150,7 +150,7 @@ impl Reverse for String { } ``` -可以说,Rust Traitt 是 Erg Traitt 和补丁的功能的结合。这样说来,Rust 的特雷特听起来更方便,其实也不尽然。 +可以说,Rust Traitt 是 Erg Traitt 和补丁的功能的结合。这样说来,Rust 的trait听起来更方便,其实也不尽然。 ```erg diff --git a/doc/zh_CN/syntax/type/16_subtyping.md b/doc/zh_CN/syntax/type/16_subtyping.md index cd921526..f3f4bc04 100644 --- a/doc/zh_CN/syntax/type/16_subtyping.md +++ b/doc/zh_CN/syntax/type/16_subtyping.md @@ -54,7 +54,7 @@ assert not c in D ## 子程序的局部类型 -子程序的参数和返回值只采用单个类。也就是说,不能将结构型和特雷特作为函数的类型直接指定。必须使用子类型指定将其指定为“作为该类型子类型的单个类”。 +子程序的参数和返回值只采用单个类。也就是说,不能将结构型和trait作为函数的类型直接指定。必须使用子类型指定将其指定为“作为该类型子类型的单个类”。 ```erg @@ -67,7 +67,7 @@ f2 x, y: Add = x + y f3 x, y: A = x + y ``` -子程序的类型推论也遵循这个规则。当子程序中的变量中有未明示类型时,编译器首先检查该变量是否为某个类的实例,如果不是,则从作用域中的特雷特中寻找适合的变量。即使这样也找不到的话,就成为编译错误。这个错误可以通过使用结构型来消除,但是推论无名型有可能是程序员不想要的结果,所以设计成程序员明确地用来指定。 +子程序的类型推论也遵循这个规则。当子程序中的变量中有未明示类型时,编译器首先检查该变量是否为某个类的实例,如果不是,则从作用域中的trait中寻找适合的变量。即使这样也找不到的话,就成为编译错误。这个错误可以通过使用结构型来消除,但是推论无名型有可能是程序员不想要的结果,所以设计成程序员明确地用来指定。 ## 上传类 diff --git a/doc/zh_CN/syntax/type/17_type_casting.md b/doc/zh_CN/syntax/type/17_type_casting.md index 77911d3e..4fd887a9 100644 --- a/doc/zh_CN/syntax/type/17_type_casting.md +++ b/doc/zh_CN/syntax/type/17_type_casting.md @@ -1,4 +1,4 @@ -# 铸造 +# cast ## 上投 diff --git a/doc/zh_CN/syntax/type/18_mut.md b/doc/zh_CN/syntax/type/18_mut.md index bcd9c9e5..9c41fe64 100644 --- a/doc/zh_CN/syntax/type/18_mut.md +++ b/doc/zh_CN/syntax/type/18_mut.md @@ -72,7 +72,7 @@ K! T: Type = Class ... 当然,你没有必要把所有这些都背下来,熟练使用。对于可变数组类型,只需在想要可变的部分加上,在实际应用中,四个可以覆盖大多数情况。 -这些排列类型是糖衣语法,实际类型如下: +这些排列类型是语法糖,实际类型如下: ```erg diff --git a/doc/zh_CN/syntax/type/advanced/existential.md b/doc/zh_CN/syntax/type/advanced/existential.md index 89e642a9..c8a0f7ec 100644 --- a/doc/zh_CN/syntax/type/advanced/existential.md +++ b/doc/zh_CN/syntax/type/advanced/existential.md @@ -8,7 +8,7 @@ T: Trait f x: T = ... ``` -上面的特雷特被用作存在类型。相反,下面的只是特雷特,是全称类型。 +上面的trait被用作存在类型。相反,下面的只是trait,是全称类型。 ```erg @@ -36,4 +36,4 @@ id|T|(x: T): T = x show(s: Show): () = log s ``` -顺便说一下,类不称为存在类型。因为预先决定了成为那个要素的对象。存在型是指满足某一特雷特的所有类型,实际上不知道要代入什么类型。 +顺便说一下,类不称为存在类型。因为预先决定了成为那个要素的对象。存在型是指满足某一trait的所有类型,实际上不知道要代入什么类型。 diff --git a/doc/zh_CN/syntax/type/advanced/marker_trait.md b/doc/zh_CN/syntax/type/advanced/marker_trait.md index 642d5cca..a873e4da 100644 --- a/doc/zh_CN/syntax/type/advanced/marker_trait.md +++ b/doc/zh_CN/syntax/type/advanced/marker_trait.md @@ -1,6 +1,6 @@ # Marker Trait -标记托盘是没有要求属性的托盘。也就是说,不安装方法就可以 Impl。如果没有要求属性的话,似乎就没有意义了,但是因为登录了属于该特雷特的信息,所以可以使用补丁方法,编译器进行特别处理。 +标记托盘是没有要求属性的托盘。也就是说,不安装方法就可以 Impl。如果没有要求属性的话,似乎就没有意义了,但是因为登录了属于该trait的信息,所以可以使用补丁方法,编译器进行特别处理。 所有标记块都包含在块中。标准中提供的是一种标记托盘。 diff --git a/doc/zh_CN/syntax/type/advanced/overloading.md b/doc/zh_CN/syntax/type/advanced/overloading.md index b32fe6e9..760dcc5b 100644 --- a/doc/zh_CN/syntax/type/advanced/overloading.md +++ b/doc/zh_CN/syntax/type/advanced/overloading.md @@ -1,6 +1,6 @@ # 过载 -Erg 不支持。也就是说,不能对函数卡印进行多重定义(过载)。但是,通过组合特雷特类和补丁,可以再现过载的行为。可以使用特雷特而不是特雷特类,但在这种情况下,安装的所有类型都成为对象。 +Erg 不支持。也就是说,不能对函数卡印进行多重定义(过载)。但是,通过组合trait类和补丁,可以再现过载的行为。可以使用trait而不是trait类,但在这种情况下,安装的所有类型都成为对象。 ```erg diff --git a/doc/zh_CN/syntax/type/advanced/phantom.md b/doc/zh_CN/syntax/type/advanced/phantom.md index 64622dc6..f9221806 100644 --- a/doc/zh_CN/syntax/type/advanced/phantom.md +++ b/doc/zh_CN/syntax/type/advanced/phantom.md @@ -1,6 +1,6 @@ # 幽灵类型(Phantom class) -幽灵型是只为给编译器注释而存在的标记特雷特。作为幽灵型的使用方法,来看清单的构成。 +幽灵型是只为给编译器注释而存在的标记trait。作为幽灵型的使用方法,来看清单的构成。 ```erg diff --git a/doc/zh_CN/syntax/type/advanced/shared.md b/doc/zh_CN/syntax/type/advanced/shared.md index ee86e003..90990621 100644 --- a/doc/zh_CN/syntax/type/advanced/shared.md +++ b/doc/zh_CN/syntax/type/advanced/shared.md @@ -37,10 +37,10 @@ log vip_area # OwnershipError: `vip_room` was moved to `normal_room` $p1 = SharedCell!.new(!1) $p2 = $p1.mirror!() $p3 = SharedCell!.new(!1) -# $p1 == $p2とすると、中身の型Int!の比較が行われる +# $p1 == $p2 比较内容类型 Int! assert $p1 == $p2 assert $p1 == $p3 -# $p1と$p2が同じものを指しているかは、`.addr!`で確認する +# 检查 `.addr!` 以查看 $p1 和 $p2 是否相同 assert $p1.addr!() == $p2.addr!() assert $p1.addr!() != $p3.addr!() $p1.add! 1 diff --git a/doc/zh_CN/syntax/type/advanced/typeof.md b/doc/zh_CN/syntax/type/advanced/typeof.md index 9118c255..45df6258 100644 --- a/doc/zh_CN/syntax/type/advanced/typeof.md +++ b/doc/zh_CN/syntax/type/advanced/typeof.md @@ -44,12 +44,12 @@ 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__を持つレコードは定義できないが、概念上はこうなる +# 你实际上不能用 __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__を持つレコード型になる +# 标记类也是带有 __valueclass_tag__ 的记录类型 M = Inherit Marker assert Structure(M) == {__valueclass_tag__ = Phantom M} D = Inherit(C and M) diff --git a/doc/zh_TW/API/consts.md b/doc/zh_TW/API/consts.md new file mode 100644 index 00000000..b42e2f5b --- /dev/null +++ b/doc/zh_TW/API/consts.md @@ -0,0 +1,13 @@ +# 内置常量 + +## True + +## False + +## None + +## Ellipsis + +## NotImplemented + +## Inf diff --git a/doc/zh_TW/API/funcs.md b/doc/zh_TW/API/funcs.md new file mode 100644 index 00000000..0dc265a6 --- /dev/null +++ b/doc/zh_TW/API/funcs.md @@ -0,0 +1,121 @@ +# 功能 + +## 基本功能 + +### 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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/modules/external/alstruct.md b/doc/zh_TW/API/modules/external/alstruct.md new file mode 100644 index 00000000..fabb7330 --- /dev/null +++ b/doc/zh_TW/API/modules/external/alstruct.md @@ -0,0 +1,57 @@ +# 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 new file mode 100644 index 00000000..8570237d --- /dev/null +++ b/doc/zh_TW/API/modules/repl.md @@ -0,0 +1,24 @@ +# 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 new file mode 100644 index 00000000..c4f16ba0 --- /dev/null +++ b/doc/zh_TW/API/modules/status.md @@ -0,0 +1,6 @@ +# 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 new file mode 100644 index 00000000..05dec139 --- /dev/null +++ b/doc/zh_TW/API/modules/unit.md @@ -0,0 +1,73 @@ +# 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 new file mode 100644 index 00000000..0f950ba5 --- /dev/null +++ b/doc/zh_TW/API/modules/unsound.md @@ -0,0 +1,24 @@ +# 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 new file mode 100644 index 00000000..21883d6e --- /dev/null +++ b/doc/zh_TW/API/operators.md @@ -0,0 +1,64 @@ +# 運算符 + +## 中綴運算符 + +### `_+_`|R; O; A <: Add(R, O)|(x: A, y: R) -> O + +執行加法。 + +### `_-_`|R; O; S <: Sub(R, O)|(x: S, y: R) -> O + +執行減法。 + +### `*`|R; O; M <: Mul R, O|(x: M, y: R) -> O + +執行乘法。 + +### `/`|R; O; D <: Div(R, O)|(x: D, y: R) -> O + +進行除法。 + +## 中綴字母運算符 + +### `and`(x: Bool, y: Bool) -> Bool + +執行 and 操作。 + +### `or`(x: Bool, y: Bool) -> Bool + +執行 and 操作。 + +## 前綴運算符 + +### `+_`|T <: Num|(x: T) -> T + +默認與 id 相同。 + +### `-_`|T <: Num|(x: T) -> T.Neg + +例如 Nat.`-`: Nat -> Neg 和返回值不同。 + +### `!`|T <: Immut|(x: T) -> `T!` + +從不可變對象創建可變對象。 +該運算符本身不是程序性的,可以在函數內部使用。 + +### `..`|T <: Ord|(x: T) -> Range T + +在 x 的末尾創建一個沒有下限的 Range 對象。 +x..x 僅返回 x 作為迭代器。 + +### `..<`|T <: Ord|(x: T) -> Range T + +x.. Range T + +創建一個從 x 開始沒有上限的 Range 對象。 + +### |T <: Ord|(x: T)`<..` -> Range T \ No newline at end of file diff --git a/doc/zh_TW/API/procs.md b/doc/zh_TW/API/procs.md new file mode 100644 index 00000000..e86d53ff --- /dev/null +++ b/doc/zh_TW/API/procs.md @@ -0,0 +1,39 @@ +# 過程 + +## 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 new file mode 100644 index 00000000..b1cab7c9 --- /dev/null +++ b/doc/zh_TW/API/special.md @@ -0,0 +1,175 @@ +# 特殊形式 + +特殊形式是不能在 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 new file mode 100644 index 00000000..8c6a8690 --- /dev/null +++ b/doc/zh_TW/API/types.md @@ -0,0 +1,262 @@ +# 內置 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 new file mode 100644 index 00000000..3c45fb7b --- /dev/null +++ b/doc/zh_TW/API/types/classes/Array!(T).md @@ -0,0 +1,3 @@ +# 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 new file mode 100644 index 00000000..107b4366 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Array(T).md @@ -0,0 +1,3 @@ +# 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 new file mode 100644 index 00000000..f6d9694e --- /dev/null +++ b/doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md @@ -0,0 +1,34 @@ +# 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 new file mode 100644 index 00000000..c38879d9 --- /dev/null +++ b/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md @@ -0,0 +1,26 @@ +# 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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/classes/Complex.md b/doc/zh_TW/API/types/classes/Complex.md new file mode 100644 index 00000000..de15086f --- /dev/null +++ b/doc/zh_TW/API/types/classes/Complex.md @@ -0,0 +1,14 @@ +# 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 new file mode 100644 index 00000000..ddea3c04 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Dict!.md @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 00000000..3bf6f0ce --- /dev/null +++ b/doc/zh_TW/API/types/classes/Either.md @@ -0,0 +1,12 @@ +# 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 new file mode 100644 index 00000000..08ff7971 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Float.md @@ -0,0 +1,21 @@ +# 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 new file mode 100644 index 00000000..0955f2ec --- /dev/null +++ b/doc/zh_TW/API/types/classes/Function(N).md @@ -0,0 +1,9 @@ +# 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 new file mode 100644 index 00000000..afcee108 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Inf.md @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 00000000..5f213e9b --- /dev/null +++ b/doc/zh_TW/API/types/classes/Interval.md @@ -0,0 +1,18 @@ +# 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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/classes/Kind(N).md b/doc/zh_TW/API/types/classes/Kind(N).md new file mode 100644 index 00000000..4a72aec9 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Kind(N).md @@ -0,0 +1,5 @@ +# 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 new file mode 100644 index 00000000..18c69b27 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Matrix.md @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 00000000..03b89e9f --- /dev/null +++ b/doc/zh_TW/API/types/classes/Module.md @@ -0,0 +1,3 @@ +# Module + +## methods diff --git a/doc/zh_TW/API/types/classes/Nat.md b/doc/zh_TW/API/types/classes/Nat.md new file mode 100644 index 00000000..d497c993 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Nat.md @@ -0,0 +1,18 @@ +# 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 new file mode 100644 index 00000000..2dfed2b1 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Neg.md @@ -0,0 +1,8 @@ +# 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 new file mode 100644 index 00000000..00415554 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Never.md @@ -0,0 +1,13 @@ +# 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 new file mode 100644 index 00000000..f2dffc07 --- /dev/null +++ b/doc/zh_TW/API/types/classes/NonZero.md @@ -0,0 +1,30 @@ +# 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 new file mode 100644 index 00000000..12340489 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Object.md @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 00000000..7560538f --- /dev/null +++ b/doc/zh_TW/API/types/classes/Operator.md @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 00000000..bf88a2cc --- /dev/null +++ b/doc/zh_TW/API/types/classes/Option.md @@ -0,0 +1,21 @@ +# 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 new file mode 100644 index 00000000..08963541 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Pos.md @@ -0,0 +1,8 @@ +# 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 new file mode 100644 index 00000000..decf10b3 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Ratio.md @@ -0,0 +1,5 @@ +# 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 new file mode 100644 index 00000000..1b7809b9 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Record.md @@ -0,0 +1,14 @@ +# 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 new file mode 100644 index 00000000..3bf3e792 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Result.md @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 00000000..5ffc3c30 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Str!.md @@ -0,0 +1,3 @@ +# 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 new file mode 100644 index 00000000..e29350a3 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Str.md @@ -0,0 +1,9 @@ +# 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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/classes/Subroutine.md b/doc/zh_TW/API/types/classes/Subroutine.md new file mode 100644 index 00000000..24204ec4 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Subroutine.md @@ -0,0 +1,19 @@ +# 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 new file mode 100644 index 00000000..1a4ca2b7 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Tensor.md @@ -0,0 +1,24 @@ +# 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 new file mode 100644 index 00000000..b31ac1e7 --- /dev/null +++ b/doc/zh_TW/API/types/classes/TransCell(T).md @@ -0,0 +1,12 @@ +# 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 new file mode 100644 index 00000000..294b6743 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Tuple.md @@ -0,0 +1,27 @@ +# 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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/classes/Vector.md b/doc/zh_TW/API/types/classes/Vector.md new file mode 100644 index 00000000..d5351a61 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Vector.md @@ -0,0 +1,3 @@ +# 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 new file mode 100644 index 00000000..4c212763 --- /dev/null +++ b/doc/zh_TW/API/types/patches/BinOp.md @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 00000000..e5d26abd --- /dev/null +++ b/doc/zh_TW/API/types/patches/UnaryOp.md @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 00000000..91aa315c --- /dev/null +++ b/doc/zh_TW/API/types/traits/Add(R,O).md @@ -0,0 +1,34 @@ +# 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 new file mode 100644 index 00000000..b31431d0 --- /dev/null +++ b/doc/zh_TW/API/types/traits/Div(R,O).md @@ -0,0 +1,9 @@ +# 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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/traits/Into.md b/doc/zh_TW/API/types/traits/Into.md new file mode 100644 index 00000000..e6ae5e72 --- /dev/null +++ b/doc/zh_TW/API/types/traits/Into.md @@ -0,0 +1,11 @@ +# 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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/traits/Num.md b/doc/zh_TW/API/types/traits/Num.md new file mode 100644 index 00000000..5745c5ce --- /dev/null +++ b/doc/zh_TW/API/types/traits/Num.md @@ -0,0 +1,16 @@ +# 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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/traits/SafeDiv(R,O).md b/doc/zh_TW/API/types/traits/SafeDiv(R,O).md new file mode 100644 index 00000000..54c3a1b1 --- /dev/null +++ b/doc/zh_TW/API/types/traits/SafeDiv(R,O).md @@ -0,0 +1,8 @@ +# 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 new file mode 100644 index 00000000..12d09b4a --- /dev/null +++ b/doc/zh_TW/API/types/traits/Sample.md @@ -0,0 +1,31 @@ +# 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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/traits/Show.md b/doc/zh_TW/API/types/traits/Show.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/traits/Unpack.md b/doc/zh_TW/API/types/traits/Unpack.md new file mode 100644 index 00000000..c78b03ba --- /dev/null +++ b/doc/zh_TW/API/types/traits/Unpack.md @@ -0,0 +1,13 @@ +# 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 new file mode 100644 index 00000000..3844f83f --- /dev/null +++ b/doc/zh_TW/compiler/TODO_hint.md @@ -0,0 +1,4 @@ +# 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 new file mode 100644 index 00000000..cf919c9f --- /dev/null +++ b/doc/zh_TW/compiler/TODO_recov_suggest.md @@ -0,0 +1,11 @@ +# 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 new file mode 100644 index 00000000..bc503a9f --- /dev/null +++ b/doc/zh_TW/compiler/TODO_warn.md @@ -0,0 +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)? diff --git a/doc/zh_TW/compiler/abandoned.md b/doc/zh_TW/compiler/abandoned.md new file mode 100644 index 00000000..d858a2f0 --- /dev/null +++ b/doc/zh_TW/compiler/abandoned.md @@ -0,0 +1,10 @@ +# 廢棄/拒絕的語言規範 + +## 重載(臨時多態性) + +被放棄了,因為它可以用參數+子類型多態來代替,並且與Python的語義不兼容。有關詳細信息,請參閱 [overload](../syntax/type/overloading.md) 文章。 + +## 具有顯式生命週期的所有權系統 + +原計劃引入 Rust 之類的所有權系統,但由於與 Python 的語義不兼容以及需要引入生命週期註解等複雜規範而被放棄,並且所有不可變對像都是 RC。託管的可變對象現在只有一個所有權. +Dyne 沒有 C# 和 Nim 那樣的 GIL,策略是允許值對象和低級操作在安全範圍內。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/architecture.md b/doc/zh_TW/compiler/architecture.md new file mode 100644 index 00000000..dc578ac3 --- /dev/null +++ b/doc/zh_TW/compiler/architecture.md @@ -0,0 +1,42 @@ +# `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` 和 `VirtualMachine` 實現。 + +## 2. 轉換 `TokenStream` -> `AST` (parser/parse.rs) + +* `Parser` 和 `Lexer` 一樣,有兩個構造函數,`Parser::new` 和 `Parser::from_str`,而 `Parser::parse` 會給出 `AST`。 +* `AST` 是 `Vec` 的包裝器類型。 + +### 2.5 脫糖 `AST` + +* 擴展嵌套變量 (`Desugarer::desugar_nest_vars_pattern`) +* desugar 多模式定義語法(`Desugarer::desugar_multiple_pattern_def`) + +## 3. 類型檢查和推斷,轉換 `AST` -> `HIR` (compiler/lower.rs) + +* `HIR` 有每個變量的類型信息。它是用於“高級中間表示”的。 +* `HIR` 只保存變量的類型,但這已經足夠了。在極端情況下,這是因為 Erg 只有轉換(或運算符)應用程序的參數對象。 +* `ASTLower` 可以用與`Parser` 和`Lexer` 相同的方式構造。 +* 如果沒有錯誤發生,`ASTLowerer::lower` 將輸出 `HIR` 和 `CompileWarnings` 的元組。 +* `ASTLowerer`歸`Compiler`所有。與傳統結構不同,`ASTLowerer`處理代碼上下文並且不是一次性的。 +* 如果類型推斷的結果不完整(如果存在未知類型變量),名稱解析時會出錯。 + +## 4. 檢查副作用(compiler/effectcheck.rs) + +## 4. 檢查所有權(compiler/memcheck.rs) + +## 5. 從`HIR`(compiler/codegen.rs)生成字節碼(`CodeObj`) + +* 根據表達式的類型信息,將執行量化子程序的名稱解析。 + +##(6.(未來計劃)轉換字節碼 -> LLVM IR) + +* 字節碼是基於堆棧的,而 LLVM IR 是基於寄存器的。 + 這個轉換過程會多出幾層中間過程。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/errors.md b/doc/zh_TW/compiler/errors.md new file mode 100644 index 00000000..a8ff3779 --- /dev/null +++ b/doc/zh_TW/compiler/errors.md @@ -0,0 +1,131 @@ +# 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 new file mode 100644 index 00000000..b7b64b68 --- /dev/null +++ b/doc/zh_TW/compiler/hir.md @@ -0,0 +1,148 @@ +# 高レベル中間表現(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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/compiler/inference.md b/doc/zh_TW/compiler/inference.md new file mode 100644 index 00000000..5efd4f9d --- /dev/null +++ b/doc/zh_TW/compiler/inference.md @@ -0,0 +1,436 @@ +# 類型推理算法 + +> :本節正在編輯中,可能包含某些錯誤。 + +以下是使用的表示方法。 + + +```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 new file mode 100644 index 00000000..b3621bd5 --- /dev/null +++ b/doc/zh_TW/compiler/overview.md @@ -0,0 +1,36 @@ +# 概覽 + +介紹每個圖層的工作方式以及特別重要的函數和方法。 + +## 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 new file mode 100644 index 00000000..5024f080 --- /dev/null +++ b/doc/zh_TW/compiler/parsing.md @@ -0,0 +1,31 @@ +# 解析 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 new file mode 100644 index 00000000..fa8a4aa5 --- /dev/null +++ b/doc/zh_TW/compiler/refinement_subtyping.md @@ -0,0 +1,155 @@ +# 篩子型 + +篩型是指以下類型。 + + +```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 new file mode 100644 index 00000000..f4a1e55c --- /dev/null +++ b/doc/zh_TW/compiler/trait_method_resolving.md @@ -0,0 +1,86 @@ +# 解決修補程序方法 + +是大於 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 new file mode 100644 index 00000000..c87ab9e0 --- /dev/null +++ b/doc/zh_TW/compiler/transpile.md @@ -0,0 +1,91 @@ +# 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 new file mode 100644 index 00000000..a4d46e87 --- /dev/null +++ b/doc/zh_TW/compiler/type_var_normalization.md @@ -0,0 +1,35 @@ +# 歸一化 + +* 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 new file mode 100644 index 00000000..d9c2769f --- /dev/null +++ b/doc/zh_TW/dev_guide/branches.md @@ -0,0 +1,31 @@ +# 分支機構命名和運營策略 + +* 基本上,開發是在一個分支中進行的(單回購開發)。只有在必須斷開分支才能工作的情況下,才創建分支或分支。 + +## main + +* 主要開發分支 +* 必須滿足以下條件 + +* 編譯成功 + +## beta(目前不創建) + +* 最新的 Beta 版本 +* 必須滿足以下條件 + +* 編譯成功 +* 所有測試都會成功 + +## feature-* + +* 開發特定功能的分支 +* 切開 main + +* 沒有條件 + +## issue-* + +* 解決特定 issue 的分支 + +* 沒有條件 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/build_features.md b/doc/zh_TW/dev_guide/build_features.md new file mode 100644 index 00000000..75ae2100 --- /dev/null +++ b/doc/zh_TW/dev_guide/build_features.md @@ -0,0 +1,17 @@ +# `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 new file mode 100644 index 00000000..cf6b624b --- /dev/null +++ b/doc/zh_TW/dev_guide/directories.md @@ -0,0 +1,25 @@ +# Erg存儲表結構 + + +```console + └─┬資產:圖片等 + ├─ CODE_OF_CONDUCT:行為準則 + ├─┬編譯器 + │ ├─ erg_common:通用工具 + │ ├─ erg_compiler + │ └─ erg_parser:解析器 + ├─┬文檔 + │ ├─┬ CN + │ │ ├─ API:Erg標準API + │ │ ├─ 編譯器:關於編譯器實現 + │ │ ├─ dev_guide:開發者和貢獻者指南 + │ │ ├─ python:Erg開發必備的Python知識 + │ │ ├─ 語法:Erg語法 + │ │ └─ 工具:Erg命令行工具 + │ └─┬ JA + │ ... + ├─ 示例:示例代碼 + ├─ library:Erg腳本庫 + ├─ src:main.rs和驅動所在目錄 + └─ tests:測試代碼 +``` \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/doc_guideline.md b/doc/zh_TW/dev_guide/doc_guideline.md new file mode 100644 index 00000000..ac75168a --- /dev/null +++ b/doc/zh_TW/dev_guide/doc_guideline.md @@ -0,0 +1,13 @@ +# 格式 + +所有不符合以下規則的文檔都是修正的對象。 + +* 代碼註釋或內部文檔以這種方式編寫。 +* 向外部(普通用戶)展示的文檔要用簡單易懂的語言書寫。 +* 文檔中首次出現的術語必須同時記錄定義、含義或鏈接。 +* ()作為補充,僅用於理解正文所必需的句子,而非理解正文所必需的句子則使用腳註。 +* 如果文檔內容過期,則根據進行更新。 + +--- + +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 new file mode 100644 index 00000000..4f65afa3 --- /dev/null +++ b/doc/zh_TW/dev_guide/env.md @@ -0,0 +1,19 @@ +# 開發環境 + +## 需要安裝的內容 + +* 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 new file mode 100644 index 00000000..9ee8c3a7 --- /dev/null +++ b/doc/zh_TW/dev_guide/faq_syntax.md @@ -0,0 +1,108 @@ +# 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 試圖用類來控制一切一樣。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/i18n_messages.md b/doc/zh_TW/dev_guide/i18n_messages.md new file mode 100644 index 00000000..08e9b807 --- /dev/null +++ b/doc/zh_TW/dev_guide/i18n_messages.md @@ -0,0 +1,55 @@ +# Multilingualization of Messages + +Erg 正在推動消息(開始、選項、文檔、提示、警告、錯誤消息等)的多語言化。如果你不熟悉 Rust 或 Erg,也可以參與此項目。請務必配合。 + +以下是多語種方法的說明。 + +## 查找 + +在 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"), +), +``` + +另外,英語是默認設置,一定要排在最後。部分是 Rust 的格式化功能,允許你將變量的內容()嵌入到字符串中。 + +## Build + +現在,我們使用選項構建它。 + +screenshot_i18n_messages + +你做到了! + +## FAQ + +Q:像這樣的指定是什麼意思? A:{RED} 及更高版本將顯示為紅色。重新啟動交互渲染。 + +Q:如果想添加自己的語言,該如何替換部分?答:目前支持以下語言。 + +* english(默認設置) +* 日語。 +* 簡體中文 +* 繁體中文 + +如果你想添加其他語言,請提出請求。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/index.md b/doc/zh_TW/dev_guide/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/dev_guide/rust_code_guideline.md b/doc/zh_TW/dev_guide/rust_code_guideline.md new file mode 100644 index 00000000..9ce19cfd --- /dev/null +++ b/doc/zh_TW/dev_guide/rust_code_guideline.md @@ -0,0 +1,23 @@ +# 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 new file mode 100644 index 00000000..0969124e --- /dev/null +++ b/doc/zh_TW/dev_guide/terms.md @@ -0,0 +1,831 @@ +# 術語詞典 + +## 符號 + +### ! + +過程或附加在標識符末尾的標記,以指示其為可變類型。或者變量運算符。 + +### ../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 new file mode 100644 index 00000000..0c033c90 --- /dev/null +++ b/doc/zh_TW/dev_guide/unify_terms.md @@ -0,0 +1,80 @@ +# 術語統一 + +## 可見性、可見性 + +使用“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 new file mode 100644 index 00000000..5e522c54 --- /dev/null +++ b/doc/zh_TW/faq_general.md @@ -0,0 +1,27 @@ +# 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 new file mode 100644 index 00000000..015fc33c --- /dev/null +++ b/doc/zh_TW/faq_technical.md @@ -0,0 +1,25 @@ +# 技術常見問題解答 + +本節回答了使用 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 new file mode 100644 index 00000000..b65b999c --- /dev/null +++ b/doc/zh_TW/improved_points.md @@ -0,0 +1,46 @@ +# 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 new file mode 100644 index 00000000..de23b5dc --- /dev/null +++ b/doc/zh_TW/index.md @@ -0,0 +1,25 @@ +# 指數 + +## [API/](./API/index.md) + + 描述 Erg 的內置或標準庫提供的子程序、類型、常量等的規範。 + +## [compiler/](./compiler/index.md) + + 解釋了 Erg 編譯器(厘米)的設計。 + +## [dev_guide/](./dev_guide/index.md) + + 項目的開發方針、貢獻方式等進行了說明。 + +## [python/](./python/index.md) + + 解釋了開發 Erg 所需的 Python 知識。 + +## [syntax/](./syntax/00_basic.md) + + Erg語法解釋。 + +## [tools/](./tools/index.md) + + Erg的外圍工具,如何使用命令選項等進行了說明。 \ No newline at end of file diff --git a/doc/zh_TW/migration_from_py.md b/doc/zh_TW/migration_from_py.md new file mode 100644 index 00000000..e01a174e --- /dev/null +++ b/doc/zh_TW/migration_from_py.md @@ -0,0 +1,28 @@ +# 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 new file mode 100644 index 00000000..fad39b15 --- /dev/null +++ b/doc/zh_TW/python/bytecode_instructions.md @@ -0,0 +1,106 @@ +# 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 new file mode 100644 index 00000000..16bdccf4 --- /dev/null +++ b/doc/zh_TW/python/bytecode_specification.md @@ -0,0 +1,70 @@ +# 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 new file mode 100644 index 00000000..8402fb32 --- /dev/null +++ b/doc/zh_TW/python/class_system.md @@ -0,0 +1,95 @@ +# 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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/syntax/00_basic.md b/doc/zh_TW/syntax/00_basic.md new file mode 100644 index 00000000..2749429e --- /dev/null +++ b/doc/zh_TW/syntax/00_basic.md @@ -0,0 +1,121 @@ +# 基本信息 + +> :此文檔尚未完成。未進行校樣(文體、正確鏈接等)。此外,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 new file mode 100644 index 00000000..5a0e8efc --- /dev/null +++ b/doc/zh_TW/syntax/01_literal.md @@ -0,0 +1,165 @@ +# 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 new file mode 100644 index 00000000..95807647 --- /dev/null +++ b/doc/zh_TW/syntax/02_name.md @@ -0,0 +1,169 @@ +# 變量 + +變量是代數的一種。 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 new file mode 100644 index 00000000..7bb1a7e2 --- /dev/null +++ b/doc/zh_TW/syntax/03_declaration.md @@ -0,0 +1,48 @@ +# 聲明 + +聲明是指定要使用的變量類型的語法。可以在代碼中的任何地方聲明,但不能只聲明變量。必須始終初始化。賦值後聲明可以檢查類型是否與賦值對象匹配。 + + +```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 new file mode 100644 index 00000000..3d555b66 --- /dev/null +++ b/doc/zh_TW/syntax/04_function.md @@ -0,0 +1,306 @@ +# 函數 + +函數是一個塊,它接受參數並對其進行處理,然後將其作為返回值返回。定義如下。 + + +```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 new file mode 100644 index 00000000..5b281cd1 --- /dev/null +++ b/doc/zh_TW/syntax/05_builtin_funcs.md @@ -0,0 +1,52 @@ +# 內置函數 + +## 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 new file mode 100644 index 00000000..d3314cfd --- /dev/null +++ b/doc/zh_TW/syntax/06_operator.md @@ -0,0 +1,30 @@ +# 運算符 + +運算符(操作符)是表示運算的符號。運算符(操作數)位於運算符的右側(左),在 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 new file mode 100644 index 00000000..c3bedc5b --- /dev/null +++ b/doc/zh_TW/syntax/07_side_effect.md @@ -0,0 +1,123 @@ +# 副作用和過程 + +到目前為止,我一直沒有解釋中的含義,現在我終於明白了它的含義。這個!直截了當地表示此對像是具有“副作用”的“過程”。過程對函數產生了一種稱為“副作用”的效果。 + + +```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 new file mode 100644 index 00000000..4a2ca07a --- /dev/null +++ b/doc/zh_TW/syntax/08_procedure.md @@ -0,0 +1,12 @@ +# 過程 + +處理可變對象時需要過程,但如果變量對像是參數,則不一定是過程。 + + +```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 new file mode 100644 index 00000000..f6eda744 --- /dev/null +++ b/doc/zh_TW/syntax/09_builtin_procs.md @@ -0,0 +1,13 @@ +# 內置過程 + +## 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 new file mode 100644 index 00000000..33e7e557 --- /dev/null +++ b/doc/zh_TW/syntax/10_array.md @@ -0,0 +1,56 @@ +# 排列 + +數組是最基本的。集合是可以在內部包含多個對象的對象。 + + +```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 new file mode 100644 index 00000000..96f03ab0 --- /dev/null +++ b/doc/zh_TW/syntax/11_tuple.md @@ -0,0 +1,125 @@ +# 元 + +元組類似於數組,但可以包含不同類型的對象。這樣的收藏稱為非等質收藏。與此相對,等質集合包括數組和集合。 + + +```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 new file mode 100644 index 00000000..96e4b68e --- /dev/null +++ b/doc/zh_TW/syntax/12_dict.md @@ -0,0 +1,71 @@ +# 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 new file mode 100644 index 00000000..aa8d34c2 --- /dev/null +++ b/doc/zh_TW/syntax/13_record.md @@ -0,0 +1,198 @@ +# 記錄 + +記錄是一個集合,它具有通過鍵訪問的 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 new file mode 100644 index 00000000..66a36c46 --- /dev/null +++ b/doc/zh_TW/syntax/14_set.md @@ -0,0 +1,50 @@ +# 集 + +集代表一個集合,在數據結構上是重複的、沒有順序的數組。 + + +```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 new file mode 100644 index 00000000..2f08bdda --- /dev/null +++ b/doc/zh_TW/syntax/15_type.md @@ -0,0 +1,7 @@ +# 類型 + +類型在 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 new file mode 100644 index 00000000..d5c9fe04 --- /dev/null +++ b/doc/zh_TW/syntax/16_iterator.md @@ -0,0 +1,91 @@ +# 迭 + +迭代器是用於檢索容器元素的對象。 + + +```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 new file mode 100644 index 00000000..b62f159b --- /dev/null +++ b/doc/zh_TW/syntax/17_mutability.md @@ -0,0 +1,92 @@ +# 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 new file mode 100644 index 00000000..593217cc --- /dev/null +++ b/doc/zh_TW/syntax/18_ownership.md @@ -0,0 +1,103 @@ +# 所有權制度 + +由於 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 new file mode 100644 index 00000000..1d85abb1 --- /dev/null +++ b/doc/zh_TW/syntax/19_visibility.md @@ -0,0 +1,199 @@ +# 可見性(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 new file mode 100644 index 00000000..5d861f95 --- /dev/null +++ b/doc/zh_TW/syntax/20_naming_rule.md @@ -0,0 +1,52 @@ +# 命名規則 + +如果要將變量用作常量表達式,則必須以大寫字母開頭。兩個以上的字符可以是小寫的。 + + +```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 new file mode 100644 index 00000000..2ca47413 --- /dev/null +++ b/doc/zh_TW/syntax/21_lambda.md @@ -0,0 +1,102 @@ +# 匿名函數(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 new file mode 100644 index 00000000..1ab1aa7c --- /dev/null +++ b/doc/zh_TW/syntax/22_subroutine.md @@ -0,0 +1,65 @@ +# 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 new file mode 100644 index 00000000..375eb459 --- /dev/null +++ b/doc/zh_TW/syntax/23_closure.md @@ -0,0 +1,99 @@ +# 封閉 + +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 new file mode 100644 index 00000000..428dd179 --- /dev/null +++ b/doc/zh_TW/syntax/24_module.md @@ -0,0 +1,47 @@ +# 模塊 + +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 new file mode 100644 index 00000000..eb944a02 --- /dev/null +++ b/doc/zh_TW/syntax/25_object_system.md @@ -0,0 +1,77 @@ +# 對象 + +可以分配給變量的所有數據。類具有以下屬性。 + +* :返回對象的(非富)字符串表示法 +* :返回對象的大小(包括堆保留量) +* :返回對象屬性的列表 +* :返回對象的散列值 +* :檢索並返回對象的屬性 +* :生成並返回對象的克隆(在內存中有獨立實體) +* :返回對象的副本(在內存中指向相同的對象) + +## 記錄 + +以記錄文字()生成的對象。此對象具有基本方法,如。 + + +```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 new file mode 100644 index 00000000..9924c37d --- /dev/null +++ b/doc/zh_TW/syntax/26_pattern_matching.md @@ -0,0 +1,203 @@ +# 模式匹配,可辯駁性 + +## 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 new file mode 100644 index 00000000..6c2b720b --- /dev/null +++ b/doc/zh_TW/syntax/27_comprehension.md @@ -0,0 +1,65 @@ +# 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 new file mode 100644 index 00000000..5076a9b8 --- /dev/null +++ b/doc/zh_TW/syntax/28_spread_syntax.md @@ -0,0 +1,45 @@ +# 展開分配 + +在分解賦值中,如果在變量之前放置,則所有剩餘元素都可以擴展到該變量。這稱為部署賦值。 + + +```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 new file mode 100644 index 00000000..7d39975f --- /dev/null +++ b/doc/zh_TW/syntax/29_decorator.md @@ -0,0 +1,124 @@ +# 裝飾器(修飾符) + +裝飾器用於將特定的狀態和行為添加到類型和函數中,或將其顯式。裝飾師的語法如下。 + + +```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 new file mode 100644 index 00000000..bf036273 --- /dev/null +++ b/doc/zh_TW/syntax/30_error_handling.md @@ -0,0 +1,106 @@ +# 錯誤處理系統 + +主要使用 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 new file mode 100644 index 00000000..ea8514d2 --- /dev/null +++ b/doc/zh_TW/syntax/31_pipeline.md @@ -0,0 +1,32 @@ +# 流水線運算符 + +按如下方式使用管線運算符。 + + +```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 new file mode 100644 index 00000000..4750706e --- /dev/null +++ b/doc/zh_TW/syntax/32_integration_with_Python.md @@ -0,0 +1,87 @@ +# 與 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 new file mode 100644 index 00000000..e7ecd528 --- /dev/null +++ b/doc/zh_TW/syntax/33_package_system.md @@ -0,0 +1,83 @@ +# 包裝系統 + +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 new file mode 100644 index 00000000..567b8087 --- /dev/null +++ b/doc/zh_TW/syntax/34_generator.md @@ -0,0 +1,37 @@ +# 發電機 + +生成器是在塊中使用過程的特殊過程。 + + +```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 new file mode 100644 index 00000000..774c354b --- /dev/null +++ b/doc/zh_TW/syntax/SUMMARY.md @@ -0,0 +1,69 @@ +# 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 new file mode 100644 index 00000000..ff8463fe --- /dev/null +++ b/doc/zh_TW/syntax/container_ownership.md @@ -0,0 +1,42 @@ +# 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 new file mode 100644 index 00000000..d9dbbb2a --- /dev/null +++ b/doc/zh_TW/syntax/grammar.txt @@ -0,0 +1,88 @@ +# 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 new file mode 100644 index 00000000..1a8dc93a --- /dev/null +++ b/doc/zh_TW/syntax/indexes.md @@ -0,0 +1,452 @@ +# 指數 + +有關不在此索引中的 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 new file mode 100644 index 00000000..2a69a835 --- /dev/null +++ b/doc/zh_TW/syntax/quick_tour.md @@ -0,0 +1,287 @@ +# 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 new file mode 100644 index 00000000..c6b1980f --- /dev/null +++ b/doc/zh_TW/syntax/type/01_type_system.md @@ -0,0 +1,224 @@ +# 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 new file mode 100644 index 00000000..9e1eec51 --- /dev/null +++ b/doc/zh_TW/syntax/type/02_basic.md @@ -0,0 +1,170 @@ +# 類型的基本語法 + +## 類型指定 + +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 new file mode 100644 index 00000000..721d341e --- /dev/null +++ b/doc/zh_TW/syntax/type/03_trait.md @@ -0,0 +1,193 @@ +# 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 new file mode 100644 index 00000000..c682d8a3 --- /dev/null +++ b/doc/zh_TW/syntax/type/04_class.md @@ -0,0 +1,285 @@ +# 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 new file mode 100644 index 00000000..d1712019 --- /dev/null +++ b/doc/zh_TW/syntax/type/05_inheritance.md @@ -0,0 +1,248 @@ +# 繼承(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 new file mode 100644 index 00000000..f53a5a5f --- /dev/null +++ b/doc/zh_TW/syntax/type/06_nst_vs_sst.md @@ -0,0 +1,43 @@ +# 記名的部分型 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 new file mode 100644 index 00000000..abc426ba --- /dev/null +++ b/doc/zh_TW/syntax/type/07_patch.md @@ -0,0 +1,223 @@ +# 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 new file mode 100644 index 00000000..1298ed20 --- /dev/null +++ b/doc/zh_TW/syntax/type/08_value.md @@ -0,0 +1,38 @@ +# 值類型(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 new file mode 100644 index 00000000..0a833803 --- /dev/null +++ b/doc/zh_TW/syntax/type/09_attributive.md @@ -0,0 +1,7 @@ +# 屬性類型(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 new file mode 100644 index 00000000..dd672739 --- /dev/null +++ b/doc/zh_TW/syntax/type/10_interval.md @@ -0,0 +1,39 @@ +# 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 new file mode 100644 index 00000000..aa876cbe --- /dev/null +++ b/doc/zh_TW/syntax/type/11_enum.md @@ -0,0 +1,86 @@ +# 枚舉類型 + +“枚舉類型”(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 new file mode 100644 index 00000000..e0107967 --- /dev/null +++ b/doc/zh_TW/syntax/type/12_refinement.md @@ -0,0 +1,75 @@ +# 篩子類型(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 new file mode 100644 index 00000000..fde83734 --- /dev/null +++ b/doc/zh_TW/syntax/type/13_algebraic.md @@ -0,0 +1,82 @@ +# 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 new file mode 100644 index 00000000..d5b8afe0 --- /dev/null +++ b/doc/zh_TW/syntax/type/14_dependent.md @@ -0,0 +1,76 @@ +# 依賴關係 + +依賴性可以說是 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 new file mode 100644 index 00000000..7d7ab552 --- /dev/null +++ b/doc/zh_TW/syntax/type/15_quantified.md @@ -0,0 +1,288 @@ +# 類型變量,量化 + +類型變量是用於指定子例程參數類型的變量,並指示其類型是可選的(非單相)。首先,作為引入類型變量的動機,讓我們考慮返回輸入的函數。 + + +```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 new file mode 100644 index 00000000..7b2779ad --- /dev/null +++ b/doc/zh_TW/syntax/type/16_subtyping.md @@ -0,0 +1,80 @@ +# 部分定型 + +在 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 new file mode 100644 index 00000000..d2bb27b3 --- /dev/null +++ b/doc/zh_TW/syntax/type/17_type_casting.md @@ -0,0 +1,74 @@ +# 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 new file mode 100644 index 00000000..04fc609c --- /dev/null +++ b/doc/zh_TW/syntax/type/18_mut.md @@ -0,0 +1,168 @@ +# 可變類型(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 new file mode 100644 index 00000000..38d5c841 --- /dev/null +++ b/doc/zh_TW/syntax/type/19_bound.md @@ -0,0 +1,16 @@ +# 類型邊界(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 new file mode 100644 index 00000000..813d14b8 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced.md @@ -0,0 +1 @@ +以後將進一步解說高級型系統。入門的朋友不看所有的條款也沒問題。 \ 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 new file mode 100644 index 00000000..f7aa9bf2 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/GADTs.md @@ -0,0 +1,68 @@ +# 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 new file mode 100644 index 00000000..fc01a53c --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/_rank2type.md @@ -0,0 +1,142 @@ +# 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 new file mode 100644 index 00000000..ac32598b --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/default_param.md @@ -0,0 +1,28 @@ +# 具有默認參數的函數類型 + +首先,看默認自變量的使用例。 + + +```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 new file mode 100644 index 00000000..666d477c --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/erasure.md @@ -0,0 +1,45 @@ +# 類型擦除(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 new file mode 100644 index 00000000..bdc1cc36 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/existential.md @@ -0,0 +1,39 @@ +# 存在類型 + +如果有對應於應有盡有的全稱型,那麼自然會有對應於應有盡有的存在型。存在型並不難。只是你沒有這樣的意識,就已經知道了你的存在型。 + + +```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 new file mode 100644 index 00000000..b3ba4c6e --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/keyword_param.md @@ -0,0 +1,26 @@ +# 關鍵字參數函數類型 + + +```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 new file mode 100644 index 00000000..cbc76120 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/kind.md @@ -0,0 +1,157 @@ +# 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 new file mode 100644 index 00000000..45ee62dd --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/marker_trait.md @@ -0,0 +1,33 @@ +# 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 new file mode 100644 index 00000000..ca40b905 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/mut_struct.md @@ -0,0 +1,40 @@ +# 可變結構類型 + +型是可以插入任意的型對象進行替換的箱型。 + + +```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 new file mode 100644 index 00000000..05bca287 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/newtype.md @@ -0,0 +1,31 @@ +# 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 new file mode 100644 index 00000000..86080fb5 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/overloading.md @@ -0,0 +1,91 @@ +# 過載 + +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 new file mode 100644 index 00000000..3c6d3c46 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/phantom.md @@ -0,0 +1,58 @@ +# 幽靈類型(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 new file mode 100644 index 00000000..62566b77 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/projection.md @@ -0,0 +1,25 @@ +# 投影類型 + +投影類型表示以下代碼中類似於的類型。 + + +```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 new file mode 100644 index 00000000..ef0ea90c --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/quantified_dependent.md @@ -0,0 +1,30 @@ +# 量化依賴性 + +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 new file mode 100644 index 00000000..5fa83b6e --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/shared.md @@ -0,0 +1,72 @@ +# 共享引用(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 new file mode 100644 index 00000000..c0d32308 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/special.md @@ -0,0 +1,54 @@ +# 特殊類型(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 new file mode 100644 index 00000000..075c6b74 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/typeof.md @@ -0,0 +1,61 @@ +# 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 new file mode 100644 index 00000000..37ba9f9e --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/variance.md @@ -0,0 +1,128 @@ +# 退化(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 new file mode 100644 index 00000000..1cb10b38 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/widening.md @@ -0,0 +1,93 @@ +# 類型擴展(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 new file mode 100644 index 00000000..189c8d0e --- /dev/null +++ b/doc/zh_TW/tips.md @@ -0,0 +1,142 @@ +# 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 new file mode 100644 index 00000000..bb87c146 --- /dev/null +++ b/doc/zh_TW/tools/build.md @@ -0,0 +1,13 @@ +# 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 new file mode 100644 index 00000000..f1dfa9ac --- /dev/null +++ b/doc/zh_TW/tools/env.md @@ -0,0 +1,3 @@ +# 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 new file mode 100644 index 00000000..654c1b18 --- /dev/null +++ b/doc/zh_TW/tools/fmt.md @@ -0,0 +1,5 @@ +# 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 new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/tools/install.md b/doc/zh_TW/tools/install.md new file mode 100644 index 00000000..669093d5 --- /dev/null +++ b/doc/zh_TW/tools/install.md @@ -0,0 +1,9 @@ +# 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 new file mode 100644 index 00000000..97f4fc64 --- /dev/null +++ b/doc/zh_TW/tools/pack.md @@ -0,0 +1,82 @@ +# 包管理器 + +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 new file mode 100644 index 00000000..4a5267dc --- /dev/null +++ b/doc/zh_TW/tools/repl.md @@ -0,0 +1,15 @@ +# REPL + +如果命令沒有參數,則會調用 REPL。你也可以使用子命令啟動它。還可以指定以下標誌。 + +* typed:顯示對象及其類型。 + + +```console +$ erg repl --typed +Erg interpreter ... (tags/?:, ...) on ... +>>> 1 +1: {1} +>>> id x = x +id = : |T: Type| T -> T +``` \ No newline at end of file diff --git a/doc/zh_TW/tools/test.md b/doc/zh_TW/tools/test.md new file mode 100644 index 00000000..eb9d4ce0 --- /dev/null +++ b/doc/zh_TW/tools/test.md @@ -0,0 +1,43 @@ +# 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 From a711efa99b325ba1012f6897e7b0e2bdb947d8a1 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 4 Sep 2022 10:26:13 +0900 Subject: [PATCH 03/42] Correct omissions and errors in translation --- doc/EN/compiler/architecture.md | 7 ++--- doc/EN/dev_guide/branches.md | 2 -- doc/EN/dev_guide/directories.md | 2 +- doc/EN/dev_guide/unify_terms.md | 40 +++------------------------ doc/JA/compiler/architecture.md | 41 +++++++++++++--------------- doc/JA/compiler/parsing.md | 2 +- doc/JA/dev_guide/branches.md | 8 ++++-- doc/JA/dev_guide/i18n_messages.md | 4 +-- doc/zh_CN/compiler/architecture.md | 11 +++----- doc/zh_CN/dev_guide/branches.md | 8 ++++-- doc/zh_CN/dev_guide/directories.md | 17 ++++++------ doc/zh_CN/dev_guide/faq_syntax.md | 4 +-- doc/zh_CN/dev_guide/i18n_messages.md | 18 ++++++------ doc/zh_TW/compiler/architecture.md | 11 +++----- doc/zh_TW/dev_guide/branches.md | 10 +++++-- doc/zh_TW/dev_guide/directories.md | 17 ++++++------ doc/zh_TW/dev_guide/faq_syntax.md | 5 ++-- doc/zh_TW/dev_guide/i18n_messages.md | 20 +++++++------- 18 files changed, 94 insertions(+), 133 deletions(-) diff --git a/doc/EN/compiler/architecture.md b/doc/EN/compiler/architecture.md index 78d5e5a5..525068ed 100644 --- a/doc/EN/compiler/architecture.md +++ b/doc/EN/compiler/architecture.md @@ -2,12 +2,12 @@ ## 1. Scan an Erg script (.er) and generate a `TokenStream` (parser/lex.rs) -* parser/lexer/Lexer generates `TokenStream` (this is an iterator of Token, TokenStream can be generated by lexer.collect()) +* parser/lexer/Lexer generates `TokenStream` (this is an iterator of `Token`, `TokenStream` can be generated by `Lexer::collect()`) * `Lexer` is constructed from `Lexer::new` or `Lexer::from_str`, where `Lexer::new` reads the code from a file or command option. * `Lexer` can generate tokens sequentially as an iterator; if you want to get a `TokenStream` all at once, use `Lexer::lex`. * `Lexer` outputs `LexError`s as errors, but `LexError` does not have enough information to display itself. If you want to display the error, use the `LexerRunner` to convert the error. * `LexerRunner` can also be used if you want to use `Lexer` as standalone; `Lexer` is just an iterator and does not implement the `Runnable` trait. - * `Runnable` is implemented by `LexerRunner`, `ParserRunner`, `Compiler`, and `VirtualMachine`. + * `Runnable` is implemented by `LexerRunner`, `ParserRunner`, `Compiler`, and `DummyVM`. ## 2. Convert `TokenStream` -> `AST` (parser/parse.rs) @@ -22,7 +22,6 @@ ## 3. Type checking & inference, Convert `AST` -> `HIR` (compiler/lower.rs) * `HIR` has every variable's type information. It is for "High-level Intermediate Representation". -* `HIR` only holds the type of the variable, but that's enough. In extreme cases, this is because Erg has only conversion (or operator) applications. If we know the type of the conversion, we have already know the type of the object of the argument. * `ASTLowerer` can be constructed in the same way as `Parser` and `Lexer`. * `ASTLowerer::lower` will output a tuple of `HIR` and `CompileWarnings` if no errors occur. * `ASTLowerer` is owned by `Compiler`. Unlike conventional structures, `ASTLowerer` handles code contexts and is not a one-time disposable. @@ -34,8 +33,6 @@ ## 5. Generate Bytecode (`CodeObj`) from `HIR` (compiler/codegen.rs) -* From the type information of the expression, name resolution of the quantified subroutines will be performed. - ## (6. (Future plans) Convert Bytecode -> LLVM IR) * Bytecode is stack-based, whereas LLVM IR is register-based. diff --git a/doc/EN/dev_guide/branches.md b/doc/EN/dev_guide/branches.md index 236036e7..ca0a2bdf 100644 --- a/doc/EN/dev_guide/branches.md +++ b/doc/EN/dev_guide/branches.md @@ -1,7 +1,5 @@ # Branch naming and operation policy -* Basically, development is done in one `main` branch (monorepo development). Create a `feature-*` branch or `issue-*` branch only when it is difficult to work without branching. - ## main * main development branch diff --git a/doc/EN/dev_guide/directories.md b/doc/EN/dev_guide/directories.md index 998b482a..137b979a 100644 --- a/doc/EN/dev_guide/directories.md +++ b/doc/EN/dev_guide/directories.md @@ -21,4 +21,4 @@ ├─ library: Erg script library ├─ src: directory where main.rs and driver are placed └─ tests: test code -``` \ No newline at end of file +``` diff --git a/doc/EN/dev_guide/unify_terms.md b/doc/EN/dev_guide/unify_terms.md index 4ef35c31..02806bf1 100644 --- a/doc/EN/dev_guide/unify_terms.md +++ b/doc/EN/dev_guide/unify_terms.md @@ -4,35 +4,9 @@ Use Visibility. -## Complement (negative type, complementary type) - -Use negative types. The result of Complement is not necessarily Not type. - -## Diff (difference type, exclusion type, direct difference type) - -Use exclusion types. The result of Diff is not always Not type. - -## Intersection (intersection type, intersection type, Cartesian product type) - -Use intersection types. Do not use Cartesian product types. This is because there is also a usage that regards a tuple as a Cartesian product type. -However, from the point of view of attribute subtyping, it is essentially equivalent to Erg's And type. -Also, the result of Intersection is not necessarily And type. For example `{1, 2, 3} and {1, 2} == {1, 2}`. - -## Translation of Nominal subtyping - -There are nominal/nominal/nominal subtyping, but use nominal subtyping. - -## Ratio type translation - -Use rational numbers. Since Float is provided separately, it is not called a floating-point number type. - -## Union - -Use a union type. The result of Union is not necessarily Or type. - ## Type bound, Type constraint -A list of predicate expressions given to quantified and sieve types. Use type bounds. +A list of predicate expressions given to quantified and refinement types. Use type bounds. ## subroutines, routines, subprograms @@ -65,24 +39,18 @@ However, in general, `v` with `v = 1` is called "Variable v", and `C` with `C = ## Attribute, Field, Property -Attribute, use attributes. -By the way, a record is a function that can define an object with element attributes without a class. +Use attributes. By the way, a record is a function that can define an object with element attributes without a class. ## Application, Call Giving arguments to a subroutine object and getting a result. -Use Call. This is because Application has a usage of "applied software". +Use Call. This is because Application has a usage of "application software". ## Array, List 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. -## procedures, procedures - -Standardize on procedures. Subroutine is a generic term for functions (and operators), procedures and methods. Callable is also anything that implements `__call__`. - -## lambda functions, lambda expressions, anonymous functions, anonymous functions +## lambda functions, lambda expressions, anonymous functions Unify with anonymous functions. In English, Lambda can be used to shorten the number of characters, but the official name is Anonymous function. -Also, Erg's anonymous functions are not anonymous, so we don't use them. \ No newline at end of file diff --git a/doc/JA/compiler/architecture.md b/doc/JA/compiler/architecture.md index 971362c4..bbed005d 100644 --- a/doc/JA/compiler/architecture.md +++ b/doc/JA/compiler/architecture.md @@ -1,32 +1,31 @@ # ergc のアーキテクチャ -## 1. Erg スクリプト (.er) をスキャンし、`TokenStream` (parser/lex.rs) を生成します +## 1. Erg スクリプト (.er) をスキャンし、`TokenStream` (parser/lex.rs) を生成する -* parser/lexer/Lexer は `TokenStream` を生成します (これは Token のイテレータです。TokenStream は lexer.collect() によって生成できます) - * `Lexer` は `Lexer::new` または `Lexer::from_str` から構築されます。`Lexer::new` はファイルまたはコマンド オプションからコードを読み取ります。 - ※ Lexer はイテレータとしてトークンを順次生成できるので、一度に TokenStream を取得したい場合は Lexer::lex を使う。 - * `Lexer` は `LexError` をエラーとして出力しますが、`LexError` 自体には表示するだけの情報がありません。エラーを表示したい場合は、`LexerRunner` を使用してエラーを変換します。 - * `Lexer` をスタンドアロンとして使用する場合は、`LexerRunner` も使用できます。`Lexer` は単なるイテレータであり、`Runnable` トレイトを実装していません。 - * Runnable は、 LexerRunner 、 ParserRunner 、 Compiler 、および VirtualMachine によって実装されます。 +* 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) +## 2. `TokenStream` -> `AST` (parser/parse.rs) -* `Parser` は `Lexer` と同様に `Parser::new` と `Parser::from_str` の 2 つのコンストラクタを持ち、`Parser::parse` は `AST` を返します。 -※`AST`は`Vec`のラッパー型で、「抽象構文木」用です。 +* `Parser` は `Lexer` と同様に `Parser::new` と `Parser::from_str` の 2 つのコンストラクタを持ち、`Parser::parse` は `AST` を返す。 +* `AST`は`Vec`のラッパー型で、「抽象構文木」を表す。 ### 2.5 `AST`の脱糖 * ネストされた変数を展開 (`Desugarer::desugar_nest_vars_pattern`) -* desugar 複数パターン定義構文 (`Desugarer::desugar_multiple_pattern_def`) +* 複数パターン定義構文をmatchへ変換 (`Desugarer::desugar_multiple_pattern_def`) ## 3. 型チェックと推論、 `AST` -> `HIR` を変換 (compiler/lower.rs) -* `HIR` は、すべての変数の型情報を持っています. これは、「高レベルの中間表現」用です. -* `HIR` は変数の型しか保持していないが、それで十分. 極端な場合、これは Erg が変換 (または演算子) のアプリケーションしか持たないためです. 変換の型がわかれば、変数の型もわかっています.引数のオブジェクト。 -※ ASTLowerer は Parser や Lexer と同じように構築できます。 -* `ASTLowerer::lower` は、エラーが発生しなければ、`HIR` と `CompileWarnings` のタプルを出力します。 -* `ASTLowerer` は `Compiler` によって所有されています. `ASTLowerer` は従来の構造体とは異なり、コード コンテキストを処理し、1 回限りの使い捨てではありません。 -※型推論の結果が不完全な場合(未知の型変数がある場合)、名前解決時にエラーが発生します。 +* `HIR` は、すべての変数の型情報を持っており、「高レベルの中間表現」を表す。 +* `ASTLowerer は Parser や Lexer と同じように構築できる。 +* `ASTLowerer::lower` は、エラーが発生しなければ、`HIR` と `CompileWarnings` のタプルを出力する。 +* `ASTLowerer` は `Compiler` によって所有されている。 `ASTLowerer` は従来の構造体とは異なり、文脈を保持し、1 回限りの使い捨てではない。 +* 型推論の結果が不完全な場合(未知の型変数がある場合)、名前解決時にエラーが発生する。 ## 4. 副作用のチェック (compiler/effectcheck.rs) @@ -34,9 +33,7 @@ ## 5. `HIR` からバイトコード (`CodeObj`) を生成 (compiler/codegen.rs) -※式の型情報から、量化されたサブルーチンの名前解決を行います。 +## (6. (今後の予定) バイトコード -> LLVM IR) -## (6. (今後の予定) バイトコード変換 -> LLVM IR) - -* バイトコードはスタックベースですが、LLVM IR はレジスタベースです。 - この変換プロセスには、さらにいくつかの中間プロセスのレイヤーがあります。 \ No newline at end of file +* バイトコードはスタックベースだが、LLVM IR はレジスタベースである。 + この変換プロセスには、さらにいくつかの中間プロセスのレイヤーが必要となる。 diff --git a/doc/JA/compiler/parsing.md b/doc/JA/compiler/parsing.md index 47811ebb..aa6ed05c 100644 --- a/doc/JA/compiler/parsing.md +++ b/doc/JA/compiler/parsing.md @@ -6,7 +6,7 @@ Ergの文法において特異なのは、space-sensitive(空白による区別 これは、`()`の省略による表現力の低下を補うためである。同様の文法は同じく`()`を省略可能なNimでも見られる。 ```erg -f + 1 == f(+1) +f +1 == f(+1) f + 1 == `+`(f, 1) f (1,) == f((1,)) f(1,) == f(1) diff --git a/doc/JA/dev_guide/branches.md b/doc/JA/dev_guide/branches.md index c8eeb9a1..84fc128b 100644 --- a/doc/JA/dev_guide/branches.md +++ b/doc/JA/dev_guide/branches.md @@ -1,7 +1,5 @@ # ブランチの命名と運用方針 -* 基本的に開発は`main`ブランチ一本で行う(モノレポ開発)。どうしてもブランチを切らないと作業しにくい場合のみ`feature-*`ブランチか`issue-*`ブランチを作成する。 - ## main * メイン開発ブランチ @@ -29,3 +27,9 @@ * 特定のissueを解決するブランチ * 条件なし + +## fix-* + +* 特定のバグを解決するブランチ(issueがバグの場合に、`issue-*`の代わりに作成する) + +* 条件なし diff --git a/doc/JA/dev_guide/i18n_messages.md b/doc/JA/dev_guide/i18n_messages.md index 675d3f3d..51fd8fb5 100644 --- a/doc/JA/dev_guide/i18n_messages.md +++ b/doc/JA/dev_guide/i18n_messages.md @@ -1,4 +1,4 @@ -# Multilingualization of Messages +# メッセージの多言語化 Ergはメッセージ(スタート、オプション、ドキュメント、ヒント、警告、エラーメッセージなど)の多言語化を進めています。 このプロジェクトは、RustやErgの詳しい知識がなくても参加することができます。ぜひ協力をお願いします。 @@ -34,7 +34,7 @@ switch_lang!( なお、英語はデフォルトであり、必ず最後に来るようにします。 `{name}` の部分は Rust のフォーマット機能で、変数の内容 (`name`) を文字列に埋め込むことができます。 -## Build +## ビルド では、`--features simplified_chinese` オプションを付けてビルドしてみましょう。 diff --git a/doc/zh_CN/compiler/architecture.md b/doc/zh_CN/compiler/architecture.md index 1088dbce..aca4bc0e 100644 --- a/doc/zh_CN/compiler/architecture.md +++ b/doc/zh_CN/compiler/architecture.md @@ -2,12 +2,12 @@ ## 1. 扫描 Erg 脚本 (.er) 并生成 `TokenStream` (parser/lex.rs) -* parser/lexer/Lexer 生成`TokenStream`(这是一个Token的迭代器,TokenStream可以通过lexer.collect()生成) +* parser/lexer/Lexer 生成`TokenStream`(这是一个`Token`的迭代器,`TokenStream`可以通过`Lexer::collect()`生成) * `Lexer` 由 `Lexer::new` 或 `Lexer::from_str` 构造,其中 `Lexer::new` 从文件或命令选项中读取代码。 * `Lexer` 可以作为迭代器按顺序生成令牌;如果您想一次获得 `TokenStream`,请使用 `Lexer::lex`。 * `Lexer` 输出 `LexError` 为错误,但 `LexError` 没有足够的信息显示自己。如果要显示错误,请使用 `LexerRunner` 转换错误。 * 如果你想单独使用 `Lexer`,也可以使用 `LexerRunner`;`Lexer` 只是一个迭代器,并没有实现 `Runnable` 特性。 - * `Runnable` 由 `LexerRunner`、`ParserRunner`、`Compiler` 和 `VirtualMachine` 实现。 + * `Runnable` 由 `LexerRunner`、`ParserRunner`、`Compiler` 和 `DummyVM` 实现。 ## 2. 转换 `TokenStream` -> `AST` (parser/parse.rs) @@ -22,7 +22,6 @@ ## 3. 类型检查和推断,转换 `AST` -> `HIR` (compiler/lower.rs) * `HIR` 有每个变量的类型信息。它是用于“高级中间表示”的。 -* `HIR` 只保存变量的类型,但这已经足够了。在极端情况下,这是因为 Erg 只有转换(或运算符)应用程序的参数对象。 * `ASTLower` 可以用与`Parser` 和`Lexer` 相同的方式构造。 * 如果没有错误发生,`ASTLowerer::lower` 将输出 `HIR` 和 `CompileWarnings` 的元组。 * `ASTLowerer`归`Compiler`所有。与传统结构不同,`ASTLowerer`处理代码上下文并且不是一次性的。 @@ -34,9 +33,7 @@ ## 5. 从`HIR`(compiler/codegen.rs)生成字节码(`CodeObj`) -* 根据表达式的类型信息,将执行量化子程序的名称解析。 - -##(6.(未来计划)转换字节码 -> LLVM IR) +## (6.(未来计划)转换字节码 -> LLVM IR) * 字节码是基于堆栈的,而 LLVM IR 是基于寄存器的。 - 这个转换过程会多出几层中间过程。 \ 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 0e426275..a7591e0a 100644 --- a/doc/zh_CN/dev_guide/branches.md +++ b/doc/zh_CN/dev_guide/branches.md @@ -1,7 +1,5 @@ # 分支机构命名和运营策略 -* 基本上,开发是在一个分支中进行的(单回购开发)。只有在必须断开分支才能工作的情况下,才创建分支或分支。 - ## main * 主要开发分支 @@ -29,3 +27,9 @@ * 解决特定 issue 的分支 * 没有条件 + +## fix-* + +* 修复特定错误的分支(如果该问题是一个错误,则代替`issue-*`创建)。 + +* 没有条件。 diff --git a/doc/zh_CN/dev_guide/directories.md b/doc/zh_CN/dev_guide/directories.md index 8e5c340e..40947a37 100644 --- a/doc/zh_CN/dev_guide/directories.md +++ b/doc/zh_CN/dev_guide/directories.md @@ -1,25 +1,24 @@ # Erg存储表结构 - ```console - └─┬资产:图片等 + └─┬ assets:图片等 ├─ CODE_OF_CONDUCT:行为准则 - ├─┬编译器 + ├─┬ compiler │ ├─ erg_common:通用工具 │ ├─ erg_compiler │ └─ erg_parser:解析器 - ├─┬文档 + ├─┬ doc: 文档 │ ├─┬ CN │ │ ├─ API:Erg标准API - │ │ ├─ 编译器:关于编译器实现 + │ │ ├─ compiler:关于编译器实现 │ │ ├─ dev_guide:开发者和贡献者指南 │ │ ├─ python:Erg开发必备的Python知识 - │ │ ├─ 语法:Erg语法 - │ │ └─ 工具:Erg命令行工具 + │ │ ├─ syntax:Erg语法 + │ │ └─ tools:Erg命令行工具 │ └─┬ JA │ ... - ├─ 示例:示例代码 + ├─ examples:示例代码 ├─ library:Erg脚本库 ├─ src:main.rs和驱动所在目录 └─ tests:测试代码 -``` \ No newline at end of file +``` diff --git a/doc/zh_CN/dev_guide/faq_syntax.md b/doc/zh_CN/dev_guide/faq_syntax.md index a22cf325..c981fb8b 100644 --- a/doc/zh_CN/dev_guide/faq_syntax.md +++ b/doc/zh_CN/dev_guide/faq_syntax.md @@ -6,8 +6,7 @@ ## 为什么类型参数周围的括号不是 <> 或 []? -因为在和中会发生语法冲突。 - +因为在和中会发生语法冲突。 ```erg # []版 @@ -28,7 +27,6 @@ y = id|Int| # OK Erg 设计为将类型本身也视为值。 - ```erg A = [Int; 3] assert A[2] == Int diff --git a/doc/zh_CN/dev_guide/i18n_messages.md b/doc/zh_CN/dev_guide/i18n_messages.md index 3b1afc5f..9edaeffa 100644 --- a/doc/zh_CN/dev_guide/i18n_messages.md +++ b/doc/zh_CN/dev_guide/i18n_messages.md @@ -4,11 +4,10 @@ Erg 正在推动消息(开始、选项、文档、提示、警告、错误消 以下是多语种方法的说明。 -## 查找 +## 查找`switch_lang!` 在 Erg 源代码中找到(使用 grep 或编辑器的搜索功能)。我们应该能找到下面这样的东西。 - ```rust switch_lang!( "japanese" => format!("この機能({name})はまだ正式に提供されていません"), @@ -20,8 +19,7 @@ switch_lang!( ## 添加消息 -请在查看其他语言内容的同时添加翻译消息。最后不要忘记逗号()。 - +请在查看其他语言内容的同时添加翻译消息。最后不要忘记逗号(,)。 ```rust switch_lang!( @@ -31,7 +29,9 @@ switch_lang!( ), ``` -另外,英语是默认设置,一定要排在最后。部分是 Rust 的格式化功能,允许你将变量的内容()嵌入到字符串中。 +另外,英语是默认设置,一定要排在最后。 + +`{name}`部分是 Rust 的格式化功能,允许你将变量的内容(`name`)嵌入到字符串中。 ## Build @@ -47,9 +47,9 @@ Q:像这样的指定是什么意思?A:{RED} 及更高版本将显示为红 Q:如果想添加自己的语言,该如何替换部分?答:目前支持以下语言。 -* english(默认设置) -* 日语。 -* 简体中文 -* 繁体中文 +* "english"(默认设置) +* "japanese" (日语) +* "simplified_chinese" (简体中文) +* "traditional_chinese" (繁体中文) 如果你想添加其他语言,请提出请求。 diff --git a/doc/zh_TW/compiler/architecture.md b/doc/zh_TW/compiler/architecture.md index dc578ac3..2f685f0a 100644 --- a/doc/zh_TW/compiler/architecture.md +++ b/doc/zh_TW/compiler/architecture.md @@ -2,12 +2,12 @@ ## 1. 掃描 Erg 腳本 (.er) 並生成 `TokenStream` (parser/lex.rs) -* parser/lexer/Lexer 生成`TokenStream`(這是一個Token的迭代器,TokenStream可以通過lexer.collect()生成) +* parser/lexer/Lexer 生成`TokenStream`(這是一個`Token`的迭代器,`TokenStream`可以通過`Lexer::collect()`生成) * `Lexer` 由 `Lexer::new` 或 `Lexer::from_str` 構造,其中 `Lexer::new` 從文件或命令選項中讀取代碼。 * `Lexer` 可以作為迭代器按順序生成令牌;如果您想一次獲得 `TokenStream`,請使用 `Lexer::lex`。 * `Lexer` 輸出 `LexError` 為錯誤,但 `LexError` 沒有足夠的信息顯示自己。如果要顯示錯誤,請使用 `LexerRunner` 轉換錯誤。 * 如果你想單獨使用 `Lexer`,也可以使用 `LexerRunner`;`Lexer` 只是一個迭代器,並沒有實現 `Runnable` 特性。 - * `Runnable` 由 `LexerRunner`、`ParserRunner`、`Compiler` 和 `VirtualMachine` 實現。 + * `Runnable` 由 `LexerRunner`、`ParserRunner`、`Compiler` 和 `DummyVM` 實現。 ## 2. 轉換 `TokenStream` -> `AST` (parser/parse.rs) @@ -22,7 +22,6 @@ ## 3. 類型檢查和推斷,轉換 `AST` -> `HIR` (compiler/lower.rs) * `HIR` 有每個變量的類型信息。它是用於“高級中間表示”的。 -* `HIR` 只保存變量的類型,但這已經足夠了。在極端情況下,這是因為 Erg 只有轉換(或運算符)應用程序的參數對象。 * `ASTLower` 可以用與`Parser` 和`Lexer` 相同的方式構造。 * 如果沒有錯誤發生,`ASTLowerer::lower` 將輸出 `HIR` 和 `CompileWarnings` 的元組。 * `ASTLowerer`歸`Compiler`所有。與傳統結構不同,`ASTLowerer`處理代碼上下文並且不是一次性的。 @@ -34,9 +33,7 @@ ## 5. 從`HIR`(compiler/codegen.rs)生成字節碼(`CodeObj`) -* 根據表達式的類型信息,將執行量化子程序的名稱解析。 - -##(6.(未來計劃)轉換字節碼 -> LLVM IR) +## (6.(未來計劃)轉換字節碼 -> LLVM IR) * 字節碼是基於堆棧的,而 LLVM IR 是基於寄存器的。 - 這個轉換過程會多出幾層中間過程。 \ No newline at end of file + 這個轉換過程會多出幾層中間過程。 diff --git a/doc/zh_TW/dev_guide/branches.md b/doc/zh_TW/dev_guide/branches.md index d9c2769f..344a9ad2 100644 --- a/doc/zh_TW/dev_guide/branches.md +++ b/doc/zh_TW/dev_guide/branches.md @@ -1,7 +1,5 @@ # 分支機構命名和運營策略 -* 基本上,開發是在一個分支中進行的(單回購開發)。只有在必須斷開分支才能工作的情況下,才創建分支或分支。 - ## main * 主要開發分支 @@ -28,4 +26,10 @@ * 解決特定 issue 的分支 -* 沒有條件 \ No newline at end of file +* 沒有條件 + +## fix-* + +* 修復特定錯誤的分支(如果該問題是一個錯誤,則代替`issue-*`創建)。 + +* 沒有條件 diff --git a/doc/zh_TW/dev_guide/directories.md b/doc/zh_TW/dev_guide/directories.md index cf6b624b..df1f008c 100644 --- a/doc/zh_TW/dev_guide/directories.md +++ b/doc/zh_TW/dev_guide/directories.md @@ -1,25 +1,24 @@ # Erg存儲表結構 - ```console - └─┬資產:圖片等 + └─┬ assets:圖片等 ├─ CODE_OF_CONDUCT:行為準則 - ├─┬編譯器 + ├─┬ compiler: 編譯器 │ ├─ erg_common:通用工具 │ ├─ erg_compiler │ └─ erg_parser:解析器 - ├─┬文檔 + ├─┬ doc: 文檔 │ ├─┬ CN │ │ ├─ API:Erg標準API - │ │ ├─ 編譯器:關於編譯器實現 + │ │ ├─ compiler:關於編譯器實現 │ │ ├─ dev_guide:開發者和貢獻者指南 │ │ ├─ python:Erg開發必備的Python知識 - │ │ ├─ 語法:Erg語法 - │ │ └─ 工具:Erg命令行工具 + │ │ ├─ syntax:Erg語法 + │ │ └─ tools:Erg命令行工具 │ └─┬ JA │ ... - ├─ 示例:示例代碼 + ├─ examples:示例代碼 ├─ library:Erg腳本庫 ├─ src:main.rs和驅動所在目錄 └─ tests:測試代碼 -``` \ No newline at end of file +``` diff --git a/doc/zh_TW/dev_guide/faq_syntax.md b/doc/zh_TW/dev_guide/faq_syntax.md index 9ee8c3a7..00ae6363 100644 --- a/doc/zh_TW/dev_guide/faq_syntax.md +++ b/doc/zh_TW/dev_guide/faq_syntax.md @@ -6,8 +6,7 @@ ## 為什麼類型參數周圍的括號不是 <> 或 []? -因為在和中會發生語法衝突。 - +因為在和中會發生語法衝突。 ```erg # []版 @@ -105,4 +104,4 @@ A:沒有那個計劃。最重要的原因是,如果允許定義自己的運 什麼情況下,可以說合一化是錯的?一個指標是“是否會因其合一而難以看到錯誤信息”。 Erg 設計師發現,將副作用特殊處理會使錯誤消息更容易閱讀。 -Erg 有一個強大的類型系統,但並不是所有的類型都決定了它。如果這樣做了,你的下場就跟 Java 試圖用類來控制一切一樣。 \ No newline at end of file +Erg 有一個強大的類型系統,但並不是所有的類型都決定了它。如果這樣做了,你的下場就跟 Java 試圖用類來控制一切一樣。 diff --git a/doc/zh_TW/dev_guide/i18n_messages.md b/doc/zh_TW/dev_guide/i18n_messages.md index 08e9b807..ef93cda6 100644 --- a/doc/zh_TW/dev_guide/i18n_messages.md +++ b/doc/zh_TW/dev_guide/i18n_messages.md @@ -4,11 +4,10 @@ Erg 正在推動消息(開始、選項、文檔、提示、警告、錯誤消 以下是多語種方法的說明。 -## 查找 +## 查找`switch_lang!` 在 Erg 源代碼中找到(使用 grep 或編輯器的搜索功能)。我們應該能找到下面這樣的東西。 - ```rust switch_lang!( "japanese" => format!("この機能({name})はまだ正式に提供されていません"), @@ -20,8 +19,7 @@ switch_lang!( ## 添加消息 -請在查看其他語言內容的同時添加翻譯消息。最後不要忘記逗號()。 - +請在查看其他語言內容的同時添加翻譯消息。最後不要忘記逗號(,)。 ```rust switch_lang!( @@ -31,7 +29,9 @@ switch_lang!( ), ``` -另外,英語是默認設置,一定要排在最後。部分是 Rust 的格式化功能,允許你將變量的內容()嵌入到字符串中。 +另外,英語是默認設置,一定要排在最後。 + +`{name}`部分是 Rust 的格式化功能,允許你將變量的內容(`name`)嵌入到字符串中。 ## Build @@ -47,9 +47,9 @@ Q:像這樣的指定是什麼意思? A:{RED} 及更高版本將顯示為 Q:如果想添加自己的語言,該如何替換部分?答:目前支持以下語言。 -* english(默認設置) -* 日語。 -* 簡體中文 -* 繁體中文 +* "english"(默認設置) +* "japanese"(日語) +* "simplified_chinese" (簡體中文) +* "traditional_chinese" (繁體中文) -如果你想添加其他語言,請提出請求。 \ No newline at end of file +如果你想添加其他語言,請提出請求。 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 04/42] 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 From cf3e059d7233451d075894eb1b48bf62120a1e86 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 11:15:59 +0800 Subject: [PATCH 05/42] modules zh_CN translate --- doc/EN/API/modules/external/alstruct.md | 6 +- doc/EN/API/modules/unit.md | 6 +- doc/JA/API/modules/unit.md | 4 +- doc/zh_CN/API/modules/external/alstruct.md | 85 +++++++++++++--------- doc/zh_CN/API/modules/repl.md | 16 ++-- doc/zh_CN/API/modules/status.md | 4 +- doc/zh_CN/API/modules/unit.md | 77 ++++++++++---------- doc/zh_CN/API/modules/unsound.md | 16 ++-- 8 files changed, 114 insertions(+), 100 deletions(-) diff --git a/doc/EN/API/modules/external/alstruct.md b/doc/EN/API/modules/external/alstruct.md index 66bd2e86..11946490 100644 --- a/doc/EN/API/modules/external/alstruct.md +++ b/doc/EN/API/modules/external/alstruct.md @@ -31,8 +31,8 @@ Int <: SemiGroup Add ## Functors ``` erg -## * Identity law: x.map(id) == x -## * Composition law: x.map(f).map(g) == x.map(f.then g) +# * 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 } @@ -41,7 +41,7 @@ Functor = Trait { ## Applicative ``` erg -## * Identity law: x.app(X.pure(id)) == x +# * 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 diff --git a/doc/EN/API/modules/unit.md b/doc/EN/API/modules/unit.md index 781eefff..eab1babf 100644 --- a/doc/EN/API/modules/unit.md +++ b/doc/EN/API/modules/unit.md @@ -47,8 +47,8 @@ Some auxiliary units are also predefined. * Potential: Volt(v) * Electrical resistance: Ohm(ohm) * Velocity: Velocity(m/s) -* Area: SquareMeter(m**2) -* Volume: CubicMeter(m**3) (liter = 10e-3 m**3) +* 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 @@ -68,6 +68,6 @@ It also defines a prefix. * Giga = 1e+9 * Tera = 1e+12 * Peta = 1e+15 -*Exa = 1e+18 +* Exa = 1e+18 *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/JA/API/modules/unit.md b/doc/JA/API/modules/unit.md index fa14eac6..a853a43e 100644 --- a/doc/JA/API/modules/unit.md +++ b/doc/JA/API/modules/unit.md @@ -47,8 +47,8 @@ SquareMeter = Patch UnitMul(Meter, Meter) * 電位: Volt(v) * 電気抵抗: Ohm(ohm) * 速度: Velocity(m/s) -* 面積: SquareMeter(m**2) -* 体積: CubicMeter(m**3) (litre = 10e-3 m**3) +* 面積: SquareMeter(m^2) +* 体積: CubicMeter(m^3) (litre = 10e-3 m^3) * 角度: Degree(deg) (rad = 180/pi deg) * 長さ: Feet, Yard, Inch, Mile, Ly, Au, Angstrom * 重さ: Pond diff --git a/doc/zh_CN/API/modules/external/alstruct.md b/doc/zh_CN/API/modules/external/alstruct.md index 87e411e5..ffa4c4d9 100644 --- a/doc/zh_CN/API/modules/external/alstruct.md +++ b/doc/zh_CN/API/modules/external/alstruct.md @@ -1,42 +1,57 @@ -# alstructuration -Modules qui fournissent des caractères représentant les structures et les parcelles d'algèbre. +# 结构 -- 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 +* 成员 -## semi-groupe - SemiGroup Op: Kind 2 = Op(Self, Self) - - IntIsSemiGroupAdd = Patch Int, Impl=SemiGroupAdd - - Int <: SemiGroup Add +## 二进制运算 -## 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 - } +``` erg +BinOp Op: Kind 2 = Subsume Op(Self, Self.ReturnTypeOf Op), Additional: { + .ReturnTypeof = TraitType -> Type +} -## 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 - } +Nat <: BinOp Add +assert Nat. ReturnTypeof(Add) == Nat +assert Nat. ReturnTypeof(Sub) == Int +assert Nat. ReturnTypeof(Mul) == Nat +assert Nat.ReturnTypeof(Div) == Positive Ratio +``` -## monad monad - Monad = Subsume Applicative, Additional: { - .bind|T, U: Type| = (Self(T), T -> Self U) -> Self U - } +## 半群(一个二元运算的代数系统) +``` erg +SemiGroup Op: Kind 2 = Op(Self, Self) + +IntIsSemiGroupAdd = Patch Int, Impl=SemiGroupAdd + +Int <: SemiGroup Add +``` + +## 函子 + +``` 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 +} +``` + +## 应用 + +``` erg +# * 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 +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 a4091909..413b2235 100644 --- a/doc/zh_CN/API/modules/repl.md +++ b/doc/zh_CN/API/modules/repl.md @@ -1,22 +1,22 @@ -# module `repl` +# 模块`repl` -provides REPL(Read-Eval-Print-Loop)-related APIs. +提供REPL(Read-Eval-Print-Loop)相关的API。 -## functions +## 功能 * `gui_help` -View information about an object in a browser. Can be used offline. +在浏览器中查看有关对象的信息。 可以离线使用。 -## types +## 类型 -### Guess = Object +### 猜测 = 对象 -#### methods +#### 方法 * `.guess` -Infers a function given its arguments and return value. +在给定参数和返回值的情况下推断函数。 ``` erg 1.guess((1,), 2) # diff --git a/doc/zh_CN/API/modules/status.md b/doc/zh_CN/API/modules/status.md index a30b4ad0..1e65ebd8 100644 --- a/doc/zh_CN/API/modules/status.md +++ b/doc/zh_CN/API/modules/status.md @@ -1,6 +1,6 @@ -# module `status` + # 模块`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 diff --git a/doc/zh_CN/API/modules/unit.md b/doc/zh_CN/API/modules/unit.md index 781eefff..d3536e38 100644 --- a/doc/zh_CN/API/modules/unit.md +++ b/doc/zh_CN/API/modules/unit.md @@ -1,59 +1,58 @@ -# module `unit` +# 模块`unit` -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. +`unit` 模块是将数值计算中经常使用的单位定义为类型的模块。 +Erg 数值类型包括 `Nat`、`Int`、`Ratio` 等。但是,这些类型没有关于“数字的含义”的信息,因此可以执行诸如添加米和码之类的无意义计算。 +通过使用 `unit` 模块,您可以避免错误,例如将不同单位的数字传递给函数。 +这样的错误确实会发生,并且会导致诸如[由于错误的单位系统导致火星探测器丢失](http://www.sydrose.com/case100/287/)之类的严重错误。 +如果您希望代码在进行数值计算时更加健壮,您应该使用此模块。 ``` erg {*} = import "unit" -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 +x = 6m # 相当于 `x = Meter.new(6)` +t = 3s # 相当于 `t = Sec.new(3)` +#m/s是速度单位对象,类型为velocity print! x/t # 2m/s print! x + 4m # 10m -print! x + 2s # TypeError: `+`(Meter, Sec) is not implemented +print! x + 2s # 类型错误: `+`(Meter, Sec) 未实现 ``` +对象`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. +在单元中,以下单元被定义为类型。它被称为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(分、时、日、年等有分、时、日、年等常量由秒生成) +* 电流:Amper(单位常数:a) +* 温度:Kelvin(单位常数:k。华氏、摄氏度类型也可用,可相互转换) +* 物质量: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) - -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). +此外,还定义了`Unit1`、`UnitMul`和`UnitDiv`类型,可以通过组合基本类型来创建新的单元。 +例如`UnitDiv(Unit1, Sec)`,因为频率单位赫兹(hertz)被定义为振动周期(秒)的倒数。 +如果要将此类型视为有意义的类型(例如添加专用方法),则应创建 [patch](./../../syntax/type/07_patch.md)。 ``` erg Hertz = Patch UnitDiv(Unit1, Sec) SquareMeter = Patch UnitMul(Meter, Meter) ``` -Some auxiliary units are also predefined. +一些辅助单元也是预定义的: -* 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 +* 频率: Hertz(hz) +* 力: Newton(newton) +* 能量: Joule(j) +* 功率: Watt(w) +* 电压: Volt(v) +* 电阻: Ohm(ohm) +* 速度: Velocity(m/s) +* 面积: SquareMeter(m^2) +* 体积: CubicMeter(m^3) (liter = 10e-3 m^3) +* 角度: Degree(deg) (rad = 180/pi deg) +* 长度: Feet, Yard, Inch, Mile, Ly, Au, Angstrom +* 重量: Pound -It also defines a prefix. +它还定义了一个前缀: * Femto = 1e-15 * Pico = 1e-12 @@ -68,6 +67,6 @@ It also defines a prefix. * Giga = 1e+9 * Tera = 1e+12 * Peta = 1e+15 -*Exa = 1e+18 +* Exa = 1e+18 -*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 +* 与名字的由来相反,Erg基本采用MKS单位制。如果需要 CGS 单位制的单位模块,请使用外部库[cgs](https://github.com/mtshiba/cgs)等)。 \ No newline at end of file diff --git a/doc/zh_CN/API/modules/unsound.md b/doc/zh_CN/API/modules/unsound.md index 28998a72..999b8fc4 100644 --- a/doc/zh_CN/API/modules/unsound.md +++ b/doc/zh_CN/API/modules/unsound.md @@ -1,24 +1,24 @@ -# module `unsound` +# 模块 `unsound` -Provides APIs perform unsound and unsafe operations that cannot be guaranteed safe in Erg's type system. +让 API 执行在 Erg 的类型系统中无法保证的不健全和不安全的操作。 ## `unsafe!` -Executes an `Unsafe` procedure. Just like Rust, `Unsafe` APIs cannot be called directly, but are all passed as higher-order functions to this procedure. +执行“不安全”过程。 就像 Rust 一样,`Unsafe` API 不能直接调用,而是作为高阶函数传递给这个过程。 ``` erg unsound = import "unsound" i = unsound. unsafe! do!: - # convert `Result Int` to `Int` + # 将 `Result Int` 转换为 `Int` unsound.transmute input!().try_into(Int), Int ``` ## 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 +## 隐式转换 -Unlike `transmute`, it automatically converts to the expected type. Works the same as Ocaml's `Obj.magic`. \ No newline at end of file +与 `transmute` 不同,它会自动转换为预期的类型。与 Ocaml 的 `Obj.magic` 工作方式相同。 \ No newline at end of file From 290c43b09f7c3036112a164bed5fd07a1f6a5cda Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 11:51:54 +0800 Subject: [PATCH 06/42] translate save --- doc/EN/API/types/classes/Nat.md | 2 +- doc/EN/API/types/classes/Neg.md | 2 +- doc/zh_CN/API/consts.md | 6 +- doc/zh_CN/API/funcs.md | 74 ++--- 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/abandoned.md | 12 +- doc/zh_CN/compiler/architecture.md | 9 +- doc/zh_CN/compiler/errors.md | 60 ++--- doc/zh_CN/compiler/hir.md | 56 ++-- 53 files changed, 555 insertions(+), 561 deletions(-) diff --git a/doc/EN/API/types/classes/Nat.md b/doc/EN/API/types/classes/Nat.md index 027d496a..6291fedb 100644 --- a/doc/EN/API/types/classes/Nat.md +++ b/doc/EN/API/types/classes/Nat.md @@ -2,7 +2,7 @@ A type that represents a natural number. Used for array indices and range types. -##def +## def ``` erg Nat = 0.._ diff --git a/doc/EN/API/types/classes/Neg.md b/doc/EN/API/types/classes/Neg.md index 2c369f3c..cd9e0d0f 100644 --- a/doc/EN/API/types/classes/Neg.md +++ b/doc/EN/API/types/classes/Neg.md @@ -3,6 +3,6 @@ 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 \ No newline at end of file diff --git a/doc/zh_CN/API/consts.md b/doc/zh_CN/API/consts.md index daf7d1e5..b42e2f5b 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 -## Not Implemented +## NotImplemented -## Inf \ No newline at end of file +## Inf diff --git a/doc/zh_CN/API/funcs.md b/doc/zh_CN/API/funcs.md index 78128595..3dee7041 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 -Note that the order of arguments is reversed from Python. +请注意,参数的顺序与 Python 相反 ### log(x: Object, type: LogType = Info) -> None -Log `x` in debug display. Logs are summarized and displayed after the execution is finished. -Emoji-capable terminals are prefixed according to `type`. +在调试显示中记录“x”。 执行完成后汇总并显示日志 +支持表情符号的终端根据“类型”添加前缀 * type == Info: 💬 * type == Ok: ✅ @@ -20,17 +20,17 @@ Emoji-capable terminals are prefixed according to `type`. ### panic(msg: Str) -> Panic -Display msg and stop. -Emoji-capable terminals have a 🚨 prefix. +显示msg并停止。 +支持表情符号的终端有一个🚨前缀。 ### discard|T|(x: ...T) -> NoneType -Throw away `x`. Used when the return value is not used. Unlike `del`, it does not make the variable `x` inaccessible. +扔掉`x`。不使用返回值时使用。与 `del` 不同,它不会使变量 `x` 不可访问 -``` erg -p!x= - # Let q! return some None or non-() value - # use `discard` if you don't need it +```erg +p! x = + # q!应该返回一些不是None或()的值 + # 如果不需要,请使用`discard` 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 -Evaluate code as code and return. +将`code`作为代码进行评估并返回。 ### classof(object: Object) -> Class -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`. +返回`object`的类。 +但是,由于无法比较类,如果要判断实例,请使用`object in Class`而不是`classof(object) == Class` +编译时确定的结构类型是通过`Typeof`获得的 -## Iterator, Array generation system +## Iterator, Array生成系统 ### 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 -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. +创建一个新类。 与`Inherit`不同,通过`Class`传递与基类型无关,并且方法会丢失 +您将无法进行比较,但您可以进行模式匹配等操作 -``` erg +```erg C = Class {i = Int} -NewInt = ClassInt +NewInt = Class Int 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" ``` -The second argument, Impl, is the trait to implement. +第二个参数 Impl 是要实现的特征 ### Inherit -Inherit a class. You can use the base class methods as they are. +继承一个类。您可以按原样使用基类方法 -### Traits +### Trait -Create a new trait. Currently, only record types can be specified. +创造一个新的特质。目前,只能指定记录类型 -### Type of +### Typeof -Returns the argument type. Use `classof` if you want to get the runtime class. -If you use it for type specification, Warning will appear. +返回参数类型。如果要获取运行时类,请使用`classof`。 +如果您将其用于类型规范,则会出现警告。 -``` erg -x: Type of i = ... +```erg +x: Typeof i = ... # TypeWarning: Typeof(i) == Int, please replace it ``` ### Deprecated -Use as a decorator. Warn about deprecated types and functions. \ No newline at end of file +作为解码器使用。警告不推荐使用的类型或函数 \ No newline at end of file diff --git a/doc/zh_CN/API/operators.md b/doc/zh_CN/API/operators.md index 31b1f58b..5c767571 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 -Executes the and operation. +执行 and 操作。 ### `or`(x: Bool, y: Bool) -> Bool -Executes the and operation. +执行 and 操作。 -## prefix operator +## 前缀运算符 ### `+_`|T <: Num|(x: T) -> T -Same as id by default. +默认与 id 相同。 ### `-_`|T <: Num|(x: T) -> T.Neg -For example, Nat.`-`: Nat -> Neg and the return value is different. +例如 Nat.`-`: Nat -> Neg 和返回值不同。 ### `!`|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 -Creates a Range object with no lower bound at the end of x. -x..x returns only x as an iterator. +在 x 的末尾创建一个没有下限的 Range 对象。 +x..x 仅返回 x 作为迭代器。 ### `..<`|T <: Ord|(x: T) -> Range T -x.. Range T -Creates a Range object with no upper bound starting at x. +创建一个从 x 开始没有上限的 Range 对象。 ### |T <: Ord|(x: T)`<..` -> Range T \ No newline at end of file diff --git a/doc/zh_CN/API/procs.md b/doc/zh_CN/API/procs.md index 371b2f7c..dfbdcff9 100644 --- a/doc/zh_CN/API/procs.md +++ b/doc/zh_CN/API/procs.md @@ -1,34 +1,34 @@ -# procedures +# 过程 ## print! ``` erg -print!(x) -> NoneType +打印!(x)->无类型 ``` - Returns x with a newline. + 使用换行符返回 x。 -##debug! +##调试&排除; ``` erg -debug!(x, type = Info) -> NoneType +调试!(x,类型=信息)-> NoneType ``` -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. +用换行符调试 x(文件名、行号、变量名一起显示)。 在发布模式中删除。 +支持表情符号的终端根据类型加前缀。 * 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 -Execute block while cond is True. +当cond为True时的执行块。 ## Lineno!() -> Nat diff --git a/doc/zh_CN/API/special.md b/doc/zh_CN/API/special.md index 698429dc..2a362bd0 100644 --- a/doc/zh_CN/API/special.md +++ b/doc/zh_CN/API/special.md @@ -1,109 +1,109 @@ -# Special form +# 特殊形式 -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. +特殊形式是不能在 Erg 类型系统中表达的运算符、子程序(等等)。它被`包围,但实际上无法捕获。 +此外,为方便起见,还出现了“Pattern”、“Body”和“Conv”等类型,但不存在此类类型。它的含义也取决于上下文。 ## `=`(pat: Pattern, body: Body) -> NoneType -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. +将 body 分配给 pat 作为变量。如果变量已存在于同一范围内或与 pat 不匹配,则引发错误。 +它还用于记录属性定义和默认参数。 -``` 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 # -gx: Int = x + 1 +g x: Int = x + 1 print! g # -KX: Int = Class(...) +K X: 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. +`=` 运算符的返回值为“未定义”。 +函数中的多个赋值和 `=` 会导致语法错误。 -``` erg -i = j = 1 # SyntaxError: multiple assignments are not allowed +``` 呃 +i = j = 1 # SyntaxError: 不允许多次赋值 print!(x=1) # SyntaxError: cannot use `=` in function arguments -# hint: did you mean keyword arguments (`x: 1`)? +# 提示:您的意思是关键字参数(`x: 1`)吗? if True, do: - i = 0 # SyntaxError: A block cannot be terminated by an assignment expression + i = 0 # SyntaxError: 块不能被赋值表达式终止 ``` ## `->`(pat: Pattern, body: Body) -> Func -Generate anonymous functions, function types. +生成匿名函数,函数类型。 ## `=>`(pat: Pattern, body: Body) -> Proc -Generate anonymous procedure, procedure type. +生成匿名过程,过程类型。 ## `:`(subject, T) -Determine if subject matches T. If they don't match, throw a compile error. +确定主题是否与 T 匹配。如果它们不匹配,则抛出编译错误。 -``` erg +```erg a: Int f x: Int, y: Int = x / y ``` -Also used for `:` applied styles. +也用于 `:` 应用样式。 -``` erg -fx: +```erg +f x: y z ``` -Like `:` and `=`, the result of the operation is undefined. +像`:`和`=`一样,运算的结果是不确定的。 -``` erg -_ = x: Int # SyntaxError: -print!(x: Int) # SyntaxError: +```erg +_ = x: Int # 语法错误: +print!(x: Int) # 语法错误: ``` ## `.`(obj, attr) -Read attributes of obj. -`x.[y, z]` will return the y and z attributes of x as an array. +读取obj的属性。 +`x.[y, z]` 将 x 的 y 和 z 属性作为数组返回。 ## `|>`(obj, c: Callable) -Execute `c(obj)`. `x + y |>.foo()` is the same as `(x + y).foo()`. +执行`c(obj)`。 `x + y |>.foo()` 与 `(x + y).foo()` 相同。 -### (x: Option T)`?` -> T | T +### (x: Option T)`?` -> T | T -Postfix operator. Call `x.unwrap()` and `return` immediately in case of error. +后缀运算符。如果出现错误,请立即调用 `x.unwrap()` 和 `return`。 ## match(obj, ...lambdas: Lambda) -For obj, execute lambdas that match the pattern. +对于 obj,执行与模式匹配的 lambda。 -``` 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 -# (one two three) +# (1, 2, 3) ``` ## del(x: ...T) -> NoneType | T -Delete the variable `x`. However, built-in objects cannot be deleted. +删除变量“x”。但是,无法删除内置对象。 -``` 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 -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. +创建一个由两对组成的类元组结构,称为 Choice 对象。 +`l, r` 被懒惰地评估。也就是说,只有在调用 .get_then 或 .get_else 时才会计算表达式。 -``` 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) -Generates sieve type, rank 2 type. +生成筛型,等级2型。 ### `...` -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! -Returns a mutable reference to a mutable object. \ No newline at end of file +返回对可变对象的可变引用。 \ No newline at end of file diff --git a/doc/zh_CN/API/types.md b/doc/zh_CN/API/types.md index 2eba4b08..7d564d92 100644 --- a/doc/zh_CN/API/types.md +++ b/doc/zh_CN/API/types.md @@ -1,90 +1,90 @@ -# List of built-in Erg types +# 内置 Erg 类型列表 -Attributes of the type itself are not stored in the `.__dict__` and cannot be referenced from the instance +类型本身的属性不存储在 `.__dict__` 中,不能从实例中引用 -## Fundamental types +## 基本类型 -### Objects +### 对象 -* `__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) +* `__dir__`:将对象的属性作为数组返回(dir函数) +* `__getattribute__`: 获取并返回一个属性 +* `__hash__`:返回对象的哈希值 +* `__repr__`:对象的字符串表示(不存在丰富/默认实现) +* `__sizeof__`:返回对象的大小(包括在堆中分配的大小) -### Show +### 显示 -* `__str__`: returns the string representation (rich) of the object +* `__str__`:返回对象的字符串表示(丰富) -###Fmt +### Fmt -* `__format__`: Returns a formatted string +* `__format__`: 返回一个格式化的字符串 -### Doc +### 文档 -* `__doc__`: object description +* `__doc__`:对象描述 -### Named +### 命名 -* `__name__`: the name of the object +* `__name__`: 对象的名称 -### Pickles +### 泡菜 -* `__reduce__`: Serialize objects with Pickle -* `__reduce_ex__`: __reduce__ that allows you to specify the protocol version +* `__reduce__`: 用 Pickle 序列化对象 +* `__reduce_ex__`: __reduce__ 允许你指定协议版本 -## Object system +## 对象系统 -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. +Trait 类相当于 Python 中的 ABC(抽象基类,接口) +实例属于1、True、“aaa”等。 +类是 Int、Bool、Str 等。 -### Type +### 类型 -* `__supers__`: Supertypes (`__mro__` is an array, but this one is a Set) +* `__supers__`:超类型(`__mro__` 是一个数组,但这个是一个 Set) * `__basicsize__`: -* `__dictoffset__`: not supported by Evm +* `__dictoffset__`:Evm 不支持 * `__flags__`: -* `__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) +* `__itemsize__`:实例的大小(如果不是类,则为 0) +* `__weakrefoffset__`:Evm 不支持 +* `__membercheck__`: 相当于`ismember(x, T)` +* `__subtypecheck__`:等价于`issubtype(U, T)`,别名`__subclasshook__`(兼容CPython) -### Instances +### 实例 -* `__class__`: Returns the class from which the instance was created (automatically attached to objects created with `.new`) +* `__class__`:返回创建实例的类(自动附加到使用 `.new` 创建的对象) ### Class -* `__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)` +* `__mro__`:用于方法解析的类型数组(包括自身,始终以 Object 结尾) +* `__base__`:基本类型(`__mro__[1]` 如果有多个) +* `__new__`: 实例化 +* `__init__`: 初始化实例 +* `__init_subclass__`: 初始化实例 +* `__intstancecheck__`:使用类似于 `MyClass.__instancecheck__(x)`,等价于 `isinstance(x, MyClass)` +* `__subclasscheck__`:等价于 `issubclass(C, MyClass)` -## operator +## 运算符 -Operators other than those specified here have no special types +此处指定以外的运算符没有特殊类型 -### Eq +### 方程 -* `__eq__(self, rhs: Self) -> Bool`: object comparison function (==) -* `__ne__`: object comparison function (!=), with default implementation +* `__eq__(self, rhs: Self) -> Bool`: 对象比较函数 (==) +* `__ne__`: 对象比较函数 (!=),默认实现 -### Ord +### 秩序 -* `__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 +* `__lt__(self, rhs: Self) -> Bool`: 对象比较函数 (<) +* `__le__`:对象比较函数(<=),默认实现 +* `__gt__`:对象比较函数(>),默认实现 +* `__ge__`:对象比较函数(>=),默认实现 -### Bin Add +### BinAdd -* Implements `__add__(self, rhs: Self) -> Self`: `+` +* 实现 `__add__(self, rhs: Self) -> Self`: `+` -### Add R +### 添加R * `__add__(self, rhs: R) -> Self.AddO` @@ -98,93 +98,93 @@ Operators other than those specified here have no special types ### BinMul <: Mul Self -* `__pow__`: implements `**` (with default implementation) +* `__pow__`:实现 `**`(默认实现) ### Div R, O -* Implements `__div__(self, rhs: Self) -> Self`: `/`, may panic due to 0 +* 实现 `__div__(self, rhs: Self) -> Self`: `/`,可能会因为 0 而恐慌 ### BinDiv <: Div Self -* `__mod__`: implement `%` (with default implementation) +* `__mod__`: 实现 `%` (默认实现) -## numeric type +## 数值型 ### Num (= Add and Sub and Mul and Eq) -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,Vector、Matrix和Tensor都是Num(Matrix和Tensor中的*分别与dot和product相同) ### Complex (= Inherit(Object, Impl := Num)) -* `imag: Ratio`: returns the imaginary part -* `real: Ratio`: returns the real part -* `conjugate self -> Complex`: returns the complex conjugate +* `imag: Ratio`:返回虚部 +* `real: Ratio`:返回实部 +* `conjugate self -> Complex`:返回复共轭 ### Float (= Inherit(FloatComplex, Impl := Num)) ### Ratio (= Inherit(Complex, Impl := Num)) -* `numerator: Int`: returns the numerator -* `denominator: Int`: Returns the denominator +* `numerator: Int`: 返回分子 +* `denominator: Int`: 返回分母 ### Int (= Inherit Ratio) ### Nat (= Inherit Int) -* `times!`: run the proc self times +* `times!`: 运行 proc self 时间 -## Other basic types +## 其他基本类型 -### Bool +### 布尔值 * `__and__`: * `__or__`: * `not`: -## Str (<: Seq) +## 字符串 (<: 序列) * `capitalize` -* `chomp`: remove newline characters +* `chomp`: 删除换行符 * `isalnum`: * `isascii`: * `isalpha`: * `isdecimal`: -* `is sight`: -* `is identifier` -*`islower` -* `is numeric` +* `isdight`: +* `isidentifier` +* `islower` +* `isnumeric` * `isprintable` * `isspace` -* `is title` +* `istitle` * `isupper` -*`lower` +* `lower` * `swapcase` * `title` * `upper` -## others +## 其他 -### Bits +### 位 -* `from_bytes`: Convert from Bytes -* `to_bytes`: Convert to Bytes (specify length and endian (byteorder)) -* `bit_length`: returns bit length +* `from_bytes`:从字节转换 +* `to_bytes`:转换为字节(指定长度和字节序(字节序)) +* `bit_length`:返回位长度 -### Iterable T +### 可迭代 T -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()`. +请注意,它不是 `Iterator` 本身的类型。 `Nat` 是 `Iterable` 但你不能 `Nat.next()`,你需要 `Nat.iter().next()`。 -* `iter`: Create an Iterator. +* `iter`:创建一个迭代器。 -### Iterator T +### 迭代器 T -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. +Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter().fold (sum, n) -> sum + n*2`等是可能的。 +由于所有和任何在使用后都会被破坏,因此没有副作用。这些应该使用没有副作用的 `next` 来实现,但内部使用 `Iterator!.next!` 来提高执行效率。 -* `next`: Returns the first element and the remaining Iterator. -*`all` -*`any` -*`filter` +* `next`:返回第一个元素和剩余的迭代器。 +* `all` +* `any` +* `filter` * `filter_map` * `find` * `find_map` @@ -192,21 +192,21 @@ Since all and any are destroyed after use, there are no side effects. These are * `flatten` * `fold` * `for_each` -*`map` +* `map` * `map_while` * `nth` -*`pos` +* `pos` * `take` * `unzip` -*`zip` +* `zip` -### Iterator!T = IteratorT and ... +### Iterator!T = IteratorT 和 ... -* `next!`: Get the first element. +* `next!`:获取第一个元素。 -## SizedIterator T = Iterator T and ... +## SizedIterator T = 迭代器 T 和 ... -An Iterator over a finite number of elements. +有限数量元素的迭代器。 * `len`: * `chain`: @@ -221,42 +221,42 @@ An Iterator over a finite number of elements. * `max`: * `min`: -## Seq T = SizedIterable T and ... +## Seq T = SizedIterable T 和 ... -* `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 +* `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 ...) +### Seq!T (= Seq T and ...) * `__setitem__!`: * `__delitem__!`: -* `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 +* `插入!`:添加到 idx +* `remove!`: 删除 idx +* `prepend!`:前置 +* `dequeue!`: 删除开头 +* `push!`:添加到末尾 +* `pop!`:拿尾巴 +* `dedup!`:删除连续值 +* `uniq!`: 删除重复元素(通过排序实现!|> dedup!,因此顺序可能会改变) +* `swap!`:交换元素 +* `reverse!`:反转元素 * `set!` -* `sort!`: sort elements +* `sort!`: 排序元素 * `translate!` \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Array!(T).md b/doc/zh_CN/API/types/classes/Array!(T).md index 51902435..1d020183 100644 --- a/doc/zh_CN/API/types/classes/Array!(T).md +++ b/doc/zh_CN/API/types/classes/Array!(T).md @@ -1,4 +1,3 @@ # Array! T -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 +表示可变长度数组的类型。在编译时长度未知时使用。 有一个语法糖叫做` [t]!`。在`Array! T = ArrayWithMutLength! T, !_`中被定义 \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Array(T).md b/doc/zh_CN/API/types/classes/Array(T).md index 78300991..c186d029 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 -Defined by `Array T = ArrayWithLen T, _`. There is a syntactic sugar called `[T]`. \ No newline at end of file +由`Array T = ArrayWithLen T, _`定义。 有一种语法糖叫做`[T]`。 \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md b/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md index c9dd51c3..3c1f20d1 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]` is syntactic sugar. There is also an [`Array` type](./Array.md) that omits the length. +`[T; N]`是语法糖。还有一个[`Array` 类型](./Array.md)省略了长度。 ## 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 - 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. + 返回是否所有元素都满足 pred。 + 如果元素为 0,则无论 pred 为 `True`,但会发出警告。 + 该规范本身已被多种语言采用,是逻辑一致性所必需的。 - ``` 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 0a6fed5c..b219a60f 100644 --- a/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md +++ b/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md @@ -1,34 +1,26 @@ -# ArrayWithLen T: Type, N: Nat +# ArrayWithMutLength! T: Type, N: Nat! -`[T; N]` is syntactic sugar. There is also an [`Array` type](./Array.md) that omits the length. +一个可变长度数组,其长度在编译时已知。还有语法糖`ArrayWithMutLength(T, !N) == [T; !N]` ## methods -* values_at(self, selectors: [Nat; N]) -> [T; N] +* push! ref! self(N ~> N+1, ...), elem: T -``` erg -assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] -``` +* pop! ref! (N ~> N-1, ...) -> T -* 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. +* sample!(ref! self) -> T +* sample! ref! self, M: Nat -> [T; M] + 随机选择里面的一个元素并返回一个副本 - ``` erg - assert[].all(_ -> False) - ``` +* shuffle!(ref! self) + 把里面的东西随机摆放 - ```python - assert all(False for _in[]) - ``` +* assert_len ref! self(_ ~> N, ...), N: Nat -> () or Panic + 验证长度。 + `panic!` 如果长度无效。 -## methods of ArrayWithLen T, N | T <: Eq +## Impl -* 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 +* From Range Int +* From [T; N] +* Num diff --git a/doc/zh_CN/API/types/classes/Complex.md b/doc/zh_CN/API/types/classes/Complex.md index 8e5bd75d..521b5b56 100644 --- a/doc/zh_CN/API/types/classes/Complex.md +++ b/doc/zh_CN/API/types/classes/Complex.md @@ -1,6 +1,6 @@ # Complex -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. +表示复数的类型。 在 Erg 中表示数字的类型,例如 Float、Int 和 Nat,通常在顶部有这种类型 ## supers @@ -11,4 +11,4 @@ Num and Norm * abs * conjugate * imag -* real \ No newline at end of file +* real diff --git a/doc/zh_CN/API/types/classes/Dict!.md b/doc/zh_CN/API/types/classes/Dict!.md index 8fa22607..0c5fa58e 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 -A type that represents a dictionary (hashmap). There is a syntactic sugar called `{K: V}`. +表示字典(哈希Map)的类型。 有一个语法糖叫做`{K: V}` ## methods -* invert!(self) -> Self! V, K \ No newline at end of file +* invert!(self) -> Self! V, K diff --git a/doc/zh_CN/API/types/classes/Either.md b/doc/zh_CN/API/types/classes/Either.md index 16f56740..900cc4d3 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 -A type that represents "either L or R". You can think of it as a two-limited form of the Or type. +表示L或R的类型。 您可以将其视为Or类型的二元形式 ## methods @@ -9,4 +9,4 @@ A type that represents "either L or R". You can think of it as a two-limited for * andl * andr * mapl -* mapr \ No newline at end of file +* mapr diff --git a/doc/zh_CN/API/types/classes/Float.md b/doc/zh_CN/API/types/classes/Float.md index 387c4257..02fe7aa8 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 -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. +表示实数(包含小数的数)的类型。符合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 @@ -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, date: Nat) -> [Str] - Separate by dight digits. 3 with no arguments. \ No newline at end of file +* separate(self, dight: Nat) -> [Str] + 按digit位数划分。没有自变量 diff --git a/doc/zh_CN/API/types/classes/Function(N).md b/doc/zh_CN/API/types/classes/Function(N).md index e210780b..0955f2ec 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 cd8c3f71..0e7e02b9 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 is a class whose only instance is inf. -The main use of inf is with interval types. -For example, integer types greater than or equal to 2 are `2.. Self(L1+L2, R1+R2) -normal addition. Addition of `Int` and `Nat` is defined here under the pretense that it is defined in each class. +正常加法。 `Int` 和 `Nat` 的添加在此定义为假装它在每个类中定义 -``` 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 5492537d..001d85d6 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 -A type that represents a subtype of the well-ordered set type (WellOrder). The Interval type has derived types such as PreOpen(x<..y). +表示有序集合类型 (WellOrder) 的子类型的类型。Interval 类型具有派生类型,例如 PreOpen(x<..y)。 -``` erg +```erg Months = 1..12 Alphabet = "a".."z" Weekdays = Monday..Friday Winter = November..December or January..February ``` -``` erg -0..1 # integer range -0.0..1.0 # real (rational) range -# or same for 0/1..1/1 +```erg +0..1 # 整数范围 +0.0..1.0 # 真实(有理)范围 +# 或 0/1..1/1 相同 ``` -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 +计算机无法处理无限位数的数字,所以实数的范围实际上是有理数的范围。 \ 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 eb926248..902029b2 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] -A type that represents a matrix. It inherits from Tensor[M, N]. +表示矩阵的类型。 它继承自 Tensor[M, N] ## def -Inherit Tensor T, [M, N] \ No newline at end of file +Inherit Tensor T, [M, N] diff --git a/doc/zh_CN/API/types/classes/Nat.md b/doc/zh_CN/API/types/classes/Nat.md index 027d496a..afa30251 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!" -``` \ No newline at end of file + print! "hello!" +``` diff --git a/doc/zh_CN/API/types/classes/Neg.md b/doc/zh_CN/API/types/classes/Neg.md index 2c369f3c..7005a062 100644 --- a/doc/zh_CN/API/types/classes/Neg.md +++ b/doc/zh_CN/API/types/classes/Neg.md @@ -1,8 +1,8 @@ # Neg -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. +表示负整数的类型。 Pos和Neg和{0} == Int +它还具有一些值得注意的属性,例如不被零除和 Neg * Neg == Pos -##def +## def -Inf<..-1 \ No newline at end of file +Inf<..-1 diff --git a/doc/zh_CN/API/types/classes/Never.md b/doc/zh_CN/API/types/classes/Never.md index c6cdea6b..2f0cdd15 100644 --- a/doc/zh_CN/API/types/classes/Never.md +++ b/doc/zh_CN/API/types/classes/Never.md @@ -1,13 +1,13 @@ # Never -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. +它是所有类型的子类型。 它是一个`Class`,因为它拥有所有的方法,当然还有 `.new`。但是,它没有实例,并且Erg会在即将创建的那一刻停止。 +还有一种叫做`Panic`的类型没有实例,但是`Never`用于正常终止或故意无限循环,`Panic`用于异常终止。 -``` erg +```erg # Never <: Panic f(): Panic = exit 0 # OK g(): Never = panic() # TypeError ``` -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 +`Never`/`Panic`的 OR 类型,例如`T 或 Never`可以转换为`T`。 这是因为`Never`在语义上是一个从不出现的选项(如果出现了,程序会立即停止)。 +但是,在函数的返回值类型中使用时,`or Never`不能省略,因为它表示程序可能会终止。 \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/NonZero.md b/doc/zh_CN/API/types/classes/NonZero.md index c54965f7..9a7d53b7 100644 --- a/doc/zh_CN/API/types/classes/NonZero.md +++ b/doc/zh_CN/API/types/classes/NonZero.md @@ -1,30 +1,30 @@ -# NonZeroN +# NonZero N -A class that represents a non-zero number. The safety of division by zero is guaranteed. +表示非零数的类。 保证除零的安全性 ```mermaid -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 +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 +.`/`: Self.(R) -> O diff --git a/doc/zh_CN/API/types/classes/Object.md b/doc/zh_CN/API/types/classes/Object.md index e7e2cf58..963f58f1 100644 --- a/doc/zh_CN/API/types/classes/Object.md +++ b/doc/zh_CN/API/types/classes/Object.md @@ -1,7 +1,7 @@ -# Objects +# Object -It is the supertype of all types. +它是所有类型的超类型 ## methods -* __sizeof__: Nat \ No newline at end of file +* __sizeof__: Nat diff --git a/doc/zh_CN/API/types/classes/Operator.md b/doc/zh_CN/API/types/classes/Operator.md index a22e91b9..0b26bbe9 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 \ No newline at end of file +Inherit Func [...T], O diff --git a/doc/zh_CN/API/types/classes/Option.md b/doc/zh_CN/API/types/classes/Option.md index a66367d9..6eeb18b0 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 -Extract it expecting the contents to be `T` type. If it is `None`, output `msg` and panic. +提取它,期望内容是 `T` 类型。 如果是 `None`,则输出 `msg` 并恐慌 -``` 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 \ No newline at end of file +* unwrap_or_exec!(self, p!: () => T) -> T diff --git a/doc/zh_CN/API/types/classes/Pos.md b/doc/zh_CN/API/types/classes/Pos.md index c3d4ca6a..44831482 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 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. +Pos是一种表示正数(大于或等于1的整数)的类型。 +由于不包括0,因此具有消除被零除的可能性等优点。 ## Def -`Pos = 1.._` \ No newline at end of file +`Pos = 1.._` diff --git a/doc/zh_CN/API/types/classes/Ratio.md b/doc/zh_CN/API/types/classes/Ratio.md index 938357f3..58b4211b 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 -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 +表示有理数的类型。 它主要用于当您要使用分数时。 +实际上,Erg中的/运算符返回 Ratio。1/3等不被评估为 0.33333... 并且被处理为1/3。 此外,0.1 相当于 1/10。 所以`0.1 + 0.2 == 0.3`。 这听起来很明显,但在 Python中它是False。 +但是,Ratio类型的效率往往比Float类型略低。 在执行速度很重要且不需要精确数值的地方应该使用浮点类型。 然而,正如Rob Pike所说,过早优化是万恶之源。 在丢弃Ratio类型并使用Float类型之前,请进行真实的性能测试。 业余爱好者无条件偏爱较轻的模具。 diff --git a/doc/zh_CN/API/types/classes/Record.md b/doc/zh_CN/API/types/classes/Record.md index 8e0bf5fc..4ff1126e 100644 --- a/doc/zh_CN/API/types/classes/Record.md +++ b/doc/zh_CN/API/types/classes/Record.md @@ -1,14 +1,14 @@ # Record -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. +记录所属的类。例如,`{i = 1}` 是`Structural {i = Int}` 类型的元素,并且是`{i = Int}` 类的实例 +请注意,其他类的实例是记录类型的元素,而不是记录类的实例 -``` 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 64824ce6..de89e41c 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 ``` -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 +和 `Option` 一样,它代表“一个可能失败的值”,但它可以有失败的上下文。 用法与`Either`几乎相同。 \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Str!.md b/doc/zh_CN/API/types/classes/Str!.md index a790d1d3..af0f1ee7 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 StrWithLenN +# StrWithLen! N: Nat! = Inherit StrWithLen N -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 5a185e01..9b4f21b8 100644 --- a/doc/zh_CN/API/types/classes/Str.md +++ b/doc/zh_CN/API/types/classes/Str.md @@ -1,9 +1,9 @@ # Str -(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 _`). +(不变长度)表示字符串的类型。 简单的 `Str` 类型是删除了字符数的 `StrWithLen N` 类型(`Str = StrWithLen _`) ## methods -*isnumeric +* isnumeric -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 +返回字符串是否为阿拉伯数字。 使用 `isunicodenumeric` 判断汉字数字和其他表示数字的字符(注意此行为与 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 c7533cac..2350098c 100644 --- a/doc/zh_CN/API/types/classes/Subroutine.md +++ b/doc/zh_CN/API/types/classes/Subroutine.md @@ -1,19 +1,19 @@ -# Subroutines +# Subroutine -Base type of Func and Proc. +Func和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 -``` \ No newline at end of file + for 0..10, i -> + if i == 5: + do + f::return i + do + log i +``` diff --git a/doc/zh_CN/API/types/classes/Tensor.md b/doc/zh_CN/API/types/classes/Tensor.md index 98488e92..131bb3c8 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] - A class for efficiently manipulating multidimensional arrays. It also defines operations such as multiplication on multidimensional arrays. - Matrix, Vector, etc. inherit from this type. + 用于有效操作多维数组的类。 它还定义了诸如多维数组上的乘法之类的操作 + Matrix、Vector 等都继承自该类型 -``` erg -Tensor.arrange(0..9) #Tensor[10] +```erg +Tensor.arange(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.arrange(0..9) #Tensor[10] * diag * linspace -*logspace -* geomspace \ No newline at end of file +* logspace +* geomspace diff --git a/doc/zh_CN/API/types/classes/TransCell(T).md b/doc/zh_CN/API/types/classes/TransCell(T).md index 9b042627..078be645 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! -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. +它是一个单元格,其内容可以针对每个模具进行更改。 由于它是T类型的子类型,因此它也表现为T类型 +当它在初始化时输入T时很有用,并且在某个点之后总是输入U -``` 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 fb4b33ee..b9b7667e 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 - 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 + 一种泛化 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 + ``` diff --git a/doc/zh_CN/API/types/classes/Vector.md b/doc/zh_CN/API/types/classes/Vector.md index ed14caa1..f9a159ed 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 -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 +表示向量的类型。与同名的Rust和C++类型不同,这种类型只处理数字。 \ No newline at end of file diff --git a/doc/zh_CN/API/types/patches/BinOp.md b/doc/zh_CN/API/types/patches/BinOp.md index 50374b29..b10cd654 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 \ No newline at end of file +Operator [L, R], O diff --git a/doc/zh_CN/API/types/patches/UnaryOp.md b/doc/zh_CN/API/types/patches/UnaryOp.md index bdc35fe6..e06e07af 100644 --- a/doc/zh_CN/API/types/patches/UnaryOp.md +++ b/doc/zh_CN/API/types/patches/UnaryOp.md @@ -1,7 +1,7 @@ -# Unary Op T, O +# UnaryOp T, O -The type of the unary operator. +一元运算符的类型 -##def +## def -Operator [T], O \ No newline at end of file +Operator [T], O diff --git a/doc/zh_CN/API/types/traits/Add(R,O).md b/doc/zh_CN/API/types/traits/Add(R,O).md index 952dd1b8..bf735100 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` 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. +`Add`是一种定义加法的类型。加法有两种类型的`+`:方法和函数 +`+`作为二元函数,即`_+_`,定义如下: -``` 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 3f0906d6..b0b5adf0 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 -Use `SafeDiv` if there are no errors due to division by zero. +如果除以零没有错误,请使用“SafeDiv” -``` 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 4b43a843..53c8e9a8 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 -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. +一种类型,表明它可以被类型转换为类型T。 +即使Self和T之间没有继承关系,也是在关系可以相互转换的时候定义的。 +与继承不同,没有隐式转换。您必须始终调用 `.into` 方法。 ## 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 a49e9815..5745c5ce 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` \ No newline at end of file +* `abs` 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 d214d620..54c3a1b1 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 a51d45ac..93629a6a 100644 --- a/doc/zh_CN/API/types/traits/Sample.md +++ b/doc/zh_CN/API/types/traits/Sample.md @@ -1,31 +1,31 @@ # 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. +具有“随机”选择实例的`sample`和`sample!`方法的特征。`sample`方法总是返回相同的实例,而`sample!`方法返回一个随机实例,该实例随调用而变化 -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. +请注意,这是一个假设您想要一个适当的实例进行测试等的特征,并且它不一定是随机的。 如果您想要随机抽样,请使用“随机”模块。 -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. +所有主要的值类都实现了 `Sample`。它还在由“Sample”类组成的元组类型、记录类型、Or类型和筛选类型中实现 -``` erg -assert Int. sample() == 42 -assert Str. sample() == "example" -# Int is sampled in 64bit range by default -print! Int. sample!() # 1313798 +```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} ``` -Below is an implementation example of `Sample`. +下面是一个`Sample`的实现示例 -``` erg +```erg EmailAddress = Class {header = Str; domain = Str}, Impl=Sample and Show @Impl Show -Email address. +EmailAddress. show self = "{self::header}@{self::domain}" @Impl Sample -Email address. +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 + header = AsciiStr.sample!() + Self.new {header; domain} +``` diff --git a/doc/zh_CN/API/types/traits/Unpack.md b/doc/zh_CN/API/types/traits/Unpack.md index 2b1c1d40..259beb3a 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 -``` \ No newline at end of file + (i: Int) -> i + ({i}: C) -> i +``` diff --git a/doc/zh_CN/compiler/abandoned.md b/doc/zh_CN/compiler/abandoned.md index 483fe374..2aca11d1 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) +## 重载(临时多态性) -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. +被放弃了,因为它可以用参数+子类型多态来代替,并且与Python的语义不兼容。 有关详细信息,请参阅 [overload](../syntax/type/overloading.md) 文章。 -## Ownership system with explicit lifetime +## 具有显式生命周期的所有权系统 -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 +原计划引入 Rust 之类的所有权系统,但由于与 Python 的语义不兼容以及需要引入生命周期注解等复杂规范而被放弃,并且所有不可变对象都是 RC。托管的可变对象现在只有一个所有权. +Dyne 没有 C# 和 Nim 那样的 GIL,策略是允许值对象和低级操作在安全范围内。 \ No newline at end of file diff --git a/doc/zh_CN/compiler/architecture.md b/doc/zh_CN/compiler/architecture.md index 8db002b4..1088dbce 100644 --- a/doc/zh_CN/compiler/architecture.md +++ b/doc/zh_CN/compiler/architecture.md @@ -2,12 +2,12 @@ ## 1. 扫描 Erg 脚本 (.er) 并生成 `TokenStream` (parser/lex.rs) -* parser/lexer/Lexer 生成`TokenStream`(这是一个`Token`的迭代器,`TokenStream`可以通过`Lexer::collect()`生成) +* 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` 实现。 + * `Runnable` 由 `LexerRunner`、`ParserRunner`、`Compiler` 和 `VirtualMachine` 实现。 ## 2. 转换 `TokenStream` -> `AST` (parser/parse.rs) @@ -22,6 +22,7 @@ ## 3. 类型检查和推断,转换 `AST` -> `HIR` (compiler/lower.rs) * `HIR` 有每个变量的类型信息。它是用于“高级中间表示”的。 +* `HIR` 只保存变量的类型,但这已经足够了。在极端情况下,这是因为 Erg 只有转换(或运算符)应用程序的参数对象。 * `ASTLower` 可以用与`Parser` 和`Lexer` 相同的方式构造。 * 如果没有错误发生,`ASTLowerer::lower` 将输出 `HIR` 和 `CompileWarnings` 的元组。 * `ASTLowerer`归`Compiler`所有。与传统结构不同,`ASTLowerer`处理代码上下文并且不是一次性的。 @@ -33,7 +34,9 @@ ## 5. 从`HIR`(compiler/codegen.rs)生成字节码(`CodeObj`) -## (6.(未来计划)转换字节码 -> LLVM IR) +* 根据表达式的类型信息,将执行量化子程序的名称解析。 + +##(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 da4af20b..6e241f3c 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 -Raised when an invalid indentation is detected. -Derived from SyntaxError. +检测到不良缩进时发生 +派生自SyntaxError ## NameError -Raised when accessing a variable that does not exist. +当您访问不存在的变量时发生 ## NotImplementedError -Raised when calling an API that has a definition but no implementation. -Derived from TypeError. +当您调用具有定义但没有实现的 API 时发生 +派生自 TypeError ## PatternError -Raised when an invalid pattern is detected. -Derived from SyntaxError. +当检测到非法模式时发生 +派生自SyntaxError ## SyntaxError -Raised when an invalid syntax is detected. +在检测到错误语法时发生 ## TabError -Raised when a tab character is used for indentation/space. -Derived from SyntaxError. +在使用制表符进行缩进/间距时发生 +派生自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 ``` -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. +在这段代码中,`y = i + x` 中的 `i` 是一个未定义的变量 +但是,常量可以在定义之前在另一个函数中调用 ```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 -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. +当您检测到将来可能导致问题的代码时发生 +此警告是由版本兼容性问题(包括库)以及语法和 API 的更改引起的 ## ImportWarning diff --git a/doc/zh_CN/compiler/hir.md b/doc/zh_CN/compiler/hir.md index 896e6e61..837b51a4 100644 --- a/doc/zh_CN/compiler/hir.md +++ b/doc/zh_CN/compiler/hir.md @@ -1,35 +1,35 @@ -# High-level Intermediate Representation (HIR) +# 高レベル中間表現(HIR, High-level Intermediate Representation) -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. +HIR 是 Erg 编译器从 AST 生成的结构 +此结构包含源代码中每个表达式的完整类型信息,并且在语法上已脱糖 +AST与源代码一一对应(纯文本),但是HIR去掉了不必要的代码信息,添加了省略的类型信息,所以HIR可以转换为源代码很难恢复 +让我们在下面的代码中查看 HIR 的示例 -``` erg +```erg v = ![] for! 0..10, i => - v.push!i + v.push! i log v.sum() ``` -The AST generated from this code looks like this: +从此代码生成的 AST 如下所示: -``` erg +```erg AST(Module[ VarDef{ - sig: VarSignature { + sig: VarSignature{ pat: VarPattern::Ident(None, VarName("v")), spec_t: None, }, op: "=", body: Block[ - Unary Op { + UnaryOp{ 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: [ - Param Signature { + ParamSignature{ 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[ ]) ``` -And the HIR generated from the AST looks like this: +从 AST 生成的 HIR 如下所示: -``` 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: [ - Param Signature { + ParamSignature{ 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[ ]) ``` -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 +对象类型被推断为尽可能小。 另一方面,子例程推断实现存在的类型 +因此,实际参数的类型和形式参数的类型可能不匹配 \ No newline at end of file From 51de3c9d5a9074241f55c043b9951b384836b258 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 12:01:06 +0800 Subject: [PATCH 07/42] Set Erg's markdown snippet highlighting to Python --- compiler/erg_compiler/context/compare.rs | 6 +- compiler/erg_compiler/context/inquire.rs | 6 +- compiler/erg_compiler/context/mod.rs | 4 +- compiler/erg_compiler/context/tyvar.rs | 6 +- compiler/erg_compiler/effectcheck.rs | 6 +- compiler/erg_compiler/varinfo.rs | 2 +- compiler/erg_parser/ast.rs | 2 +- compiler/erg_parser/desugar.rs | 4 +- doc/EN/API/types/classes/Kind(N).md | 2 +- doc/EN/compiler/errors.md | 8 +- doc/EN/compiler/parsing.md | 4 +- doc/EN/python/class_system.md | 4 +- doc/EN/syntax/00_basic.md | 16 ++-- doc/EN/syntax/01_literal.md | 38 ++++----- doc/EN/syntax/02_name.md | 30 +++---- doc/EN/syntax/03_declaration.md | 8 +- doc/EN/syntax/04_function.md | 56 ++++++------- doc/EN/syntax/05_builtin_funcs.md | 8 +- doc/EN/syntax/07_side_effect.md | 18 ++--- doc/EN/syntax/08_procedure.md | 2 +- doc/EN/syntax/09_builtin_procs.md | 2 +- doc/EN/syntax/10_array.md | 10 +-- doc/EN/syntax/11_tuple.md | 24 +++--- doc/EN/syntax/12_dict.md | 14 ++-- doc/EN/syntax/13_record.md | 26 +++---- doc/EN/syntax/16_iterator.md | 8 +- doc/EN/syntax/17_mutability.md | 14 ++-- doc/EN/syntax/22_subroutine.md | 12 +-- doc/EN/syntax/24_module.md | 4 +- doc/EN/syntax/32_integration_with_Python.md | 10 +-- doc/EN/syntax/33_package_system.md | 8 +- doc/EN/syntax/34_generator.md | 6 +- doc/EN/syntax/type/01_type_system.md | 30 +++---- doc/EN/syntax/type/02_basic.md | 28 +++---- doc/EN/syntax/type/03_trait.md | 26 +++---- doc/EN/syntax/type/04_class.md | 36 ++++----- doc/EN/syntax/type/05_inheritance.md | 26 +++---- doc/EN/syntax/type/06_nst_vs_sst.md | 2 +- doc/EN/syntax/type/07_patch.md | 28 +++---- doc/EN/syntax/type/10_interval.md | 8 +- doc/EN/syntax/type/11_enum.md | 12 +-- doc/EN/syntax/type/12_refinement.md | 12 +-- doc/EN/syntax/type/13_algebraic.md | 12 +-- doc/EN/syntax/type/15_quantified.md | 46 +++++------ doc/EN/syntax/type/16_subtyping.md | 12 +-- doc/EN/syntax/type/17_type_casting.md | 8 +- doc/EN/syntax/type/advanced/erasure.md | 8 +- doc/EN/syntax/type/advanced/existential.md | 8 +- doc/EN/syntax/type/advanced/mut_struct.md | 6 +- doc/EN/syntax/type/advanced/newtype.md | 4 +- doc/EN/syntax/type/advanced/overloading.md | 14 ++-- doc/EN/syntax/type/advanced/phantom.md | 10 +-- doc/EN/syntax/type/advanced/projection.md | 4 +- .../type/advanced/quantified_dependent.md | 6 +- doc/EN/syntax/type/advanced/shared.md | 8 +- doc/EN/tips.md | 22 +++--- doc/JA/API/funcs.md | 12 +-- doc/JA/API/modules/external/alstruct.md | 10 +-- doc/JA/API/modules/repl.md | 2 +- doc/JA/API/modules/unit.md | 4 +- doc/JA/API/modules/unsound.md | 2 +- doc/JA/API/procs.md | 4 +- doc/JA/API/special.md | 20 ++--- doc/JA/API/types/classes/ArrayWithLen(T,N).md | 6 +- doc/JA/API/types/classes/Function(N).md | 2 +- doc/JA/API/types/classes/IntRange.md | 4 +- doc/JA/API/types/classes/Interval.md | 4 +- doc/JA/API/types/classes/Kind(N).md | 2 +- doc/JA/API/types/classes/Nat.md | 4 +- doc/JA/API/types/classes/Never.md | 2 +- doc/JA/API/types/classes/Option.md | 2 +- doc/JA/API/types/classes/Record.md | 2 +- doc/JA/API/types/classes/Result.md | 2 +- doc/JA/API/types/classes/Subroutine.md | 2 +- doc/JA/API/types/classes/Tensor.md | 4 +- doc/JA/API/types/classes/TransCell(T).md | 2 +- doc/JA/API/types/classes/Tuple.md | 4 +- doc/JA/API/types/traits/Add(R,O).md | 8 +- doc/JA/API/types/traits/Div(R,O).md | 2 +- doc/JA/API/types/traits/Num.md | 2 +- doc/JA/API/types/traits/SafeDiv(R,O).md | 2 +- doc/JA/API/types/traits/Sample.md | 4 +- doc/JA/API/types/traits/Unpack.md | 2 +- doc/JA/compiler/errors.md | 8 +- doc/JA/compiler/hir.md | 6 +- doc/JA/compiler/inference.md | 78 +++++++++---------- doc/JA/compiler/parsing.md | 4 +- doc/JA/compiler/refinement_subtyping.md | 2 +- doc/JA/compiler/trait_method_resolving.md | 14 ++-- doc/JA/compiler/transpile.md | 8 +- doc/JA/dev_guide/faq_syntax.md | 8 +- doc/JA/dev_guide/terms.md | 6 +- doc/JA/dev_guide/unify_terms.md | 2 +- doc/JA/migration_from_py.md | 4 +- doc/JA/python/class_system.md | 4 +- doc/JA/syntax/00_basic.md | 16 ++-- doc/JA/syntax/01_literal.md | 38 ++++----- doc/JA/syntax/02_name.md | 30 +++---- doc/JA/syntax/03_declaration.md | 8 +- doc/JA/syntax/04_function.md | 56 ++++++------- doc/JA/syntax/05_builtin_funcs.md | 8 +- doc/JA/syntax/06_operator.md | 4 +- doc/JA/syntax/07_side_effect.md | 18 ++--- doc/JA/syntax/08_procedure.md | 2 +- doc/JA/syntax/09_builtin_procs.md | 2 +- doc/JA/syntax/10_array.md | 10 +-- doc/JA/syntax/11_tuple.md | 24 +++--- doc/JA/syntax/12_dict.md | 14 ++-- doc/JA/syntax/13_record.md | 26 +++---- doc/JA/syntax/14_set.md | 10 +-- doc/JA/syntax/16_iterator.md | 8 +- doc/JA/syntax/17_mutability.md | 14 ++-- doc/JA/syntax/18_ownership.md | 12 +-- doc/JA/syntax/19_visibility.md | 34 ++++---- doc/JA/syntax/20_naming_rule.md | 10 +-- doc/JA/syntax/21_lambda.md | 18 ++--- doc/JA/syntax/22_subroutine.md | 12 +-- doc/JA/syntax/23_closure.md | 14 ++-- doc/JA/syntax/24_module.md | 8 +- doc/JA/syntax/25_object_system.md | 4 +- doc/JA/syntax/26_pattern_matching.md | 24 +++--- doc/JA/syntax/27_comprehension.md | 6 +- doc/JA/syntax/28_spread_syntax.md | 8 +- doc/JA/syntax/29_decorator.md | 14 ++-- doc/JA/syntax/30_error_handling.md | 8 +- doc/JA/syntax/31_pipeline.md | 4 +- doc/JA/syntax/32_integration_with_Python.md | 10 +-- doc/JA/syntax/33_package_system.md | 8 +- doc/JA/syntax/34_generator.md | 6 +- doc/JA/syntax/container_ownership.md | 6 +- doc/JA/syntax/quick_tour.md | 50 ++++++------ doc/JA/syntax/type/01_type_system.md | 30 +++---- doc/JA/syntax/type/02_basic.md | 28 +++---- doc/JA/syntax/type/03_trait.md | 26 +++---- doc/JA/syntax/type/04_class.md | 36 ++++----- doc/JA/syntax/type/05_inheritance.md | 26 +++---- doc/JA/syntax/type/06_nst_vs_sst.md | 2 +- doc/JA/syntax/type/07_patch.md | 28 +++---- doc/JA/syntax/type/08_value.md | 4 +- doc/JA/syntax/type/10_interval.md | 8 +- doc/JA/syntax/type/11_enum.md | 12 +-- doc/JA/syntax/type/12_refinement.md | 12 +-- doc/JA/syntax/type/13_algebraic.md | 12 +-- doc/JA/syntax/type/14_dependent.md | 10 +-- doc/JA/syntax/type/15_quantified.md | 46 +++++------ doc/JA/syntax/type/16_subtyping.md | 12 +-- doc/JA/syntax/type/17_type_casting.md | 8 +- doc/JA/syntax/type/18_mut.md | 26 +++---- doc/JA/syntax/type/19_bound.md | 2 +- doc/JA/syntax/type/advanced/GADTs.md | 8 +- doc/JA/syntax/type/advanced/_rank2type.md | 24 +++--- doc/JA/syntax/type/advanced/default_param.md | 4 +- doc/JA/syntax/type/advanced/erasure.md | 8 +- doc/JA/syntax/type/advanced/existential.md | 8 +- doc/JA/syntax/type/advanced/keyword_param.md | 6 +- doc/JA/syntax/type/advanced/kind.md | 26 +++---- doc/JA/syntax/type/advanced/marker_trait.md | 8 +- doc/JA/syntax/type/advanced/mut_struct.md | 6 +- doc/JA/syntax/type/advanced/newtype.md | 4 +- doc/JA/syntax/type/advanced/overloading.md | 14 ++-- doc/JA/syntax/type/advanced/phantom.md | 10 +-- doc/JA/syntax/type/advanced/projection.md | 4 +- .../type/advanced/quantified_dependent.md | 6 +- doc/JA/syntax/type/advanced/shared.md | 8 +- doc/JA/syntax/type/advanced/special.md | 6 +- doc/JA/syntax/type/advanced/typeof.md | 6 +- doc/JA/syntax/type/advanced/variance.md | 12 +-- doc/JA/syntax/type/advanced/widening.md | 14 ++-- doc/JA/tips.md | 22 +++--- doc/JA/tools/pack.md | 2 +- doc/JA/tools/test.md | 6 +- doc/zh_CN/API/funcs.md | 12 +-- doc/zh_CN/API/special.md | 16 ++-- .../API/types/classes/ArrayWithLen(T,N).md | 6 +- doc/zh_CN/API/types/classes/Function(N).md | 2 +- doc/zh_CN/API/types/classes/IntRange.md | 4 +- doc/zh_CN/API/types/classes/Interval.md | 4 +- doc/zh_CN/API/types/classes/Kind(N).md | 2 +- doc/zh_CN/API/types/classes/Nat.md | 4 +- doc/zh_CN/API/types/classes/Never.md | 2 +- doc/zh_CN/API/types/classes/Option.md | 2 +- doc/zh_CN/API/types/classes/Record.md | 2 +- doc/zh_CN/API/types/classes/Result.md | 2 +- doc/zh_CN/API/types/classes/Subroutine.md | 2 +- doc/zh_CN/API/types/classes/Tensor.md | 4 +- doc/zh_CN/API/types/classes/TransCell(T).md | 2 +- doc/zh_CN/API/types/classes/Tuple.md | 4 +- doc/zh_CN/API/types/traits/Add(R,O).md | 8 +- doc/zh_CN/API/types/traits/Div(R,O).md | 2 +- doc/zh_CN/API/types/traits/Num.md | 2 +- doc/zh_CN/API/types/traits/SafeDiv(R,O).md | 2 +- doc/zh_CN/API/types/traits/Sample.md | 4 +- doc/zh_CN/API/types/traits/Unpack.md | 2 +- doc/zh_CN/compiler/errors.md | 8 +- doc/zh_CN/compiler/hir.md | 6 +- doc/zh_CN/compiler/parsing.md | 4 +- doc/zh_CN/dev_guide/faq_syntax.md | 8 +- doc/zh_CN/python/class_system.md | 4 +- doc/zh_CN/syntax/00_basic.md | 16 ++-- doc/zh_CN/syntax/01_literal.md | 38 ++++----- doc/zh_CN/syntax/02_name.md | 30 +++---- doc/zh_CN/syntax/03_declaration.md | 8 +- doc/zh_CN/syntax/04_function.md | 56 ++++++------- doc/zh_CN/syntax/05_builtin_funcs.md | 8 +- doc/zh_CN/syntax/07_side_effect.md | 18 ++--- doc/zh_CN/syntax/08_procedure.md | 2 +- doc/zh_CN/syntax/09_builtin_procs.md | 2 +- doc/zh_CN/syntax/10_array.md | 10 +-- doc/zh_CN/syntax/11_tuple.md | 24 +++--- doc/zh_CN/syntax/12_dict.md | 14 ++-- doc/zh_CN/syntax/13_record.md | 26 +++---- doc/zh_CN/syntax/16_iterator.md | 8 +- doc/zh_CN/syntax/17_mutability.md | 14 ++-- doc/zh_CN/syntax/22_subroutine.md | 12 +-- doc/zh_CN/syntax/24_module.md | 4 +- .../syntax/32_integration_with_Python.md | 10 +-- doc/zh_CN/syntax/33_package_system.md | 8 +- doc/zh_CN/syntax/34_generator.md | 6 +- doc/zh_CN/syntax/type/01_type_system.md | 30 +++---- doc/zh_CN/syntax/type/02_basic.md | 28 +++---- doc/zh_CN/syntax/type/03_trait.md | 26 +++---- doc/zh_CN/syntax/type/04_class.md | 36 ++++----- doc/zh_CN/syntax/type/05_inheritance.md | 26 +++---- doc/zh_CN/syntax/type/06_nst_vs_sst.md | 2 +- doc/zh_CN/syntax/type/07_patch.md | 28 +++---- doc/zh_CN/syntax/type/10_interval.md | 8 +- doc/zh_CN/syntax/type/11_enum.md | 12 +-- doc/zh_CN/syntax/type/12_refinement.md | 12 +-- doc/zh_CN/syntax/type/13_algebraic.md | 12 +-- doc/zh_CN/syntax/type/15_quantified.md | 46 +++++------ doc/zh_CN/syntax/type/16_subtyping.md | 12 +-- doc/zh_CN/syntax/type/17_type_casting.md | 8 +- doc/zh_CN/syntax/type/advanced/erasure.md | 8 +- doc/zh_CN/syntax/type/advanced/existential.md | 8 +- doc/zh_CN/syntax/type/advanced/mut_struct.md | 6 +- doc/zh_CN/syntax/type/advanced/newtype.md | 4 +- doc/zh_CN/syntax/type/advanced/overloading.md | 14 ++-- doc/zh_CN/syntax/type/advanced/phantom.md | 10 +-- doc/zh_CN/syntax/type/advanced/projection.md | 4 +- .../type/advanced/quantified_dependent.md | 6 +- doc/zh_CN/syntax/type/advanced/shared.md | 8 +- doc/zh_CN/tips.md | 22 +++--- 242 files changed, 1449 insertions(+), 1449 deletions(-) diff --git a/compiler/erg_compiler/context/compare.rs b/compiler/erg_compiler/context/compare.rs index 41d1e1d3..9cd8bc3a 100644 --- a/compiler/erg_compiler/context/compare.rs +++ b/compiler/erg_compiler/context/compare.rs @@ -334,7 +334,7 @@ impl Context { (Maybe, false) } - /// ```erg + /// ```python /// assert sup_conforms(?E(<: Eq(?E)), base: Nat, sup_trait: Eq(Nat)) /// assert sup_conforms(?E(<: Eq(?R)), base: T, sup_trait: Eq(U)) /// ``` @@ -360,7 +360,7 @@ impl Context { } /// lhs :> rhs? - /// ```erg + /// ```python /// assert supertype_of(Int, Nat) # i: Int = 1 as Nat /// assert supertype_of(Bool, Bool) /// ``` @@ -815,7 +815,7 @@ impl Context { } /// see doc/LANG/compiler/refinement_subtyping.md - /// ```erg + /// ```python /// assert is_super_pred({I >= 0}, {I == 0}) /// assert is_super_pred({T >= 0}, {I == 0}) /// assert !is_super_pred({I < 0}, {I == 0}) diff --git a/compiler/erg_compiler/context/inquire.rs b/compiler/erg_compiler/context/inquire.rs index e2f28a03..a1d74570 100644 --- a/compiler/erg_compiler/context/inquire.rs +++ b/compiler/erg_compiler/context/inquire.rs @@ -391,7 +391,7 @@ impl Context { /// Just return input if the type is already concrete (or there is still a type variable that cannot be resolved) /// 単相化されたトレイトを具体的な型に置換する /// 既に具体的な型である(か、まだ型変数があり解決できない)場合はそのまま返す - /// ```erg + /// ```python /// instantiate_trait(Add(Int)) => Ok(Int) /// instantiate_trait(Array(Add(Int), 2)) => Ok(Array(Int, 2)) /// instantiate_trait(Array(Int, 2)) => Ok(Array(Int, 2)) @@ -502,7 +502,7 @@ impl Context { } /// e.g. - /// ```erg + /// ```python /// substitute_call(instance: ((?T, ?U) -> ?T), [Int, Str], []) => instance: (Int, Str) -> Int /// substitute_call(instance: ((?T, Int) -> ?T), [Int, Nat], []) => instance: (Int, Int) -> Str /// substitute_call(instance: ((?M(: Nat)..?N(: Nat)) -> ?M+?N), [1..2], []) => instance: (1..2) -> {3} @@ -889,7 +889,7 @@ impl Context { /// C3 linearization requires prior knowledge of inter-type dependencies, and cannot be used for Erg structural subtype linearization /// /// Algorithm: - /// ```erg + /// ```python /// [Int, Str, Nat, Never, Obj, Str!, Module] /// => [], [Int, Str, Nat, Never, Obj, Str!, Module] /// => [[Int]], [Str, Nat, Never, Obj, Str!, Module] diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index b845787d..7913bc94 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -104,7 +104,7 @@ impl TyParamIdx { } } - /// ```erg + /// ```python /// Nested(Nth(1), 0).select(F(X, G(Y, Z))) == Y /// ``` pub fn select(self, from: &Type) -> Type { @@ -246,7 +246,7 @@ pub struct Context { pub(crate) decls: Dict, // stores defined names // 型の一致はHashMapでは判定できないため、keyはVarNameとして1つずつ見ていく - /// ```erg + /// ```python /// f [x, y], z = ... /// ``` /// => params: vec![(None, [T; 2]), (Some("z"), U)] diff --git a/compiler/erg_compiler/context/tyvar.rs b/compiler/erg_compiler/context/tyvar.rs index 8a86b084..e717eedd 100644 --- a/compiler/erg_compiler/context/tyvar.rs +++ b/compiler/erg_compiler/context/tyvar.rs @@ -81,7 +81,7 @@ impl Context { } /// see doc/LANG/compiler/inference.md#一般化 for details - /// ```erg + /// ```python /// generalize_t(?T) == 'T: Type /// generalize_t(?T(<: Nat) -> ?T) == |'T <: Nat| 'T -> 'T /// generalize_t(?T(<: Eq(?T(<: Eq(?T(<: ...)))) -> ?T) == |'T <: Eq('T)| 'T -> 'T @@ -258,7 +258,7 @@ impl Context { } /// e.g. - /// ```erg + /// ```python /// deref_tyvar(?T(:> Never, <: Int)[n]): ?T => Int (if self.level <= n) /// deref_tyvar((Int)): (Int) => Int /// ``` @@ -983,7 +983,7 @@ impl Context { /// When comparing arguments and parameter, the left side (`sub`) is the argument (found) and the right side (`sup`) is the parameter (expected) /// /// The parameter type must be a supertype of the argument type - /// ```erg + /// ```python /// sub_unify({I: Int | I == 0}, ?T(<: Ord)): (/* OK */) /// sub_unify(Int, ?T(:> Nat)): (?T :> Int) /// sub_unify(Nat, ?T(:> Int)): (/* OK */) diff --git a/compiler/erg_compiler/effectcheck.rs b/compiler/erg_compiler/effectcheck.rs index 4c8a1b11..dfc7aea3 100644 --- a/compiler/erg_compiler/effectcheck.rs +++ b/compiler/erg_compiler/effectcheck.rs @@ -153,7 +153,7 @@ impl SideEffectChecker { /// returns effects, purity violations will be appended to `self.errs`. /// /// causes side-effects: - /// ```erg + /// ```python /// p!() // 1 side-effect /// p!(q!()) // 2 side-effects /// x = @@ -161,12 +161,12 @@ impl SideEffectChecker { /// y + 1 // 1 side-effect /// ``` /// causes no side-effects: - /// ```erg + /// ```python /// q! = p! /// y = f(p!) /// ``` /// purity violation: - /// ```erg + /// ```python /// for iter, i -> print! i /// ``` fn check_expr(&mut self, expr: &Expr) { diff --git a/compiler/erg_compiler/varinfo.rs b/compiler/erg_compiler/varinfo.rs index 263d58ae..f44305c3 100644 --- a/compiler/erg_compiler/varinfo.rs +++ b/compiler/erg_compiler/varinfo.rs @@ -35,7 +35,7 @@ impl Mutability { use Mutability::*; /// e.g. -/// ```erg +/// ```python /// K(T, [U, V]) = ... /// U.idx == Nested(Just(1), 0) /// ``` diff --git a/compiler/erg_parser/ast.rs b/compiler/erg_parser/ast.rs index aa11ea9e..31cab944 100644 --- a/compiler/erg_parser/ast.rs +++ b/compiler/erg_parser/ast.rs @@ -2633,7 +2633,7 @@ impl Def { } /// e.g. -/// ```erg +/// ```python /// T = Class ... /// T. /// x = 1 diff --git a/compiler/erg_parser/desugar.rs b/compiler/erg_parser/desugar.rs index a67a24a4..6a2748c6 100644 --- a/compiler/erg_parser/desugar.rs +++ b/compiler/erg_parser/desugar.rs @@ -311,12 +311,12 @@ impl Desugarer { todo!() } - /// ```erg + /// ```python /// @deco /// f x = ... /// ``` /// ↓ - /// ```erg + /// ```python /// _f x = ... /// f = deco _f /// ``` diff --git a/doc/EN/API/types/classes/Kind(N).md b/doc/EN/API/types/classes/Kind(N).md index 4a72aec9..b3103d53 100644 --- a/doc/EN/API/types/classes/Kind(N).md +++ b/doc/EN/API/types/classes/Kind(N).md @@ -1,5 +1,5 @@ # Kind N: Nat -```erg +```python Kind N: Nat = (Type; N) -> Type ``` diff --git a/doc/EN/compiler/errors.md b/doc/EN/compiler/errors.md index da4af20b..32a8efe0 100644 --- a/doc/EN/compiler/errors.md +++ b/doc/EN/compiler/errors.md @@ -24,7 +24,7 @@ Raised when an attempt is made to obtain another variable reference while a borr Raised when there is an apparent non-stop cycle. -```erg +```python i: Int = i f(): Int = g() @@ -91,7 +91,7 @@ Raised when the object type does not match. 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 +```python i = 0 f x = y = i + x @@ -102,7 +102,7 @@ f x = 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 +```python f() = g() g() = f() ``` @@ -113,7 +113,7 @@ g() = f() This happens when syntactically sound but redundant or uncommon code is detected (e.g., unnecessary `()`). -```erg +```python if (True): # SyntaxWarning: unnecessary parentheses ... ``` diff --git a/doc/EN/compiler/parsing.md b/doc/EN/compiler/parsing.md index 59d11bac..fbc7fc76 100644 --- a/doc/EN/compiler/parsing.md +++ b/doc/EN/compiler/parsing.md @@ -5,7 +5,7 @@ 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 +```python f +1 == f(+1) f + 1 == `+`(f, 1) f (1,) == f((1,)) @@ -20,7 +20,7 @@ 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 +```python # 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` is the right-hand side value, but i to the left of -> is the left-hand side value diff --git a/doc/EN/python/class_system.md b/doc/EN/python/class_system.md index 89b6d2e9..fa6c7f10 100644 --- a/doc/EN/python/class_system.md +++ b/doc/EN/python/class_system.md @@ -51,7 +51,7 @@ TypeError: can only concatenate str (not "int") to str Erg statically checks for consistency with the parent class. The `Override` decorator must be given when overriding, and the type of the overriding function must be a subtype of the type of the function being overridden. -```erg +```python >>> C = Class() ... .f self = 1 ... .g self = self.f() + 1 @@ -81,7 +81,7 @@ f(c) f(1) # TypeError ``` -```erg +```python # f: |T, X <: {.m = Self.() -> T}| X -> T f(x) = x.m() diff --git a/doc/EN/syntax/00_basic.md b/doc/EN/syntax/00_basic.md index 4d643c3b..651caf2f 100644 --- a/doc/EN/syntax/00_basic.md +++ b/doc/EN/syntax/00_basic.md @@ -11,7 +11,7 @@ This document describes the basic syntax of Erg. The [Standard API](./API/index. First, let's do "Hello World". -```erg +```python print!("Hello, World!") ``` @@ -19,7 +19,7 @@ This is almost identical to Python and other languages in the same family. The m In Erg, parentheses `()` can be omitted unless there is some confusion in interpretation. The omission of parentheses is similar to Ruby, but it is not possible to omit parentheses that can be interpreted in more than one way. -```erg +```python print! "Hello, World!" # OK print! "Hello,", "World!" # OK print!() # OK @@ -70,7 +70,7 @@ hello, world! The code after `#` is ignored as a comment. Use this to explain the intent of the code or to temporarily disable the code. -```erg +```python # Comment # `#` and after are ignored until a new line is inserted #[ @@ -85,7 +85,7 @@ A script is a series of expressions. An expression is something that can be calc Each expression is separated by a separator - either a new line or a semicolon `;`-. Erg scripts are basically evaluated from left to right, top to bottom. -```erg +```python n = 1 # assignment expression f(1, 2) # function-call expression 1 + 1 # operator-call expression @@ -95,7 +95,7 @@ f(1, 2); 1 + 1 As shown below, there is a syntax called instant block that takes the last expression evaluated in the block as the value of the variable. This differs from a function with no arguments, which does not add `()`. Note that instant blocks are evaluated only once on the fly. -```erg +```python i = x = 1 x + 1 @@ -104,7 +104,7 @@ assert i == 2 This cannot be accomplished with a semicolon (`;`). -```erg +```python i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses ``` @@ -112,7 +112,7 @@ i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses Erg, like Python, uses indentation to represent blocks. There are five operators (special forms) that trigger the start of a block: `=`, `->`, `=>`, `do`, and `do!` (In addition, `:` and `|`, although not operators, also produce indentation). The meanings of each are described later. -```erg +```python f x, y = x + y @@ -131,7 +131,7 @@ ans = match x: If a line is too long, it can be broken using `\`. -```erg +```python # this does not means `x + y + z` but means `x; +y; +z` x + y diff --git a/doc/EN/syntax/01_literal.md b/doc/EN/syntax/01_literal.md index f8336328..3411024d 100644 --- a/doc/EN/syntax/01_literal.md +++ b/doc/EN/syntax/01_literal.md @@ -4,19 +4,19 @@ ### Int Literal -```erg +```python 0, -0, 1, -1, 2, -2, 3, -3, ... ``` ### Ratio Literal -```erg +```python 0.00, -0.0, 0.1, 400.104, ... ``` If a `Ratio` literal has an integer or decimal part of `0`, you can omit the `0`. -```erg +```python assert 1.0 == 1. assert 0.5 == .5 ``` @@ -29,14 +29,14 @@ Subsequent documents may use `assert` to indicate that the results are equal. Any Unicode-representable string can be used. Unlike Python, quotation marks cannot be enclosed in `'`. If you want to use `"` in a string, use `\"`. -```erg +```python "", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "السَّلَامُ عَلَيْكُمْ", ... ``` `{}` allows you to embed expressions in strings. This is called string interpolation. If you want to output `{`, `}` itself, use `\{`, `\}`. -```erg +```python assert "1 + 1 is 2" == "{1} + {1} is {1+1}" s = "1+1" assert "\{1+1}\" == "\{{s}\}" @@ -47,11 +47,11 @@ assert "\{1+1}\" == "\{{s}\}" This is a literal representing exponential notation often used in academic calculations. It is an instance of type ``Ratio``. The notation is the same as in Python. -```erg +```python 1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ... ``` -```erg +```python assert 1e-10 == 0.0000000001 ``` @@ -61,37 +61,37 @@ Each of these literals has its own documentation describing them separately, so ### [Array Literal](./10_array.md) -```erg +```python [], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ... ``` ### [Dict Literal](./11_dict.md) -```erg +```python {:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ... ``` ### [Tuple Literal](./12_tuple.md) -```erg +```python (), (1, 2, 3), (1, "hello", True), ... ``` ### [Record Literal](./13_record.md) -```erg +```python {=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ... ``` ### [Set Literal](./14_set.md) -```erg +```python {}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ... ``` As a difference from `Array` literals, duplicate elements are removed in `Set`. -```erg +```python assert {1, 2, 1} == {1, 2} ``` @@ -99,19 +99,19 @@ assert {1, 2, 1} == {1, 2} ## Boolean Object -```erg +```python True, False ``` ### None Object -```erg +```python None ``` ## Range Object -```erg +```python assert 0..5 == {1, 2, 3, 4, 5} assert 0..10 in 5 assert 0..<10 notin 10 @@ -120,7 +120,7 @@ assert 0..9 == 0..<10 ## Float Object -```erg +```python assert 0.0f64 == 0 assert 0.0f32 == 0.0f64 ``` @@ -129,7 +129,7 @@ Float objects are constructed by multiplying a `Ratio` object by `f64`, which is ## Complex Object -```erg +```python 1+2im, 0.4-1.2im, 0im, im ``` @@ -139,7 +139,7 @@ A `Complex` object is simply an arithmetic combination of an imaginary unit obje In Erg, you can omit the `*` to indicate multiplication as long as there is no confusion in interpretation. However, the combined strength of the operators is set stronger than `*`. -```erg +```python # same as `assert (1*m) / (1*s) == 1*(m/s)` assert 1m / 1s == 1 (m/s) ``` diff --git a/doc/EN/syntax/02_name.md b/doc/EN/syntax/02_name.md index 8b87e4a2..63138c32 100644 --- a/doc/EN/syntax/02_name.md +++ b/doc/EN/syntax/02_name.md @@ -5,7 +5,7 @@ Variables are a type of algebra; algebra in Erg - sometimes simply referred to a A variable is defined as follows. The `n` part is called the variable name (or identifier), `=` is the assignment operator, and the `1` part is the assigned value. -```erg +```python n = 1 ``` @@ -15,13 +15,13 @@ We have just said that `1` is an object. We will discuss what an object is later If you want to specify the "type" of a variable, do the following. The type is roughly the set to which an object belongs, as will be explained later. Here we specify that `n` is a natural number (`Nat`) type. -```erg +```python n: Nat = 1 ``` Note that, unlike other languages, multiple assignments are not allowed. -```erg +```python # NG l1 = l2 = [1, 2, 3] # SyntaxError: multiple assignment not allowed # OK @@ -31,7 +31,7 @@ l2 = l1.clone() It is also not possible to reassign to a variable. The syntax that can be used instead, to hold mutable states, are described later. -```erg +```python i = 1 i = i + 1 # AssignError: cannot assign twice ``` @@ -40,7 +40,7 @@ You can define a variable with the same name in the inner scope, but you are onl Note that this is a different behavior than the Python "statement" scope. This kind of functionality is generally referred to as shadowing. However, unlike shadowing in other languages, you cannot shadow in the same scope. -```erg +```python x = 0 # x = 1 # AssignError: cannot assign twice if x.is_zero(), do: @@ -51,7 +51,7 @@ assert x == 0 The following may seem possible at first glance, but it is still not possible. This is a design decision, not a technical constraint. -```erg +```python x = 0 if x.is_zero(), do: x = x + 1 # NameError: cannot define variables refer to variables with the same name @@ -64,7 +64,7 @@ assert x == 0 Constants are also a type of algebra. If you start an identifier with a capital letter, it is treated as a constant. They are called constants because once defined, they do not change. The `N` part is called the constant name (or identifier). Otherwise, it is the same as a variable. -```erg +```python N = 0 if True, do: N = 1 # AssignError: constants cannot be shadowed @@ -77,13 +77,13 @@ For example, constants are used for mathematical constants, information about ex It is common practice to use all-caps (style in which all letters are capitalized) for identifiers of objects other than [types](./type/01_type_system.md). -```erg +```python PI = 3.141592653589793 URL = "https://example.com" CHOICES = ["a", "b", "c"] ``` -```erg +```python PI = 3.141592653589793 match! x: PI => print! "π" @@ -95,7 +95,7 @@ The above code prints `π` when `x` is `3.141592653589793`. If `x` is changed to Some objects cannot be bound as constants. Mutable objects, for example. Mutable objects are objects whose states can be changed, as described in detail later. This is because of the rule that only constant expressions can be assigned to constants. Constant expressions are also discussed later. -```erg +```python X = 1 # OK X = !1 # TypeError: cannot define Int! object as a constant ``` @@ -104,7 +104,7 @@ X = !1 # TypeError: cannot define Int! object as a constant You can delete an variable by using the `Del` function. All other variables that depend on the variable (that is, that refer directly to the value of the variable) are also removed. -```erg +```python x = 1 y = 2 Z = 3 @@ -119,7 +119,7 @@ f(2) # NameError: f is not defined (deleted in line 6) Note that `Del` can only delete variables defined in the user-defined module. Built-in constants such as `True` cannot be deleted. -```erg +```python Del True # TypeError: cannot delete built-in constants Del print! # TypeError: cannot delete built-in variables ``` @@ -128,7 +128,7 @@ Del print! # TypeError: cannot delete built-in variables Note that `x == a` is not necessarily true when `x = a`. An example is `Float.NaN`. This is the formal specification of floating-point numbers as defined by IEEE 754. -```erg +```python x = Float.NaN assert x ! = NaN assert x ! = x @@ -136,7 +136,7 @@ assert x ! = x There are other objects for which no equivalence relation is defined in the first place. -```erg +```python f = x -> x**2 + 2x + 1 g = x -> (x + 1)**2 f == g # TypeError: cannot compare function objects @@ -149,7 +149,7 @@ C == D # TypeError: cannot compare class objects Strictly speaking, `=` does not assign the right-hand side value directly to the left-hand side identifier. In the case of function and class objects, "modification" such as giving variable name information to the object is performed. However, this is not the case for structural types. -```erg +```python f x = x print! f # g x = x + 1 diff --git a/doc/EN/syntax/03_declaration.md b/doc/EN/syntax/03_declaration.md index b609984e..1548c120 100644 --- a/doc/EN/syntax/03_declaration.md +++ b/doc/EN/syntax/03_declaration.md @@ -4,7 +4,7 @@ Declaration is the syntax for specifying the type of variable to be used. Declarations can be made anywhere in the code, but declarations alone do not refer to the variables. They must be initialized. After the assignment, the declaration can be checked to ensure that the type is compatible with the object to which it is assigned. -```erg +```python i: Int # Can be declared at the same time as the assignment, like i: Int = 2 i = 2 @@ -17,7 +17,7 @@ i: {2} Declaration after assignment is similar to type checking by `assert`, but has the feature that it is checked at compile time. Type checking by `assert` at runtime can be checked for "may be type Foo", but type checking by `:` at compile time is strict: if the type is not determined to be "type Foo", it will not pass the check and an error will occur. -```erg +```python i = (-1..10).sample! assert i in Nat # this may pass i: Int # this will pass @@ -26,14 +26,14 @@ i: Nat # this will not pass (-1 is not an element of Nat) Functions can be declared in 2 different ways. -```erg +```python f: (x: Int, y: Int) -> Int f: (Int, Int) -> Int ``` If you declare the argument names explicitly, a type error will result if the names are different at definition time. If you want to give the argument names arbitrary names, you can declare them in the second way. In that case, only the method name and its type will be seen by type checking. -```erg +```python T = Trait { .f = (x: Int, y: Int): Int } diff --git a/doc/EN/syntax/04_function.md b/doc/EN/syntax/04_function.md index be531d30..8e93f12b 100644 --- a/doc/EN/syntax/04_function.md +++ b/doc/EN/syntax/04_function.md @@ -2,7 +2,7 @@ A function is a block that takes an "argument", processes it, and returns it as a "return value". It is defined as follows. -```erg +```python add x, y = x + y # or add(x, y) = x + y @@ -13,7 +13,7 @@ In contrast, the objects passed to a function are called arguments. The function `add` is a function that takes `x` and `y` as parameters and returns the sum of them, `x + y`. The defined function can be called (applied/invoked) as follows. -```erg +```python add 1, 2 # or add(1, 2) @@ -23,16 +23,16 @@ add(1, 2) Functions are invoked like `f x, y, ...`, but if there are too many arguments for a single line, they can be applied using `:` (colon). -```erg +```python f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4 ``` -```erg +```python f some_long_name_variable_1 + some_long_name_variable_2: some_long_name_variable_3 * some_long_name_variable_4 ``` -```erg +```python f: some_long_name_variable_1 + some_long_name_variable_2 some_long_name_variable_3 * some_long_name_variable_4 @@ -40,7 +40,7 @@ f: All three codes above mean the same thing. This style is also useful when using `if` functions, for example. -```erg +```python result = if Bool.sample!(): do: log "True was chosen" @@ -57,19 +57,19 @@ After `:`, no code other than comments may be written, and must always be on a n If a function is defined with a large number of parameters, there is a danger of passing the arguments in the wrong order. In such cases, it is safe to call the function using keyword arguments. -```erg +```python f x, y, z, w, v, u: Int = ... ``` The functions defined above have many arguments and are arranged in a confusing order. You should not create such a function, but you may encounter such code when using code written by others. Therefore, we use keyword arguments. If you use keyword arguments, the values are passed from the name to the correct argument, even if they are in the wrong order. -```erg +```python f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3 ``` Note that keyword arguments and a new line immediately after the `:` are considered a colon-call style. -```erg +```python # means `f(x: y)` f x: y @@ -84,7 +84,7 @@ Default parameters are used when some parameters are mostly fixed and you want t Default parameters are specified by `:=`(walrus operator). If `base` is not specified, assign `math.E` to `base`. -```erg +```python math_log x: Ratio, base := math.E = ... assert math_log(100, 10) == 2 @@ -93,7 +93,7 @@ assert math_log(100) == math_log(100, math.E) Note that there is a distinction between specifying no argument and assigning `None`. -```erg +```python p! x := 0 = print! p!(2) # 2 p!() # 0 @@ -102,20 +102,20 @@ p!(None) # None Can also be used with type specification and patterns. -```erg +```python math_log x, base: Ratio := math.E = ... f [x, y] := [1, 2] = ... ``` However, within the default arguments, it is not possible to call the procedures (described later) or assign mutable objects. -```erg +```python f x := p! 1 = ... # NG ``` Also, the argument just defined cannot be used as the value passed to the default argument. -```erg +```python f x := 1, y := x = ... # NG ``` @@ -123,13 +123,13 @@ f x := 1, y := x = ... # NG The `log` function, which outputs a log (record) of its arguments, can take any number of arguments. -```erg +```python log "Hello", "World", "!" # Hello World ! ``` To define such a function, add `...` to a parameter. This way, the function receives arguments as a variable-length array. -```erg +```python f ...x = for x, i -> log i @@ -140,7 +140,7 @@ f 1, 2, 3, 4, 5 ## Function definition with multiple patterns -```erg +```python fib n: Nat = match n: 0 -> 0 @@ -150,7 +150,7 @@ fib n: Nat = Functions like the one above, where `match` appears directly under the definition, can be rewritten as follows. -```erg +```python fib 0 = 0 fib 1 = 1 fib(n: Nat): Nat = fib(n - 1) + fib(n - 2) @@ -160,7 +160,7 @@ Note that a function definition with multiple patterns is not so-called overload If instances of different classes are mixed, the last definition must specify that the function argument is of type `Or`. -```erg +```python f "aa" = ... f 1 = ... # `f x = ... ` is invalid @@ -169,7 +169,7 @@ f x: Int or Str = ... Also, like `match`, it must also be exhaustive. -```erg +```python fib 0 = 0 fib 1 = 1 # PatternError: pattern of fib's parameter is not exhaustive @@ -177,7 +177,7 @@ fib 1 = 1 However, it can be made exhaustive by explicitly specifying the type using the [refinement type](./type/12_refinement.md) described later. -```erg +```python fib: 0..1 -> 0..1 fib 0 = 0 fib 1 = 1 @@ -191,7 +191,7 @@ A recursive function is a function that includes itself in its definition. As a simple example, let us define a function `factorial` that performs a factorial calculation. Factorial is a computation that "multiplies all positive numbers less than or equal to". The factorial of 5 is `5*4*3*2*1 == 120`. -```erg +```python factorial 0 = 1 factorial 1 = 1 factorial(n: Nat): Nat = n * factorial(n - 1) @@ -205,7 +205,7 @@ Since the definition of `factorial` contains itself, `factorial` is a recursive As a reminder, if you do not add a type specification, it is inferred like this. -```erg +```python factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int factorial 0 = 1 factorial 1 = 1 @@ -214,7 +214,7 @@ factorial n = n * factorial(n - 1) However, even if you can reason about it, you should explicitly specify the type of the recursive function. In the example above, a code like ``factorial(-1)`` would work, but -```erg +```python factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ... ``` @@ -227,7 +227,7 @@ A function name begins with an uppercase letter to indicate a compile-time funct Compile-time functions are limited in what they can do. Only constant expressions can be used in compile-time functions, i.e., only some operators (such as quadrature, comparison, and type construction operations) and compile-time functions. Arguments to be passed must also be constant expressions. In return, the advantage is that the computation can be done at compile time. -```erg +```python Add(X, Y: Nat): Nat = X + Y assert Add(1, 2) == 3 @@ -241,7 +241,7 @@ Sin X = math.sin X # ConstantError: this function is not computable at compile t Compile-time functions are also used in polymorphic type definitions. -```erg +```python Option T: Type = T or NoneType Option: Type -> Type ``` @@ -250,7 +250,7 @@ Option: Type -> Type Erg does not define `==` for functions. This is because there is no structural equivalence algorithm for functions in general. -```erg +```python f = x: Int -> (x + 1)**2 g = x: Int -> x**2 + 2x + 1 @@ -269,7 +269,7 @@ assert (lambda x: x) ! = (lambda x: x) ## Appendix2: ()-completion -```erg +```python f x: Object = ... # will be completed to f(x: Object) = ... diff --git a/doc/EN/syntax/05_builtin_funcs.md b/doc/EN/syntax/05_builtin_funcs.md index f0b3075a..12aa1eeb 100644 --- a/doc/EN/syntax/05_builtin_funcs.md +++ b/doc/EN/syntax/05_builtin_funcs.md @@ -4,7 +4,7 @@ `if` is a function that changes processing depending on a condition. -```erg +```python result: Option Int = if! Bool.sample!(), do: log "True was chosen" 1 @@ -14,7 +14,7 @@ print! result # None (or 1) `.sample!()` returns a random set of values. If the return value is true, `print! "True"` is executed. You can also specify what to do if the condition is false; the second do block is called the else block. -```erg +```python result: Nat = if Bool.sample!(): do: log "True was chosen" @@ -27,7 +27,7 @@ print! result # 1 (or 0) If the process is a single line, you can omit indentation. -```erg +```python result = if Bool.sample!(): do 1 do 0 @@ -37,7 +37,7 @@ result = if Bool.sample!(): You can use `for` to write a repeating process. -```erg +```python match_s(ss: Iterator(Str), pat: Pattern): Option Str = for ss, s -> if pat.match(s).is_some(): diff --git a/doc/EN/syntax/07_side_effect.md b/doc/EN/syntax/07_side_effect.md index 342cae82..1037bb36 100644 --- a/doc/EN/syntax/07_side_effect.md +++ b/doc/EN/syntax/07_side_effect.md @@ -2,14 +2,14 @@ We have been neglecting to explain the meaning of the `!`, but now its meaning will finally be revealed. This `!` indicates that this object is a "procedure" with a "side-effect". A procedure is a function with a side-effect. -```erg +```python f x = print! x # EffectError: functions cannot be assigned objects with side effects # hint: change the name to 'f!' ``` The above code will result in a compile error. This is because you are using a procedure in a function. In such a case, you must define it as a procedure. -```erg +```python p! x = print! x ``` @@ -21,7 +21,7 @@ Procedures defined in this way also cannot be used within a function, so side-ef Functions and procedures each can be methods. Functional methods can only take immutable references to `self`, while procedural methods can take mutable references to `self`. The `self` is a special parameter, which in the context of a method refers to the calling object itself. The reference `self` cannot be assigned to any other variable. -```erg +```python C!. method ref self = x = self # OwnershipError: cannot move out 'self' @@ -30,7 +30,7 @@ C!. Procedural methods can also take [ownership](./18_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition. -```erg +```python n = 1 s = n.into(Str) # '1' n # ValueError: n was moved by .into (line 2) @@ -40,7 +40,7 @@ Only one procedural methods can have a mutable reference at any given time. In a Note, however, that it is possible to create (immutable/mutable) references from mutable references. This allows recursion and `print!` of `self` in procedural methods. -```erg +```python T -> T # OK (move) T -> Ref T # OK (move) T => Ref! T # OK (only once) @@ -63,14 +63,14 @@ There are procedures that for any given `x` will result in `p!(x) == p!(x)` (e.g An example of the former is `print!`, and an example of the latter is the following function. -```erg +```python nan _ = Float.NaN assert nan(1) ! = nan(1) ``` There are also objects, such as classes, for which equivalence determination itself is not possible. -```erg +```python T = Structural {i = Int} U = Structural {i = Int} assert T == U @@ -88,7 +88,7 @@ Back to the point: the precise definition of "side-effect" in Erg is As an example, consider the `print!` procedure. At first glance, `print!` does not seem to rewrite any variables. But if it were a function, it could rewrite outer variables, for example, with code like this: -```erg +```python camera = import "some_camera_module" ocr = import "some_ocr_module" @@ -107,7 +107,7 @@ The direct side-effect is caused by `cam.shot!()`, but obviously that informatio Nevertheless, there may be cases where you want to temporarily check a value in a function and do not want to add `!` in the related function just for that purpose. In such cases, the `log` function can be used. `log` prints the value after the entire code has been executed. In this way, side-effects are not propagated. -```erg +```python log "this will be printed after execution" print! "this will be printed immediately" # this will be printed immediately diff --git a/doc/EN/syntax/08_procedure.md b/doc/EN/syntax/08_procedure.md index 44363e46..a46e863a 100644 --- a/doc/EN/syntax/08_procedure.md +++ b/doc/EN/syntax/08_procedure.md @@ -3,7 +3,7 @@ Procedures are necessary when dealing with mutable objects, but having a mutable object as an argument does not necessarily make it a procedure. Here is a function takes a mutable object (not procedure). -```erg +```python peek_str s: Str! = log s ``` diff --git a/doc/EN/syntax/09_builtin_procs.md b/doc/EN/syntax/09_builtin_procs.md index 5a78d28e..eff9af73 100644 --- a/doc/EN/syntax/09_builtin_procs.md +++ b/doc/EN/syntax/09_builtin_procs.md @@ -6,7 +6,7 @@ Returns the unique identification number of the object. Although in pure Erg semantics no difference can be found between objects with the same structure, in practice objects have different locations in memory. `id!` returns a number representing this position. -```erg +```python ```

diff --git a/doc/EN/syntax/10_array.md b/doc/EN/syntax/10_array.md index a3c8c20c..fd42f8a3 100644 --- a/doc/EN/syntax/10_array.md +++ b/doc/EN/syntax/10_array.md @@ -3,7 +3,7 @@ Arrays are the most basic __collection (aggregate)__. A collection is an object that can hold multiple objects inside it. -```erg +```python a = [1, 2, 3] a: [Int; 3] # Type specification: number after semicolon is the number of elements # Can be omitted if the number of elements is not known @@ -16,13 +16,13 @@ assert mut_a == [2, 2, 3] As a rule, arrays cannot contain objects of different types. -```erg. +```python. [1, "a"] # TypeError: 1st element is Int, but 2nd element is Str ``` However, you can bypass the restriction by explicitly specifying the type like this. -```erg +```python [1, "a"]: [Int or Str]. ``` @@ -30,7 +30,7 @@ However, you can bypass the restriction by explicitly specifying the type like t An array can also have multiple values taken out at once. This is called slicing. -```erg +```python l = [1, 2, 3, 4] # Same as l[1:3] in Python assert l[1.. <3] == [2, 3] @@ -43,7 +43,7 @@ assert l[..].step(2) == [2, 4] The object obtained by slicing is an (immutable) copy to an array. -```erg +```python print! Typeof l[1..2] # [Int; 4] ``` diff --git a/doc/EN/syntax/11_tuple.md b/doc/EN/syntax/11_tuple.md index 75a942c3..403833b5 100644 --- a/doc/EN/syntax/11_tuple.md +++ b/doc/EN/syntax/11_tuple.md @@ -3,7 +3,7 @@ Tuples are similar to arrays, but can hold objects of different types. Such a collection is called an unequal collection. In contrast, homogeneous collections include arrays, sets, etc. -```erg +```python t = (1, True, "a") (i, b, s) = t assert(i == 1 and b == True and s == "a") @@ -12,7 +12,7 @@ assert(i == 1 and b == True and s == "a") The tuple `t` can retrieve the nth element in the form `t.n`; note that unlike Python, it is not `t[n]`. This is because accessing tuple elements is more like an attribute (the existence of the element is checked at compile time, and the type can change depending on `n`) than a method (an array's `[]` is a method). -```erg +```python assert t.0 == 1 assert t.1 == True assert t.2 == "a" @@ -20,14 +20,14 @@ assert t.2 == "a" Parentheses `()` are optional when not nested. -```erg +```python t = 1, True, "a" i, b, s = t ``` Tuples can hold objects of different types, so they cannot be iterated like arrays. -```erg +```python t: ({1}, {2}, {3}) = (1, 2, 3) (1, 2, 3).iter().map(x -> x + 1) # TypeError: type ({1}, {2}, {3}) has no method `.iter()` # If all types are the same, they can be represented by `(T; n)` like arrays, but this still does not allow iteration @@ -38,11 +38,11 @@ assert (Int; 3) == (Int, Int, Int) However, nonhomogeneous collections (such as tuples) can be converted to homogeneous collections (such as arrays) by upcasting, intersecting, and so on. This is called equalization. -```erg +```python (Int, Bool, Str) can be [T; 3] where T :> Int, T :> Bool, T :> Str ``` -```erg +```python t: (Int, Bool, Str) = (1, True, "a") # non-homogenous a: [Int or Bool or Str; 3] = [1, True, "a"] # homogenous _a: [Show; 3] = [1, True, "a"] # homogenous @@ -54,21 +54,21 @@ t.try_into([Show; 3])? .iter().map(x -> log x) # OK A tuple with zero elements is called a __unit__. A unit is a value, but also refers to its own type. -```erg +```python unit = () (): () ``` Unit is a superclass of all element 0 tuples. -```erg +```python () > (Int; 0) () > (Str; 0) ``` The use of this object is for procedures with no arguments and no return value, etc. Erg subroutines must have arguments and a return value. However, in some cases, such as a procedure, there may be no meaningful arguments or return value, only side effects. In such cases, we use units as "meaningless, formal values. -```erg +```python # ↓ Actually, this parenthesis is a unit p!() =. # `print!` does not return a meaningful value @@ -83,7 +83,7 @@ In Erg, you should use `()` when you are sure from the beginning that the operat Actually, all of Erg's `Callable` objects are one argument and one return value; a subroutine that takes N arguments was just receiving "one tuple with N elements" as an argument. -```erg +```python # f x = ... is implicitly assumed to be f(x) = ... is considered to be f x = x assert f(1) == 1 @@ -95,14 +95,14 @@ assert (2, 3) == g 1, 2, 3 This also explains the function type. -```erg +```python assert f in T: {(T,) -> T | T} assert g in {(Int, ... (Int; N)) -> (Int; N) | N: Nat} ``` To be precise, the function's input is not a tuple but a "Named tuple with default attributes". This is a special tuple that can only be used in function arguments, can be named like a record, and can have a default value. -```erg +```python f(x: Int, y=0) = x + y f: (Int, y=Int) -> Int diff --git a/doc/EN/syntax/12_dict.md b/doc/EN/syntax/12_dict.md index 2bbfbfd0..3c03c35f 100644 --- a/doc/EN/syntax/12_dict.md +++ b/doc/EN/syntax/12_dict.md @@ -2,14 +2,14 @@ Dict is a collection of key/value pairs. -```erg +```python ids = {"Alice": 145, "Bob": 214, "Charlie": 301} assert ids["Alice"] == 145 ``` The key does not have to be a string if it is a `Hash` object. -```erg +```python # deprecated to use a range object as a key (confused with slice) r = {1..3: "1~3", 4..6: "4~6", 7..9: "7~9"} assert r[1..3] == "1~3" @@ -20,20 +20,20 @@ assert l[[]] == "empty" Order does not matter for Dict. It also cannot have duplicate elements. In this respect, Dict is similar to Set. You could say that a Dict is a Set with values. -```erg +```python {"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214} ``` When generating a dict from a dict literal, it is checked for duplicate keys. Any duplicates will result in a compile error. -```erg +```python {"Alice": 145, "Alice": 1} # KeyError: Duplicate key "Alice" ``` Empty Dict is created with `{:}`. Note that `{}` denotes an empty set. -```erg +```python mut_dict = !{:} mut_dict.insert! "Alice", 145 mut_dict.insert! "Bob", 214 @@ -44,7 +44,7 @@ assert mut_dict["Alice"] == 145 There need not be a single key/value type. Such a dictionary is called a __heterogenous dict_. -```erg +```python d: {Str: Int, Int: Str} = {"a": 1, 1: "a"} assert d["a"] == 1 assert d[1] == "a" @@ -53,7 +53,7 @@ assert d[1] == "a" However, it is not possible to assign values of the same type to keys of different types, or values of different types to keys of the same type. In such cases, use the type Or instead. -```erg +```python invalid1 = {1: "a", "a": "b"} invalid2 = {1: "a", 2: 2} diff --git a/doc/EN/syntax/13_record.md b/doc/EN/syntax/13_record.md index 8fb4c524..c7f8694e 100644 --- a/doc/EN/syntax/13_record.md +++ b/doc/EN/syntax/13_record.md @@ -3,7 +3,7 @@ A record is a collection that combines the properties of a Dict accessed by key and a tuple whose access is inspected at compile time. If you know JavaScript, think of it as a (more enhanced) kind of object literal notation. -```erg +```python john = {.name = "John"; .age = 21} assert john.name == "John" @@ -20,7 +20,7 @@ So how should we use dictionaries and records? In general, we recommend using records. Records have the advantages of being checked at compile-time for the existence of elements and of being able to specify __visibility_. Specifying visibility is equivalent to specifying public/private in Java and other languages. For details, see [visibility](./15_visibility.md) for details. -```erg +```python a = {x = 1; .y = x + 1} a.x # AttributeError: x is private # Hint: declare as `.x`. @@ -31,7 +31,7 @@ The above example may seem strange to someone familiar with JavaScript, but simp You can also explicitly specify the type of an attribute. -```erg +```python anonymous = { .name: Option! Str = ! .age = 20 @@ -41,7 +41,7 @@ anonymous.name.set! "John" A record can also have the method. -```erg +```python o = { .i = !0 .inc! ref! self = self.i.inc!() @@ -55,7 +55,7 @@ assert o.i == 1 There is a notable syntax with respect to records. When all the attribute values of a record are classes (not structural types), the record itself behaves as a type with its own attributes as required attributes. Such a type is called a record type. See the section [Record] for more details. -```erg +```python # record john = {.name = "John"} # record type @@ -74,7 +74,7 @@ Named.name # Str Records can be deconstructed as follows. -```erg +```python record = {x = 1; y = 2} {x = a; y = b} = record assert a == 1 @@ -91,7 +91,7 @@ match point: `x = ...` can also be abbreviated to `x` when there is a variable with the same name as the attribute, for example, `x = x` or `x = .x` to `x`, and `.x = .x` or `.x = x` to `.x`. However, when there is only one attribute, it must be followed by `;` to distinguish it from a set. -```erg +```python x = 1 y = 2 xy = {x; y} @@ -108,7 +108,7 @@ assert tuple.1 == 1 This syntax can be used to deconstructed a record and assign it to a variable. -```erg +```python # same as `{x = x; y = y} = xy` {x; y} = xy assert x == 1 @@ -123,7 +123,7 @@ assert b == 2 An empty record is represented by `{=}`. An empty record is also its own class, like Unit. -```erg +```python empty_record = {=} empty_record: {=} # Object: Type = {=} @@ -137,7 +137,7 @@ As an enumerated type, `{}` is an empty type that contains nothing in its elemen Conversely, the record class `{=}` has no required instance attribute, so all objects are elements of it. An `Object` is an alias of this. An `Object` (a patch of `Object`) is an element of `. __sizeof__` and other very basic provided methods. -```erg +```python AnyPatch = Patch Structural {=} . __sizeof__ self = ... .clone self = ... @@ -153,7 +153,7 @@ Also, if you define a type (such as `Int and Str`) that results in a composition Erg has another syntax, instant block, which simply returns the last value evaluated. Attributes cannot be retained. -```erg +```python x = x = 1 y = x + 1 @@ -169,7 +169,7 @@ y = A bare record (a record generated by a record literal) must be defined directly in the instance if you try to implement a method on its own. This is inefficient, and as the number of attributes increases, error messages and the like become difficult to see and use. -```erg +```python john = { name = "John Smith" age = !20 @@ -183,7 +183,7 @@ john + 1 So, in such a case, you can inherit a record class. Such a class is called a data class. This is described in [class](./type/04_class.md). -```erg +```python Person = Inherit {name = Str; age = Nat} Person. greet! ref self = print! "Hello, my name is {self::name} and I am {self::age} years old." diff --git a/doc/EN/syntax/16_iterator.md b/doc/EN/syntax/16_iterator.md index 302d197b..d53deb4c 100644 --- a/doc/EN/syntax/16_iterator.md +++ b/doc/EN/syntax/16_iterator.md @@ -2,7 +2,7 @@ An iterator is an object used to retrieve elements of a container. -```erg +```python for! 0..9, i => print! i ``` @@ -12,7 +12,7 @@ Each number (=Int object) is assigned to `i` and the following operation (=`prin Now let's look at the type signature of the `for!` procedure. -```erg +```python for!: |T: Type, I <: Iterable T| (I, T => None) => None ``` @@ -20,7 +20,7 @@ The first argument seems to accept an object of type `Iterable`. `Iterable` is a type with `.Iterator` attribute, `.iter` method in the request method. -```erg +```python Iterable T = Trait { .Iterator = {Iterator} .iter = Self(T). () -> Self.Iterator T @@ -29,7 +29,7 @@ Iterable T = Trait { The type `{Iterator}` of the `.Iterator` attribute is so-called set-kind (kind is described [here](./type/advanced/kind.md)). -```erg +```python assert [1, 2, 3] in Iterable(Int) assert 1..3 in Iterable(Int) assert [1, 2, 3].Iterator == ArrayIterator diff --git a/doc/EN/syntax/17_mutability.md b/doc/EN/syntax/17_mutability.md index e88b87b1..47484bfa 100644 --- a/doc/EN/syntax/17_mutability.md +++ b/doc/EN/syntax/17_mutability.md @@ -3,7 +3,7 @@ As we have already seen, all Erg variables are immutable. However, Erg objects have the concept of mutability. Take the following code as an example. -```erg +```python a = [1, 2, 3] a = a + [4, 5, 6] print! a # [1, 2, 3, 4, 5, 6] @@ -13,7 +13,7 @@ The above code cannot actually be executed by Erg. This is because it is not rea This code can be executed. -```erg +```python b = ![1, 2, 3] b.concat! [4, 5, 6] print! b # [1, 2, 3, 4, 5, 6] @@ -22,7 +22,7 @@ print! b # [1, 2, 3, 4, 5, 6] The final result of `a, b` looks the same, but their meanings are very different. Although `a` is a variable that represents an array of `Nat`, the objects pointed to in the first and second lines are different. The name `a` is the same, but the contents are different. -```erg +```python a = [1, 2, 3] print! id! a # 0x000002A798DFE940 _a = a + [4, 5, 6] @@ -33,14 +33,14 @@ The `id!` procedure returns the address in memory where the object resides. `b` is a `Nat` "dynamic" array. The content of the object changes, but the variables point to the same thing. -```erg +```python b = ![1, 2, 3] print! id! b # 0x000002A798DFE220 b.concat! [4, 5, 6] print! id! b # 0x000002A798DFE220 ``` -```erg +```python i = !0 if! True. do! do! i.inc!() # or i.add!(1) @@ -51,7 +51,7 @@ print! i # 1 `!` is a special operator called the __mutation operator__. It makes immutable objects mutable. The behavior of objects marked with `!` can be customized. -```erg +```python Point = Class {.x = Int; .y = Int} # In this case .x is made mutable and .y remains immutable @@ -69,7 +69,7 @@ print! p.x # 1 Unlike variables, constants point to the same thing in all scopes. Constants are declared with the `=` operator. -```erg +```python PI = 3.141592653589 match! x: PI => print! "this is pi" diff --git a/doc/EN/syntax/22_subroutine.md b/doc/EN/syntax/22_subroutine.md index 0128c059..c5f70cff 100644 --- a/doc/EN/syntax/22_subroutine.md +++ b/doc/EN/syntax/22_subroutine.md @@ -2,14 +2,14 @@ ## Func -```erg +```python some_func(x: T, y: U) -> V some_func: (T, U) -> V ``` ## Proc -```erg +```python some_proc!(x: T, y: U) => V some_proc!: (T, U) => V ``` @@ -18,7 +18,7 @@ some_proc!: (T, U) => V The method type cannot be specified externally with ``Self``. -```erg +```python .some_method(self, x: T, y: U) => () # Self.(T, U) => () takes ownership of self .some_method: Ref(Self). (T, U) => () @@ -28,7 +28,7 @@ The method type cannot be specified externally with ``Self``. In the following, assume that the type `T!` takes the type argument `N: Nat`. To specify it externally, use a type variable. -```erg +```python T!: Nat -> Type # ~> indicates the state of the type argument before and after application (in this case, self must be a variable reference) T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => () @@ -39,7 +39,7 @@ For methods that do not have `ref!`, i.e., are deprived of ownership after appli If ownership is taken, it is as follows. -```erg +```python # If you don't use N, you can omit it with _. # .some_method!: |N, X: Nat| T!(N).({X}) => T!(N+X) .some_method!|N, X: Nat|(self(N), X: Nat) => T!(N+X) @@ -51,7 +51,7 @@ It can be defined as a normal function by enclosing it with ``. Neuter alphabetic operators such as `and` and `or` can be defined as neuter operators by enclosing them with ``. -```erg +```python and(x, y, z) = x and y and z `_+_`(x: Foo, y: Foo) = x.a + y.a `-_`(x: Foo) = Foo.new(-x.a) diff --git a/doc/EN/syntax/24_module.md b/doc/EN/syntax/24_module.md index 2a7c92d9..98027038 100644 --- a/doc/EN/syntax/24_module.md +++ b/doc/EN/syntax/24_module.md @@ -2,7 +2,7 @@ Erg allows you to think of the file itself as a single record. This is called a module. -```erg: foo.er +```python: foo.er # foo.er .i = 1 ``` @@ -12,7 +12,7 @@ Erg allows you to think of the file itself as a single record. This is called a foo = {.i = 1} ``` -```erg: bar.er +```python: bar.er #bar.er foo = import "foo" print! foo # diff --git a/doc/EN/syntax/32_integration_with_Python.md b/doc/EN/syntax/32_integration_with_Python.md index 1948466b..945379a2 100644 --- a/doc/EN/syntax/32_integration_with_Python.md +++ b/doc/EN/syntax/32_integration_with_Python.md @@ -5,7 +5,7 @@ When the Erg script is compiled, a .pyc file is generated, which can simply be imported as a Python module. However, variables set to private on the Erg side cannot be accessed from Python. -```erg +```python # foo.er .public = "this is a public variable" private = "this is a private variable" @@ -30,7 +30,7 @@ All objects imported from Python are by default of type `Object`. Since no compa All APIs in the Python standard library are type specified by the Erg development team. -```erg +```python time = pyimport "time" time.sleep! 1 ``` @@ -50,7 +50,7 @@ def baz(): ... ``` -```erg +```python # foo.d.er foo = pyimport "foo" .X = declare foo.'X', Int @@ -58,14 +58,14 @@ foo = pyimport "foo" .baz! = declare foo.'baz', () => Int ``` -```erg +```python foo = pyimport "foo" assert foo.bar(1) in Int ``` This ensures type safety by performing type checking at runtime. The ``declare`` function works roughly as follows. -```erg +```python declare|S: Subroutine| sub!: S, T = # Actually, => can be cast to a function without block side effects x => diff --git a/doc/EN/syntax/33_package_system.md b/doc/EN/syntax/33_package_system.md index dded29be..23e5aff5 100644 --- a/doc/EN/syntax/33_package_system.md +++ b/doc/EN/syntax/33_package_system.md @@ -25,7 +25,7 @@ You can import `foo` and `bar` modules in `app.er`. The `bar` directory can be r A `foo` module is a module consisting of files, and a `bar` module is a module consisting of directories. The `bar` module also contains `baz` and `qux` modules. This module is simply an attribute of the `bar` module, and can be accessed from `app.er` as follows. -```erg +```python # app.er foo = import "foo" bar = import "bar" @@ -47,7 +47,7 @@ For example, a module for testing. A file ending with `.test.er` is a (white box └─ foo.test.er ./src -```erg +```python # app.er foo = import "foo" @@ -66,14 +66,14 @@ Also, files ending in ``.private.er`` are private modules and can only be access └─ qux.er ``` -```erg +```python # foo.er bar = import "bar" bar.qux bar.baz # AttributeError: module 'baz' is private ``` -```erg +```python # qux.er baz = import "baz" ``` diff --git a/doc/EN/syntax/34_generator.md b/doc/EN/syntax/34_generator.md index 1aef8649..12eba58e 100644 --- a/doc/EN/syntax/34_generator.md +++ b/doc/EN/syntax/34_generator.md @@ -2,7 +2,7 @@ Generators are special procedures that use the `yield!` procedure in a block. -```erg +```python g!() = yield! 1 yield! 2 @@ -12,7 +12,7 @@ g!() = `yield!` is a procedure defined in a block of subroutines that calls `self!.yield!`. Like `return`, it returns the value passed to it as a return value, but it has the feature of saving the current execution state of the block and executing it from the beginning when it is called again. A generator is both a procedure and an iterator; a Python generator is a function that creates an iterator, while Erg iterates directly. Procedures themselves are generally not mutable objects (no `!`), but a generator is a mutable object because its own contents can change with each execution. -```erg +```python # Generator! g!: Generator!((), Int) assert g!() == 1 @@ -22,7 +22,7 @@ assert g!() == 3 A Python-style generator can be defined as follows. -```erg +```python make_g() = () => yield! 1 yield! 2 diff --git a/doc/EN/syntax/type/01_type_system.md b/doc/EN/syntax/type/01_type_system.md index d45ede30..3f1ee80a 100644 --- a/doc/EN/syntax/type/01_type_system.md +++ b/doc/EN/syntax/type/01_type_system.md @@ -6,7 +6,7 @@ The following is a brief description of Erg's type system. Details are explained One of the unique features of Erg is that there is not much difference in syntax between (normal) variable, function (subroutine), and type (Kind) definitions. All are defined according to the syntax of normal variable and function definitions. -```erg +```python f i: Int = i + 1 f # f(1) # 2 @@ -64,7 +64,7 @@ Erg's array (Array) is what Python calls a list. `[Int; 3]` is an array class th > __Note__: `(Type; N)` is both a type and a value, so it can be used like this. > -> ```erg. +> ```python. > Types = (Int, Str, Bool) > > for! Types, T => @@ -73,7 +73,7 @@ Erg's array (Array) is what Python calls a list. `[Int; 3]` is an array class th > a: Types = (1, "aaa", True) > ``` -```erg +```python pop|T, N|(l: [T; N]): ([T; N-1], T) = [...l, last] = l (l, last) @@ -86,7 +86,7 @@ lpop|T, N|(l: [T; N]): (T, [T; N-1]) = A type ends with `!` can be rewritten internal structure. For example, the `[T; !N]` class is a dynamic array. To create an object of type `T!` from an object of type `T`, use the unary operator `!`. -```erg +```python i: Int! = !1 i.update! i -> i + 1 assert i == 2 @@ -101,7 +101,7 @@ assert mut_arr == [1, 2, 3, 4]. Types are defined as follows. -```erg +```python Point2D = {.x = Int; .y = Int} ``` @@ -115,7 +115,7 @@ As mentioned earlier, a "type" in Erg roughly means a set of objects. The following is a definition of the `Add` type, which requires `+` (the middle operator). `R, O` are the so-called type parameters, which can be a true type (class) such as `Int` or `Str`. In other languages, type parameters are given a special notation (generics, templates, etc.), but in Erg they can be defined just like normal parameters. Type parameters can also be used for types other than type objects. For example, the array type `[Int; 3]` is a syntax sugar for `Array Int, 3`. If the type implementations overlap, the user must explicitly choose one. -```erg +```python Add R = Trait { .AddO = Type . `_+_` = Self.(R) -> Self.AddO @@ -124,7 +124,7 @@ Add R = Trait { .`_+_` is an abbreviation for Add.`_+_`. The prefix operator .`+_` is a method of type `Num`. -```erg +```python Num = Add and Sub and Mul and Eq NumImpl = Patch Num NumImpl. @@ -134,7 +134,7 @@ NumImpl. Polymorphic types can be treated like functions. They can be monomorphic by specifying them as `Mul Int, Str`, etc. (in many cases, they are inferred with real arguments without specifying them). -```erg +```python 1 + 1 `_+_` 1, 1 Nat.`_+_` 1, 1 @@ -146,7 +146,7 @@ The top four lines return the same result (to be exact, the bottom one returns ` This is because `Int <: Ratio`, so `1` is downcast to `Ratio`. But this is not cast. -```erg +```python i = 1 if i: # TypeError: i: Int cannot be cast to Bool, use Int.is_zero() instead. log "a" @@ -159,7 +159,7 @@ This is because `Bool <: Int` (`True == 1`, `False == 0`). Casts to subtypes gen Erg uses static duck typing, so there is little need to explicitly specify the type. -```erg +```python f x, y = x + y ``` @@ -168,7 +168,7 @@ If `{0}, {-1}`, it is monomorphic to `Int` since it does not match `Nat`. If the `{0}` and `{1}` are enumerated types that are partial types such as `Int` and `Nat`. Enumerated types, for example, can be given names and request/implementation methods. In namespaces that have access to that type, objects that satisfy the request can use the implementation method. -```erg +```python Binary = Patch {0, 1} Binary. # self contains an instance. In this example, either 0 or 1. @@ -185,7 +185,7 @@ Binary. Thereafter, the code `0.to_bool()` is possible (although `0 as Bool == False` is defined built-in). Here is an example of a type that can actually rewrite `self` as shown in the code. -```erg +```python Binary! = Patch {0, 1}! Binary! switch! ref! self = match! self: @@ -199,7 +199,7 @@ print! b # => 0 ## Structure type (anonymous type) -```erg +```python Binary = {0, 1} ``` @@ -212,14 +212,14 @@ Such types are called structural types. When we want to emphasize its use as the The following cannot be specified. For example, you cannot specify `Int` and `Int` and `Int` and `Int` and `Int` and `Int`. For example, `Int` and `Str` are both `Add`, but `Int` and `Str` cannot be added. -```erg +```python add l: Add, r: Add = l + r # TypeError: there is no implementation of `_+_`: |T, U <: Add| (T, U) -> ``` Also, the types `A` and `B` below are not considered the same type. However, the type `O` is considered to match. -```erg +```python ... |R1; R2; O; A <: Add(R1, O); B <: Add(R2, O)| ``` diff --git a/doc/EN/syntax/type/02_basic.md b/doc/EN/syntax/type/02_basic.md index 3a270717..d555b8ce 100644 --- a/doc/EN/syntax/type/02_basic.md +++ b/doc/EN/syntax/type/02_basic.md @@ -4,7 +4,7 @@ In Erg, the type of a variable can be specified after `:` as follows. This can be done at the same time as an assignment. -```erg +```python i: Int # Declare the variable i to be of type Int i: Int = 1 j = 1 # type specification can be omitted @@ -12,7 +12,7 @@ j = 1 # type specification can be omitted You can also specify a type for ordinary expressions. -```erg +```python i = 1: Int f([1, "a"]: [Int or Str]) ``` @@ -20,7 +20,7 @@ f([1, "a"]: [Int or Str]) For simple variable assignments, most type specifications can be omitted. Type specifications are more useful when defining subroutines and types. -```erg +```python # Type specification for parameters f x, y: Array Int = ... T X, Y: Array Int = ... @@ -28,20 +28,20 @@ T X, Y: Array Int = ... Note that in the above case, `x, y` are both `Array Int`. -```erg +```python # The value of a capital variable must be a constant expression f X: Int = X ``` Alternatively, if you don't need complete information about the type argument, you can omit it with `_`. -```erg +```python g v: [T; _] = ... ``` Note, however, `_` at a type specification implies `Object`. -```erg +```python f x: _, y: Int = x + y # TypeError: + is not implemented between Object and Int ``` @@ -52,7 +52,7 @@ The left side of `<:` can only specify a class. Use `Subtypeof` or similar opera This is also often used when defining subroutines or types, rather than simply specifying variables. -```erg +```python # Subtype specification of an argument f X <: T = ... @@ -66,7 +66,7 @@ Iterable T = Trait { You can also use a subtype specification when defining a class to statically check whether the class is a subtype of the specified type. -```erg +```python # Class C is a subtype of Show C = Class Object, Impl := Show C.show self = ... # Show's required attributes. @@ -74,7 +74,7 @@ C.show self = ... # Show's required attributes. You can also specify a subtype only in specific cases. -```erg +```python K T: Eq K Int <: Show and Eq K T = Class Object @@ -87,7 +87,7 @@ K(Int). Subtype specification is recommended when implementing structural types. This is because, due to the nature of structural subtyping, typo or type specification errors will not cause errors when implementing required attributes. -```erg +```python C = Class Object C.shoe self = ... # Show is not implemented due to Typo (it is considered just a unique method). ``` @@ -96,7 +96,7 @@ C.shoe self = ... # Show is not implemented due to Typo (it is considered just a Attributes can be defined for traits and classes only in modules. -```erg +```python C = Class() C.pub_attr = "this is public" C::private_attr = "this is private" @@ -107,7 +107,7 @@ assert c.pub_attr == "this is public" The syntax for defining a batch definition is called a batch definition, in which a newline is added after `C.` or `C::` and the definitions are grouped together below the indentation. -```erg +```python C = Class() C.pub1 = ... C.pub2 = ... @@ -127,7 +127,7 @@ C:: Types can be aliased. This allows long types, such as record types, to be shortened. -```erg +```python Id = Int Point3D = {x = Int; y = Int; z = Int} IorS = Int or Str @@ -140,7 +140,7 @@ However, only one alias of the same type is allowed per module, and multiple ali This means that types with different purposes should be defined as separate types. The purpose is also to prevent adding aliases on top of types that already have aliases. -```erg +```python Id = Int UserId = Int # TypeWarning: duplicate aliases: Id and UserId diff --git a/doc/EN/syntax/type/03_trait.md b/doc/EN/syntax/type/03_trait.md index 9fcf79b0..ea1fb991 100644 --- a/doc/EN/syntax/type/03_trait.md +++ b/doc/EN/syntax/type/03_trait.md @@ -3,7 +3,7 @@ Trait is a nominal type that adds a type attribute requirement to record types. It is similar to the Abstract Base Class (ABC) in Python, but with the distinction of being able to perform algebraic operations. -```erg +```python Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int} ``` @@ -12,7 +12,7 @@ Trait does not distinguish between attributes and methods. Note that traits can only be declared, not implemented (implementation is achieved by a feature called patching, which will be discussed later). Traits can be checked for implementation in a class by specifying a partial type. -```erg +```python Point2D <: Norm Point2D = Class {.x = Int; .y = Int} Point2D.norm self = self.x**2 + self.y**2 @@ -20,14 +20,14 @@ Point2D.norm self = self.x**2 + self.y**2 Error if the required attributes are not implemented. -```erg +```python Point2D <: Norm # TypeError: Point2D is not a subtype of Norm Point2D = Class {.x = Int; .y = Int} ``` Traits, like structural types, can apply operations such as composition, substitution, and elimination (e.g. `T and U`). The resulting trait is called an instant trait. -```erg +```python T = Trait {.x = Int} U = Trait {.y = Int} V = Trait {.x = Int; y: Int} @@ -40,7 +40,7 @@ assert Structural(W) == Structural(T.replace {.x = Ratio}) Trait is also a type, so it can be used for normal type specification. -```erg +```python points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)] assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25]. ``` @@ -51,7 +51,7 @@ The expansion operator `...` allows you to define a trait that contains a certai In the example below, `BinAddSub` subsumes `BinAdd` and `BinSub`. This corresponds to Inheritance in a class, but unlike Inheritance, multiple base types can be combined using `and`. Traits that are partially excluded by `not` are also allowed. -```erg +```python Add R = Trait { .AddO = Type . `_+_` = Self.(R) -> Self.AddO @@ -69,7 +69,7 @@ BinAddSub = Subsume Add(Self) and Sub(Self) Traits can be structured. -```erg +```python SAdd = Structural Trait { . `_+_` = Self.(Self) -> Self } @@ -87,7 +87,7 @@ assert add(C.new(1), C.new(2)) == C.new(3) Nominal traits cannot be used simply by implementing a request method, but must be explicitly declared to have been implemented. In the following example, `add` cannot be used with an argument of type `C` because there is no explicit declaration of implementation. It must be `C = Class {i = Int}, Impl := Add`. -```erg +```python Add = Trait { .`_+_` = Self.(Self) -> Self } @@ -109,7 +109,7 @@ Structural traits do not need to be declared for this implementation, but instea Traits can take parameters. This is the same as for polymorphic types. -```erg +```python Mapper T: Type = Trait { .mapIter = {Iterator} .map = Self(T). (T -> U) -> Self.MapIter U @@ -127,7 +127,7 @@ assert [1, 2, 3].iter().map(x -> "{x}").collect(Array) == ["1", "2", "3"]. Derived traits can override the type definitions of the base trait. In this case, the type of the overriding method must be a subtype of the base method type. -```erg +```python # `Self.(R) -> O` is a subtype of ``Self.(R) -> O or Panic Div R, O: Type = Trait { . `/` = Self.(R) -> O or Panic @@ -142,7 +142,7 @@ SafeDiv R, O = Subsume Div, { The actual definitions of `Add`, `Sub`, and `Mul` look like this. -```erg +```python Add R = Trait { .Output = Type . `_+_` = Self.(R) -> .Output @@ -159,7 +159,7 @@ Mul R = Trait { `.Output` is duplicated. If you want to implement these multiple traits at the same time, specify the following. -```erg +```python P = Class {.x = Int; .y = Int} # P|Self <: Add(P)| can be abbreviated to P|<: Add(P)| P|Self <: Add(P)|. @@ -172,7 +172,7 @@ P|Self <: Mul(Int)|. Duplicate APIs implemented in this way are almost always type inferred when used, but can also be resolved by explicitly specifying the type with `||`. -```erg +```python print! P.Output # TypeError: ambiguous type print! P|<: Mul(Int)|.Output # ``` diff --git a/doc/EN/syntax/type/04_class.md b/doc/EN/syntax/type/04_class.md index f582937a..b345aa65 100644 --- a/doc/EN/syntax/type/04_class.md +++ b/doc/EN/syntax/type/04_class.md @@ -3,7 +3,7 @@ A class in Erg is roughly a type that can create its own elements (instances). Here is an example of a simple class. -```erg +```python Person = Class {.name = Str; .age = Nat} # If `.new` is not defined, then Erg will create `Person.new = Person::__new__` Person. @@ -22,7 +22,7 @@ In the class above, the `.new` method is defined so that field names, etc. can b Note that the following definition without line breaks will result in a syntax error. -```erg +```python Person.new name, age = ... # SyntaxError: cannot define attributes directly on an object ``` @@ -39,7 +39,7 @@ class Person: age: int ``` -```erg +```python # In Erg, this notation implies the declaration of a class attribute (not an instance attribute) Person = Class() Person. @@ -47,7 +47,7 @@ Person. age: Int ``` -```erg +```python # Erg code for the Python code above Person = Class { .name = Str @@ -61,7 +61,7 @@ In addition, dividing the attributes in this way clarifies roles such as "this a The example below illustrates this. The attribute `species` is common to all instances, so it is more natural to use it as a class attribute. However, the attribute `name` should be an instance attribute because each instance should have it individually. -```erg +```python Person = Class {name = Str} Person:: species = "human" @@ -85,7 +85,7 @@ alice.greet() # Hello, My name is Alice. Incidentally, if an instance attribute and a type attribute have the same name and the same type, a compile error occurs. This is to avoid confusion. -```erg +```python C = Class {.i = Int} C.i = 1 # AttributeError: `.i` is already defined in instance fields ``` @@ -102,7 +102,7 @@ Erg does not allow you to add class methods, but you can use [patch](./07_patch. You can also inherit from existing classes ([Inheritable](./../27_decorator.md/#inheritable) class). You can create an inherited class by using `Inherit`. The type on the left-hand side is called the derived class, and the argument type of `Inherit` on the right-hand side is called the base class (inherited class). -```erg +```python MyStr = Inherit Str # other: You can use MyStr if you set ``other: Str''. MyStr. @@ -117,7 +117,7 @@ Unlike Python, the defined Erg classes are `final` (non-inheritable) by default. To make a class inheritable, an `Inheritable` decorator must be attached to the class. Str` is one of the inheritable classes. -```erg +```python MyStr = Inherit Str # OK MyStr2 = Inherit MyStr # NG @@ -131,7 +131,7 @@ MyStr3 = Inherit InheritableMyStr # OK Classes have a different equivalence checking mechanism than types. Types are equivalence tested based on their structure. -```erg +```python Person = {.name = Str; .age = Nat} Human = {.name = Str; .age = Nat} @@ -140,7 +140,7 @@ assert Person == Human class has no equivalence relation defined. -```erg +```python Person = Class {.name = Str; .age = Nat} Human = Class {.name = Str; .age = Nat} @@ -151,7 +151,7 @@ Person == Human # TypeError: cannot compare classes We said that a class is a type that can generate its own elements, but that is not a strict description. In fact, a record type + patch can do the same thing. -```erg +```python Person = {.name = Str; .age = Nat} PersonImpl = Patch Person PersonImpl. @@ -174,7 +174,7 @@ Type checking for classes is simply a matter of checking the object's `. __class Erg enables NSTs in classes; the advantages of NSTs include robustness. When writing large programs, it is often the case that the structure of an object is coincidentally matched. -```erg +```python Dog = {.name = Str; .age = Nat} DogImpl = Patch Dog DogImpl. @@ -192,7 +192,7 @@ john.bark() # "Yelp!" The structure of `Dog` and `Person` is exactly the same, but it is obviously nonsense to allow animals to greet and humans to bark. The former is impossible, so it is safer to make it inapplicable. In such cases, it is better to use classes. -```erg +```python Dog = Class {.name = Str; .age = Nat} Dog.bark = log "Yelp!" ... @@ -207,7 +207,7 @@ Another feature is that the type attributes added by the patch are virtual and a That is, `T.x`, `T.bar` are objects that can be accessed (compile-time bound) by types compatible with `{i = Int}`, and are not defined in `{i = Int}` or `C`. In contrast, class attributes are held by the class itself. Therefore, they cannot be accessed by classes that are not in an inheritance relationship, even if they have the same structure. -```erg +```python C = Class {i = Int} C. foo self = ... @@ -233,7 +233,7 @@ There are two types of classes: regular classes, which are record classes throug The data class inherits the functionality of the record class and has features such as decomposition assignment, `==` and `hash` implemented by default, etc. On the other hand, the data class has its own equivalence relation and format display. On the other hand, if you want to define your own equivalence relations or formatting displays, you should use the normal class. -```erg +```python C = Class {i = Int} c = C.new {i = 1} d = C.new {i = 2} @@ -251,7 +251,7 @@ assert e ! = f To facilitate defining classes of type `Or`, an `Enum` is provided. -```erg +```python X = Class() Y = Class() XorY = Enum X, Y @@ -260,7 +260,7 @@ XorY = Enum X, Y Each type can be accessed as `XorY.X`, `XorY.Y` and the constructor can be obtained as `XorY.cons(X)`. `.cons` is a method that takes a class and returns its constructor. -```erg +```python x1 = XorY.new X.new() x2 = XorY.cons(X)() assert x1 == x2 @@ -270,7 +270,7 @@ assert x1 == x2 A class is a subtype of a requirement type. methods (including patch methods) of the requirement type can be used in the class. -```erg +```python T = Trait {.foo = Foo} C = Class(... , impl: T) C. diff --git a/doc/EN/syntax/type/05_inheritance.md b/doc/EN/syntax/type/05_inheritance.md index bb8c78f1..92607492 100644 --- a/doc/EN/syntax/type/05_inheritance.md +++ b/doc/EN/syntax/type/05_inheritance.md @@ -3,7 +3,7 @@ Inheritance allows you to define a new class that adds functionality or specialization to an existing class. Inheritance is similar to inclusion in a trait. The inherited class becomes a subtype of the original class. -```erg +```python NewInt = Inherit Int NewInt. plus1 self = self + 1 @@ -16,7 +16,7 @@ If you want the newly defined class to be inheritable, you must give it the `Inh You can specify an optional argument `additional` to allow the class to have additional instance attributes, but only if the class is a value class. However, you cannot add instance attributes if the class is a value class. -```erg +```python @Inheritable Person = Class {name = Str} Student = Inherit Person, additional: {id = Int} @@ -34,7 +34,7 @@ Erg is exceptionally designed not to allow inheritance of type ``Never``. Erg is [Or type](./13_algebraic.md) can also be inherited. In this case, you can remove any of the choices (multiple choices are possible with `or`) by specifying the optional argument `Excluding`. No additional choices can be added. The class to which you add an option is not a subtype of the original class. -```erg +```python Number = Class Int or Float or Complex Number.abs(self): Float = match self: @@ -48,7 +48,7 @@ RealNumber = Inherit Number, Excluding: Complex Similarly, [refinement type](./12_refinement.md) can also be specified. -```erg +```python Months = Class 0..12 MonthsNot31Days = Inherit Months, Excluding: {1, 3, 5, 7, 8, 10, 12} @@ -73,7 +73,7 @@ Next, consider the second condition. This is for type consistency. Since the der Finally, consider the third condition. This condition is unique to Erg and not often found in other object-oriented languages, again for safety. Let's look at what could go wrong if this were not the case. -```erg +```python # Bad example @Inheritable Base! = Class {x = Int!} @@ -94,7 +94,7 @@ In the inherited class `Inherited!`, the `.g!` method is overridden to transfer Erg has built this rule into the specification. -```erg +```python # OK. @Inheritable Base! = Class {x = Int!} @@ -123,7 +123,7 @@ Although it is not possible to replace traits at inheritance time, there are exa For example, `Int`, a subtype of `Real` (which implements `Add()`), appears to reimplement `Add()`. -```erg +```python Int = Class ... , Impl := Add() and ... ``` @@ -134,13 +134,13 @@ They are two different traits (`Add` is a [covariate](./advanced/variance.md), s Erg does not allow intersection, diff, and complement between normal classes. -```erg +```python Int and Str # TypeError: cannot unite classes ``` This rule prevents inheritance from multiple classes, i.e., multiple inheritance. -```erg +```python IntAndStr = Inherit Int and Str # SyntaxError: multiple inheritance of classes is not allowed ``` @@ -161,7 +161,7 @@ The first is an update operation on the inherited source class attribute. It can Overriding is different from rewriting because it is an operation to override with a more specialized method. Overrides must also be replaced by compatible types. -```erg +```python @Inheritable Base! = Class {.pub = !Int; pri = !Int} Base! @@ -180,7 +180,7 @@ Inherited! The second is an update operation on the (variable) instance attribute of the inherited source. This is also prohibited. Instance attributes of the base class may only be updated from methods provided by the base class. Regardless of the visibility of the attribute, it cannot be updated directly. However, they can be read. -```erg +```python @Inheritable Base! = Class {.pub = !Int; pri = !Int} Base! @@ -209,7 +209,7 @@ So, conversely, where should inheritance be used? One indicator is when "semanti Erg allows the type system to automatically do part of the subtype determination (e.g., Nat, where Int is greater than or equal to 0). However, for example, it is difficult to create a "string type representing a valid e-mail address" relying solely on Erg's type system. You should probably perform validation on a normal string. Then, we would like to add some kind of "warrant" to the string object that has passed validation. That is the equivalent of downcasting to an inherited class. Downcasting a `Str object` to `ValidMailAddressStr` is a one-to-one correspondence with validating that the string is in the correct email address format. -```erg +```python ValidMailAddressStr = Inherit Str ValidMailAddressStr. init s: Str = @@ -229,7 +229,7 @@ But obviously it is wrong to apply a `Dog` type object. So we will use the `Pers This way, only `Person` objects, classes that inherit from them, and `Student` objects will be accepted as arguments. This is more conservative and avoids unnecessarily assuming too much responsibility. -```erg +```python Named = {name = Str; ...} Dog = Class {name = Str; breed = Str} Person = Class {name = Str} diff --git a/doc/EN/syntax/type/06_nst_vs_sst.md b/doc/EN/syntax/type/06_nst_vs_sst.md index 8cc422cc..2738cf7f 100644 --- a/doc/EN/syntax/type/06_nst_vs_sst.md +++ b/doc/EN/syntax/type/06_nst_vs_sst.md @@ -1,6 +1,6 @@ # Nominal Subtyping vs. Structural Subtyping -```erg +```python Months = 0..12 # NST diff --git a/doc/EN/syntax/type/07_patch.md b/doc/EN/syntax/type/07_patch.md index 79795524..80c0b8eb 100644 --- a/doc/EN/syntax/type/07_patch.md +++ b/doc/EN/syntax/type/07_patch.md @@ -4,7 +4,7 @@ Erg does not allow modification of existing types and classes. This means, it is not possible to define additional methods in a class, nor to perform specialization (a language feature that monomorphizes a polymorphically declared type and defines a dedicated method, as in C++). However, there are many situations where you may want to add feature to an existing type or class, and there is a function called "patching" that allows you to do this. -```erg +```python StrReverse = Patch Str StrReverse. reverse self = self.iter().rev().collect(Str) @@ -18,7 +18,7 @@ In fact, built-in method `.reverse` is not a method of `Str`, but a method added However, patch methods have lower precedence than methods of the nominal type (class/trait) and cannot override methods of existing types. -```erg +```python StrangeInt = Patch Int StrangeInt. `_+_` = Int.`_-_` # AssignError: . `_+_` is already defined in Int @@ -28,7 +28,7 @@ If you want to override, you must inherit from the class. However, it is basically recommended not to override and to define a method with a different name. Overriding is not very easy to do because of some safety restrictions. -```erg +```python StrangeInt = Inherit Int StrangeInt. # Overriding methods must be given Override decorators. @@ -41,7 +41,7 @@ StrangeInt. Patches can be defined for a single type, and can be grouped together. -```erg +```python # foo.er StrReverse = Patch(Str) @@ -61,7 +61,7 @@ StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKeba StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase ``` -```erg +```python {StrBoosterPack; ...} = import "foo" assert "abc".reverse() == "cba" @@ -72,7 +72,7 @@ assert "to kebab case".to_kebab_case() == "to-kebab-case" If multiple patches are defined, some of them may result in duplicate implementations. -```erg +```python # foo.er StrReverse = Patch(Str) @@ -88,13 +88,13 @@ StrReverseMk2. In such a case, you can make it unique by using the __related function__ form instead of the method form. -```erg +```python assert StrReverseMk2.reverse("hello") == "olleh" ``` You can also make it unique by selectively importing. -```erg +```python {StrReverseMk2; ...} = import "foo" assert "hello".reverse() == "olleh" @@ -106,7 +106,7 @@ Patches can also relate types to each other. The `StrReverse` patch relates `Str Such a patch is called a __glue patch__. Because `Str` is a built-in type, a glue patch is necessary for users to retrofit traits. -```erg +```python Reverse = Trait { .reverse = Self.() -> Self } @@ -121,7 +121,7 @@ Only one glue patch can be defined per type/trait pair. This is because if multiple glue patches were "visible" at the same time, it would not be possible to uniquely determine which implementation to choose. However, you can swap patches when moving to another scope (module). -```erg +```python NumericStr = Inherit Str NumericStr. ... @@ -152,7 +152,7 @@ impl Reverse for String { You could say that Rust's traits are features of Erg's traits and patches. This makes Rust's traits sound more convenient, but that is not necessarily the case. -```erg +```python # Erg Reverse = Trait { .reverse = Self.() -> Self @@ -167,7 +167,7 @@ StrReverse. Because the `impl` block is objectized as a patch in Erg, selective inclusion is possible when importing from other modules. As a side-effect, it also allows implementation of external traits to external structures. Also, syntaxes such as `dyn trait` and `impl trait` are no longer required by the structure type. -```erg +```python # Erg reversible: [Reverse; 2] = [[1, 2, 3], "hello"] @@ -189,7 +189,7 @@ A patch can be defined not only for one specific type, but also for "function ty In this case, the term to which the degree of freedom is to be given is given as an argument (in the case below, `T: Type`). A patch defined in this way is called an all-symmetric patch. As you can see, an all-symmetric patch is precisely a function that returns a patch, but it can also be considered a patch in its own right. -```erg +```python FnType T: Type = Patch(T -> T) FnType(T). type = T @@ -204,7 +204,7 @@ However, this has a lower priority than nominal patches and class methods. Careful design should be used when defining structural patches, as some properties are lost by extension, such as the following. -```erg +```python # This should not be `Structural` Norm = Structural Patch {x = Int; y = Int} Norm. diff --git a/doc/EN/syntax/type/10_interval.md b/doc/EN/syntax/type/10_interval.md index 4c71ed4f..3d48f0b1 100644 --- a/doc/EN/syntax/type/10_interval.md +++ b/doc/EN/syntax/type/10_interval.md @@ -2,7 +2,7 @@ The most basic use of `Range` objects is as iterator. -```erg +```python for! 0..9, i => print! i ``` @@ -11,7 +11,7 @@ Note that unlike Python, it includes a end number. However, this is not only use for the `Range` objects. It can also be used the type. Such a type is called the Interval type. -```erg +```python i: 0..10 = 2 ``` @@ -20,7 +20,7 @@ The `Nat` type is equivalent to `0.. ExtraStatus, and elements of Status can use methods of ExtraStatus. Status = Trait {"Ok", "Error"} # ... @@ -65,7 +65,7 @@ Methods can also be added by patching. Use the `or` operator to explicitly indicate inclusion or to add a choice to an existing Enum type. -```erg +```python ExtraStatus = Status or {"Unknown"} ``` @@ -75,7 +75,7 @@ By default, a class whose requirement type is an homogeneous enumerated type can If you do not wish to do so, you can make it a wrapper class. -```erg +```python Abc = Class {"A", "B", "C"} Abc.new("A").is_uppercase() diff --git a/doc/EN/syntax/type/12_refinement.md b/doc/EN/syntax/type/12_refinement.md index 2aac3db8..f8df698d 100644 --- a/doc/EN/syntax/type/12_refinement.md +++ b/doc/EN/syntax/type/12_refinement.md @@ -5,7 +5,7 @@ Refinement type is a type constrained by a predicate expression. Enumeration typ The standard form of a refinement type is `{Elem: Type | (Pred)*}`. This means that the type is a type whose elements are `Elem` satisfying `Pred`. The type that can be used for the sifting type is [Const type](./advanced/const.md) only. -```erg +```python Nat = 0.. _ Odd = {N: Int | N % 2 == 1} Char = StrWithLen 1 @@ -22,7 +22,7 @@ It is called a refinement type because it is a type whose elements are part of a The `Pred` is called a (left-hand side) predicate expression. Like assignment expressions, it does not return a meaningful value, and only a pattern can be placed on the left-hand side. That is, expressions such as `X**2 - 5X + 6 == 0` cannot be used as refinement-type predicate expressions. In this respect, it differs from a right-hand-side predicate expression. -```erg +```python {X: Int | X**2 - 5X + 6 == 0} # SyntaxError: the predicate form is invalid. Only names can be on the left-hand side ``` @@ -34,14 +34,14 @@ However, the Erg compiler has very little knowledge of algebra, so it cannot sol It's nice that you defined `Odd`, but as it is, it doesn't look like it can be used much outside of literals. To promote an odd number in a normal `Int` object to `Odd`, i.e., to downcast an `Int` to `Odd`, you need to pass the constructor of `Odd`. For refinement types, the normal constructor `.new` may panic, and there is an auxiliary constructor called `.try_new` that returns a `Result` type. -```erg +```python i = Odd.new (0..10).sample!() i: Odd # or Panic ``` It can also be used as a type specification in `match`. -```erg +```python # i: 0..10 i = (0..10).sample! match i: @@ -58,7 +58,7 @@ However, Erg cannot currently make sub-decisions such as `Even` because it was n The enumerative/interval types introduced before are syntax sugar of the refinement type. `{a, b, ...}` is `{I: Typeof(a) | I == a or I == b or ... }`, and `a..b` is desugarized to `{I: Typeof(a) | I >= a and I <= b}`. -```erg +```python {1, 2} == {I: Int | I == 1 or I == 2} 1..10 == {I: Int | I >= 1 and I <= 10} 1... <10 == {I: Int | I >= 1 and I < 10} @@ -68,7 +68,7 @@ The enumerative/interval types introduced before are syntax sugar of the refinem Just as `_: {X}` can be rewritten as `X` (constant pattern), `_: {X: T | Pred}` can be rewritten as `X: T | Pred`. -```erg +```python # method `.m` is defined for arrays of length 3 or greater Array(T, N | N >= 3) .m(&self) = ... diff --git a/doc/EN/syntax/type/13_algebraic.md b/doc/EN/syntax/type/13_algebraic.md index f910147a..e214c71d 100644 --- a/doc/EN/syntax/type/13_algebraic.md +++ b/doc/EN/syntax/type/13_algebraic.md @@ -10,7 +10,7 @@ Union types can give multiple possibilities for types. As the name suggests, the A typical Union is the `Option` type. The `Option` type is a `T or NoneType` patch type, primarily representing values that may fail. -```erg +```python IntOrStr = Int or Str assert dict.get("some key") in (Int or NoneType) @@ -22,7 +22,7 @@ Option T = T or NoneType Intersection types are got by combining types with the `and` operation. -```erg +```python Num = Add and Sub and Mul and Eq ``` @@ -33,7 +33,7 @@ As mentioned above, normal classes cannot be combined with the `and` operation. Diff types are got by `not` operation. It is better to use `and not` as a closer notation to English text, but it is recommended to use just `not` because it fits better alongside `and` and `or`. -```erg +```python CompleteNum = Add and Sub and Mul and Div and Eq and Ord Num = CompleteNum not Div not Ord @@ -47,7 +47,7 @@ Complement types is got by the `not` operation, which is a unary operation. The Intersection with type `not T` is equivalent to Diff, and Diff with type `not T` is equivalent to Intersection. However, this way of writing is not recommended. -```erg +```python # the simplest definition of the non-zero number type NonZero = Not {0} # deprecated styles @@ -61,7 +61,7 @@ There are two algebraic types: apparent algebraic types that can be simplified a The "apparent algebraic types" include `or` and `and` of Enum, Interval, and the Record types. These are not true algebraic types because they are simplified, and using them as type specifiers will result in a Warning; to eliminate the Warning, you must either simplify them or define their types. -```erg +```python assert {1, 2, 3} or {2, 3} == {1, 2, 3} assert {1, 2, 3} and {2, 3} == {2, 3} assert -2..-1 or 1..2 == {-2, -1, 1, 2} @@ -77,7 +77,7 @@ q: Point2D = {x = 1; y = 2; z = 3} True algebraic types include the types `Or` and `And`. Classes such as `or` between classes are of type `Or`. -```erg +```python assert Int or Str == Or(Int, Str) assert Int and Marker == And(Int, Marker) ``` diff --git a/doc/EN/syntax/type/15_quantified.md b/doc/EN/syntax/type/15_quantified.md index 368aaaf5..9c76157a 100644 --- a/doc/EN/syntax/type/15_quantified.md +++ b/doc/EN/syntax/type/15_quantified.md @@ -3,14 +3,14 @@ A type variable is a variable used, for example, to specify the type of subroutine arguments, and its type is arbitrary (not monomorphic). First, as motivation for introducing type variables, consider the `id` function, which returns input as is. -```erg +```python id x: Int = x ``` The `id` function that returns the input as is is defined for the type `Int`, but this function can obviously be defined for any type. Let's use `Object` for the largest class. -```erg +```python id x: Object = x i = id 1 @@ -21,7 +21,7 @@ b = id True Sure, it now accepts arbitrary types, but there is one problem: the return type is expanded to `Object`. The return type is expanded to `Object`. I would like to see the return type `Int` if the input is of type `Int`, and `Str` if it is of type `Str`. -```erg +```python print! id 1 # id(1) + 1 # TypeError: cannot add `Object` and `Int ``` @@ -29,7 +29,7 @@ id(1) + 1 # TypeError: cannot add `Object` and `Int To ensure that the type of the input is the same as the type of the return value, use a __type variable__. Type variables are declared in `||`(type variable list). -```erg +```python id|T: Type| x: T = x assert id(1) == 1 assert id("foo") == "foo" @@ -39,7 +39,7 @@ assert id(True) == True This is called the __universal quantification (universalization)__ of the function. There are minor differences, but it corresponds to the function called generics in other languages. A universalized function is called a __polymorphic function__. Defining a polymorphic function is like defining a function of the same form for all types (Erg prohibits overloading, so the code below cannot really be written). -```erg +```python id|T: Type| x: T = x # pseudo code id x: Int = x @@ -56,7 +56,7 @@ You can also omit `|T, N| foo: [T; N]` if it can be inferred to be other than a You can also provide constraints if the type is too large for an arbitrary type. Constraints also have advantages, for example, a subtype specification allows certain methods to be used. -```erg +```python # T <: Add # => T is a subclass of Add # => can do addition @@ -68,7 +68,7 @@ In this case, `T` is satisfied by `Int`, `Ratio`, etc. So, the addition of `Int` You can also type it like this. -```erg +```python f| Y, Z: Type X <: Add Y, O1 @@ -80,7 +80,7 @@ f| If the annotation list is long, you may want to pre-declare it. -```erg +```python f: |Y, Z: Type, X <: Add(Y, O1), O1 <: Add(Z, O2), O2 <: Add(X, O3)| (X, Y, Z) -> O3 f|X, Y, Z| x: X, y: Y, z: Z = x + y + z + x @@ -90,7 +90,7 @@ Unlike many languages with generics, all declared type variables must be used ei This is a requirement from Erg's language design that all type variables are inferrable from real arguments. So information that cannot be inferred, such as the return type, is passed from real arguments; Erg allows types to be passed from real arguments. -```erg +```python Iterator T = Trait { # Passing return types from arguments. # .collect: |K: Type -> Type| Self(T). ({K}) -> K(T) @@ -104,7 +104,7 @@ it.collect(Array) # [2, 3, 4]. Type variables can only be declared during `||`. However, once declared, they can be used anywhere until they exit scope. -```erg +```python f|X|(x: X): () = y: X = x.clone() log X.__name__ @@ -117,14 +117,14 @@ f 1 You can also explicitly monophasize at the time of use as follows -```erg +```python f: Int -> Int = id|Int| ``` In that case, the specified type takes precedence over the type of the actual argument (failure to match will result in a type error that the type of the actual argument is wrong). That is, if the actual object passed can be converted to the specified type, it will be converted; otherwise, a compile error will result. -```erg +```python assert id(1) == 1 assert id|Int|(1) in Int assert id|Ratio|(1) in Ratio @@ -135,14 +135,14 @@ id|Int|("str") # TypeError: id|Int| is type `Int -> Int` but got Str When this syntax is batting against comprehensions, you need to enclose it in `()`. -```erg +```python # {id|Int| x | x <- 1..10} would be interpreted as {id | ...} will be interpreted as. {(id|Int| x) | x <- 1..10} ``` A type variable cannot be declared with the same name as a type that already exists. This is because all type variables are constants. -```erg +```python I: Type # ↓ invalid type variable, already exists f|I: Type| ... = ... @@ -152,7 +152,7 @@ f|I: Type| ... = ... Type arguments on the left-hand side are treated as bound variables by default. -```erg +```python K(T: Type, N: Nat) = ... K(T, N). foo(x) = ... @@ -160,7 +160,7 @@ K(T, N). Using another type variable name will result in a warning. -```erg +```python K(T: Type, N: Nat) = ... K(U, M). # Warning: K's type variable names are 'T' and 'N' foo(x) = ... @@ -168,7 +168,7 @@ K(U, M). # Warning: K's type variable names are 'T' and 'N' Constants are the same in all namespaces since their definition, so of course they cannot be used for type variable names. -```erg +```python N = 1 K(N: Nat) = ... # NameError: N is already defined @@ -183,7 +183,7 @@ L(M). You cannot have multiple definitions for each type argument, but you can define methods with the same name because there is no relationship between dependent types that are not assigned type arguments (non-primitive-kind) and dependent types that are assigned (primitive-kind). -```erg +```python K(I: Int) = ... K. # K is not a true type (atomic Kind), so we cannot define a method @@ -197,7 +197,7 @@ K(0). The `id` function defined in the previous section is a function that can be of any type. So what is the type of the `id` function itself? -```erg +```python print! classof(id) # |T: Type| T -> T ``` @@ -207,7 +207,7 @@ There is a restriction on the closed universal quantified type: only subroutine Like anonymous functions, polymorphic types have arbitrary type variable names, but they all have the same value. -```erg +```python assert (|T: Type| T -> T) == (|U: Type| U -> U) ``` @@ -222,14 +222,14 @@ In contrast, a type in which type variables are defined and used on the right-ha An open universal type is a supertype of all isomorphic "true" types. In contrast, a closed universal type is a subtype of all isomorphic true types. -```erg +```python (|T: Type| T -> T) < (Int -> Int) < (T -> T) ``` You may remember that closed ones are smaller/open ones are larger. But why is this so? For a better understanding, let's consider an instance of each. -```erg +```python # id: |T: Type| T -> T id|T|(x: T): T = x @@ -265,7 +265,7 @@ The important point is that there are no type arguments in the closed, polymorph In Erg, the type itself is also a value, so types that take arguments, such as function types, will probably be dependent types. In other words, polymorphic function types are both a quantified type and a dependent type. -```erg +```python PolyFn = Patch(|T| T -> T) PolyFn. type self = T # NameError: cannot find 'T' diff --git a/doc/EN/syntax/type/16_subtyping.md b/doc/EN/syntax/type/16_subtyping.md index e5ed7cf9..ca71245c 100644 --- a/doc/EN/syntax/type/16_subtyping.md +++ b/doc/EN/syntax/type/16_subtyping.md @@ -2,7 +2,7 @@ In Erg, class inclusion can be determined with the comparison operators `<`, `>`. -```erg +```python Nat < Int Int < Object 1... _ < Nat @@ -13,7 +13,7 @@ Int < Object Note that this has a different meaning than the `<:` operator. It declares that the class on the left-hand side is a subtype of the type on the right-hand side, and is meaningful only at compile-time. -```erg +```python C <: T # T: StructuralType f|D <: E| ... @@ -26,7 +26,7 @@ You can also specify `Self <: Add` for a polymorphic subtype specification, for Structural types are types for structural typing and are considered to be the same object if they have the same structure. -```erg +```python T = Structural {i = Int} U = Structural {i = Int} @@ -38,7 +38,7 @@ assert t in U In contrast, classes are types for notational typing and cannot be compared structurally to types and instances. -```erg +```python C = Class {i = Int} D = Class {i = Int} @@ -54,7 +54,7 @@ Arguments and return values of subroutines take only a single class. In other words, you cannot directly specify a structural type or a trait as the type of a function. It must be specified as "a single class that is a subtype of that type" using the partial type specification. -```erg +```python # OK f1 x, y: Int = x + y # NG @@ -68,7 +68,7 @@ Type inference in subroutines also follows this rule. When a variable in a subro ## Class upcasting -```erg +```python i: Int i as (Int or Str) i as (1..10) diff --git a/doc/EN/syntax/type/17_type_casting.md b/doc/EN/syntax/type/17_type_casting.md index 65ef9207..f1465b5c 100644 --- a/doc/EN/syntax/type/17_type_casting.md +++ b/doc/EN/syntax/type/17_type_casting.md @@ -8,7 +8,7 @@ A simple example is `1 + 2.0`: the `+`(Int, Ratio), or Int(<: Add(Ratio, Ratio)) ~~The Erg extended bytecode adds type information to BINARY_ADD, in which case the type information is Ratio-Ratio. In this case, the BINARY_ADD instruction does the casting of Int, so no special instruction specifying the cast is inserted. So, for example, even if you override a method in a child class, if you specify the parent as the type, type coercion is performed and the method is executed in the parent's method (name modification is performed at compile time to refer to the parent's method). The compiler only performs type coercion validation and name modification. The runtime does not cast objects (currently. Cast instructions may be implemented for execution optimization). ~~ -```erg +```python @Inheritable Parent = Class() Parent. @@ -31,7 +31,7 @@ child # "Hello from Parent" This behavior does not create an incompatibility with Python. In the first place, Python does not specify the type of a variable, so that all variables are typed as type variables, so to speak. Since type variables choose the smallest type they can fit, the same behavior as in Python is achieved if you do not specify a type in Erg. -```erg +```python @Inheritable Parent = Class() Parent. @@ -52,7 +52,7 @@ child # "Hello from Child" You can also use `.from` and `.into`, which are automatically implemented for types that are inherited from each other. -```erg +```python assert 1 == 1.0 assert Ratio.from(1) == 1.0 assert 1.into() == 1.0 @@ -62,7 +62,7 @@ assert 1.into() == 1.0 Since downcasting is generally unsafe and the conversion method is non-trivial, we instead implement ``TryFrom.try_from``. -```erg +```python IntTryFromFloat = Patch Int IntTryFromFloat. try_from r: Float = diff --git a/doc/EN/syntax/type/advanced/erasure.md b/doc/EN/syntax/type/advanced/erasure.md index 94f9e01a..ff485c46 100644 --- a/doc/EN/syntax/type/advanced/erasure.md +++ b/doc/EN/syntax/type/advanced/erasure.md @@ -6,7 +6,7 @@ The most common example of a type that has been type-erased is `[T, _]`. Arrays However, a type that has been type-erased becomes a supertype of a type that has not been (e.g. `[T; N] <: [T; _]`), so it can accept more objects. Objects of type `[T; N]` can of course use methods of type `[T; _]`, but the `N` information is erased after use. If the length does not change, then it is possible to use `[T; N]` in the signature. If the length remains the same, it must be indicated by a signature. -```erg +```python # Functions that are guaranteed to not change the length of the array (e.g., sort) f: [T; N] -> [T; N] # functions that do not (f: [T; N]) # functions that do not (e.g. filter) @@ -16,14 +16,14 @@ g: [T; n] -> [T; _] If you use `_` in the type specification itself, the type is upcast to `Object`. For non-type type arguments (Int, Bool, etc.), the parameter with `_` will be undefined. -```erg +```python i: _ # i: Object [_; _] == [Object; _] == Array ``` Type erasure is not the same as omitting a type specification. Once the type argument information has been erased, it will not be returned unless you assert it again. -```erg +```python implicit = (1..5).iter().map(i -> i * 2).to_arr() explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat)) ``` @@ -36,7 +36,7 @@ let partial = (1..6).iter().map(|i| i * 2).collect::>(); Erg does not allow partial omission of types, but uses higher-order kind polymorphism instead. -```erg +```python # collect is a higher-order Kind method that takes Kind hk = (1..5).iter().map(i -> i * 2).collect(Array) hk: Array(Int) diff --git a/doc/EN/syntax/type/advanced/existential.md b/doc/EN/syntax/type/advanced/existential.md index 5cc1ef99..34c385fa 100644 --- a/doc/EN/syntax/type/advanced/existential.md +++ b/doc/EN/syntax/type/advanced/existential.md @@ -3,7 +3,7 @@ If there is a for-all type corresponding to ∀, it is natural to assume that there is an existential type corresponding to ∃. Existential types are not difficult. You already know the existential type, just not consciously aware of it as such. -```erg +```python T: Trait f x: T = ... ``` @@ -11,7 +11,7 @@ f x: T = ... The trait `T` above is used as the existential type. In contrast, `T` in the lower case is only a trait, and `X` is an for-all type. -```erg +```python f|X <: T| x: X = ... ``` @@ -19,7 +19,7 @@ In fact, the existential type is replaced by an for-all type. So why is there su First of all, as we saw above, existential types do not involve type variables, which simplifies type specification. Also, since the type variable can be removed, it is possible to construct a type that would have rank 2 or higher if it were an all-presumptive type. -```erg +```python show_map f: (|T| T -> T), arr: [Show; _] = arr.map x -> y = f x @@ -30,7 +30,7 @@ show_map f: (|T| T -> T), arr: [Show; _] = However, as you can see, the existential type forgets or expands the original type, so if you do not want to expand the return type, you must use the for-all type. Conversely, types that are only taken as arguments and are not relevant to the return value may be written as existential types. -```erg +```python # id(1): I want it to be Int id|T|(x: T): T = x # |S <: Show|(s: S) -> () is redundant diff --git a/doc/EN/syntax/type/advanced/mut_struct.md b/doc/EN/syntax/type/advanced/mut_struct.md index 9fdd8479..b23de3c9 100644 --- a/doc/EN/syntax/type/advanced/mut_struct.md +++ b/doc/EN/syntax/type/advanced/mut_struct.md @@ -2,7 +2,7 @@ The ``T!`` type is described as a box type that can be replaced by any ``T`` type object. -```erg +```python Particle!State: {"base", "excited"}! = Class(... Impl := Phantom State) Particle! # This method moves the State from "base" to "excited". @@ -19,7 +19,7 @@ In other words, the length cannot be changed. To change the length, the structur This is achieved by Mutable structure (mutable) types. -```erg +```python v = [Str; !0].new() v.push! "Hello" v: [Str; !1]. @@ -30,7 +30,7 @@ Incidentally, the `[T; !N]` type is the sugar-coated syntax of the `ArrayWithLen Mutable structure types can of course be user-defined. Note, however, that there are some differences from invariant structure types in terms of the construction method. -```erg +```python Nil T = Class(Impl := Phantom T) List T, !0 = Inherit Nil T List T, N: Nat! = Class {head = T; rest = List(T, !N-1)} diff --git a/doc/EN/syntax/type/advanced/newtype.md b/doc/EN/syntax/type/advanced/newtype.md index bf08c2a0..96d65399 100644 --- a/doc/EN/syntax/type/advanced/newtype.md +++ b/doc/EN/syntax/type/advanced/newtype.md @@ -4,7 +4,7 @@ Here is the Erg version of the newtype pattern commonly used in Rust. Erg allows type aliases to be defined as follows, but they only refer to the same type. -```erg +```python UserId = Int ``` @@ -14,7 +14,7 @@ Also, for example, when designing a database system, suppose there are several t The newtype pattern is a good design pattern for such cases. -```erg +```python UserId = Class {id = Nat} UserId. new id: Nat = diff --git a/doc/EN/syntax/type/advanced/overloading.md b/doc/EN/syntax/type/advanced/overloading.md index 6f621555..99740240 100644 --- a/doc/EN/syntax/type/advanced/overloading.md +++ b/doc/EN/syntax/type/advanced/overloading.md @@ -3,7 +3,7 @@ Erg does not support __ad hoc polymorphism__. That is, multiple definitions of functions and Kinds (overloading) are not possible. However, you can reproduce the overloading behavior by using a combination of a trait and a patch. You can use traits instead of trait classes, but then all types that implement `.add1` will be covered. -```erg +```python Add1 = Trait { .add1: Self.() -> Self } @@ -24,7 +24,7 @@ Such a polymorphism by accepting all subtypes of a type is called __subtyping po If the process is exactly the same for each type, it can be written as below. The above is used when the behavior changes from class to class (but the return type is the same). A polymorphism that uses type arguments is called __parametric polymorphism__. Parametric polymorphism is often used in conjunction with subtyping, as shown below, in which case it is a combination of parametric and subtyping polymorphism. -```erg +```python add1|T <: Int or Str| x: T = x + 1 assert add1(1) == 2 assert add1(1.0) == 2.0 @@ -32,7 +32,7 @@ assert add1(1.0) == 2.0 Also, overloading of types with different numbers of arguments can be reproduced with default arguments. -```erg +```python C = Class {.x = Int; .y = Int} C. new(x, y := 0) = Self::__new__ {.x; .y} @@ -47,7 +47,7 @@ In conclusion, Erg prohibits overloading and adopts subtyping plus parametric po First, overloaded functions are distributed in their definitions. This makes it difficult to report the cause of an error when it occurs. Also, importing a subroutine may change the behavior of already defined subroutines. -```erg +```python {id; ...} = import "foo" ... id x: Int = x @@ -60,7 +60,7 @@ id "str" # TypeError: id is not implemented for Str Second, it is incompatible with default arguments. When a function with default arguments is overloaded, there is a problem with which one takes precedence. -```erg +```python f x: Int = ... f(x: Int, y := 0) = ... @@ -70,7 +70,7 @@ f(1) # which is chosen? Furthermore, it is incompatible with the declaration. The declaration `f: Num -> Num` cannot specify which definition it refers to. This is because `Int -> Ratio` and `Ratio -> Int` are not inclusive. -```erg +```python f: Num -> Num f(x: Int): Ratio = ... f(x: Ratio): Int = ... @@ -79,7 +79,7 @@ f(x: Ratio): Int = ... And the grammar is inconsistent: Erg prohibits variable reassignment, but the overloaded grammar looks like reassignment. Nor can it be replaced by an anonymous function. -```erg +```python # same as `f = x -> body` f x = body diff --git a/doc/EN/syntax/type/advanced/phantom.md b/doc/EN/syntax/type/advanced/phantom.md index 9abfeade..b36d8b5e 100644 --- a/doc/EN/syntax/type/advanced/phantom.md +++ b/doc/EN/syntax/type/advanced/phantom.md @@ -3,7 +3,7 @@ Phantom types are marker traits that exist only to provide annotations to the compiler. As a usage of phantom types, let's look at the structure of a list. -```erg +```python Nil = Class() List T, 0 = Inherit Nil List T, N: Nat = Class {head = T; rest = List(T, N-1)} @@ -11,7 +11,7 @@ List T, N: Nat = Class {head = T; rest = List(T, N-1)} This code results in an error. -```erg +```python 3 | List T, 0 = Inherit Nil ^^^ TypeConstructionError: since Nil does not have a parameter T, it is not possible to construct List(T, 0) with Nil @@ -21,7 +21,7 @@ hint: use 'Phantom' trait to consume T This error is a complaint that `T` cannot be type inferred when `List(_, 0).new Nil.new()` is used. In such a case, whatever the `T` type is, it must be consumed on the right-hand side. A type of size zero, such as a tuple of length zero, is convenient because it has no runtime overhead. -```erg +```python Nil T = Class((T; 0)) List T, 0 = Inherit Nil T List T, N: Nat = Class {head = T; rest = List(T, N-1)} @@ -31,7 +31,7 @@ This code passes compilation. But it's a little tricky to understand the intent, In such a case, a phantom type is just what you need. A phantom type is a generalized type of size 0. -```erg +```python Nil T = Class(Impl := Phantom T) List T, 0 = Inherit Nil T List T, N: Nat = Class {head = T; rest = List(T, N-1)} @@ -45,7 +45,7 @@ assert nil.__size__ == 0 Also, `Phantom` can consume arbitrary type arguments in addition to its type. In the following example, `Phantom` holds a type argument called `State`, which is a subtype object of `Str`. Again, `State` is a fake type variable that does not appear in the object's entity. -```erg +```python VM! State: {"stopped", "running"}! = Class(... State) VM!("stopped"). start ref! self("stopped" ~> "running") = diff --git a/doc/EN/syntax/type/advanced/projection.md b/doc/EN/syntax/type/advanced/projection.md index e9ce3ae4..57668930 100644 --- a/doc/EN/syntax/type/advanced/projection.md +++ b/doc/EN/syntax/type/advanced/projection.md @@ -2,7 +2,7 @@ A projection type represents a type such as ``Self.AddO`` in the following code. -```erg +```python Add R = Trait { . `_+_` = Self, R -> Self.AddO .AddO = Type @@ -16,7 +16,7 @@ AddForInt. The type ``Add(R)`` can be said to be a type that defines addition with some object. Since the method should be a type attribute, the `+` type declaration should be written below the indentation. The mise-en-scène of the `Add` type is the declaration `.AddO = Type`, and the entity of the `.AddO` type, which is a projective type, is held by a type that is a subtype of `Add`. For example, `Int.AddO = Int`, `Odd.AddO = Even`. -```erg +```python assert Int < Add assert Int.AddO == Int assert Odd < Add diff --git a/doc/EN/syntax/type/advanced/quantified_dependent.md b/doc/EN/syntax/type/advanced/quantified_dependent.md index 28afb5ed..623f206f 100644 --- a/doc/EN/syntax/type/advanced/quantified_dependent.md +++ b/doc/EN/syntax/type/advanced/quantified_dependent.md @@ -2,7 +2,7 @@ Erg has quantified and dependent types. Then naturally, it is possible to create a type that combines the two. That is the quantified dependent type. -```erg +```python NonNullStr = |N: Nat| StrWithLen N | N ! = 0 # same as {S | N: Nat; S: StrWithLen N; N ! = 0} NonEmptyArray = |N: Nat| [_; N | N > 0] # same as {A | N: Nat; A: Array(_, N); N > 0} ``` @@ -11,7 +11,7 @@ The standard form of quantified dependent types are `K(A, ... | Pred)`. ``K`` is Quantified dependent types as left-hand side values can only define methods in the same module as the original type. -```erg +```python K A: Nat = Class ... K(A). ... @@ -21,7 +21,7 @@ K(A | A >= 1). Quantified dependent types as right-hand side values require that the type variable to be used be declared in the type variable list (`||`). -```erg +```python # T is a concrete type a: |N: Nat| [T; N | N > 1] ``` diff --git a/doc/EN/syntax/type/advanced/shared.md b/doc/EN/syntax/type/advanced/shared.md index ccc907ae..69b7cb7e 100644 --- a/doc/EN/syntax/type/advanced/shared.md +++ b/doc/EN/syntax/type/advanced/shared.md @@ -21,7 +21,7 @@ The relation `VIPMember[] <: NormalMember[]` is fine for immutable objects. Howe In Erg, such code is played back due to the ownership system. -```erg +```python NormalMember = Class() VIPMember = Class() @@ -35,7 +35,7 @@ log vip_area # OwnershipError: `vip_room` was moved to `normal_room` However, it can be inconvenient for an object to be owned by only one place. For this reason, Erg has a type `SharedCell!T!`, which represents a shared state. -```erg +```python $p1 = SharedCell!.new(!1) $p2 = $p1.mirror!() $p3 = SharedCell!.new(!1) @@ -57,7 +57,7 @@ The `SharedCell! T!` type is also a subtype of `T!` and can call methods of type An important fact is that `SharedCell! T!` is non-variant, i.e., no inclusions are defined for different type arguments. -```erg +```python $vip_area = SharedCell!.new([].into [VIPMember; !_]) $normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError: expected SharedCell!([NormalMember; !_]), but got SharedCell!([VIPMember; !_]) # hint: SharedCell!(T) is non-variant, which means it cannot have a supertype or a subtype. @@ -65,7 +65,7 @@ $normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError: However, the following code have not problem. In the last line, it's the `VIPMember` argument that has been typed converted. -```erg +```python $normal_area = SharedCell!.new([].into [NormalMember; !_]) $normal_area.push!(NormalMember.new()) # OK $normal_area.push!(VIPMember.new()) # OK diff --git a/doc/EN/tips.md b/doc/EN/tips.md index b90de192..1baf322d 100644 --- a/doc/EN/tips.md +++ b/doc/EN/tips.md @@ -7,7 +7,7 @@ However, external libraries may not support multiple languages. ## Want to change only certain attributes of a record -```erg +```python record: {.name = Str; .age = Nat; .height = CentiMeter} {height; rest; ...} = record mut_record = {.height = !height; ...rest} @@ -17,7 +17,7 @@ mut_record = {.height = !height; ...rest} Shadowing in the same scope is not possible with Erg. However, you can redefine them if the scope changes (This is a syntax called instance block). -````erg +````python ## Get a T!-type object and finally assign it to a variable as type T x: T = x: T! = foo() @@ -29,7 +29,7 @@ x: T = You can create a wrapper class. This is a so-called composition pattern. -```erg +```python FinalWrapper = Class {inner = FinalClass} FinalWrapper. method self = @@ -43,7 +43,7 @@ You can define a traditional enumerated type (algebraic data type) commonly foun If you implement `Singleton`, classes and instances are identical. Also, if you use `Enum`, the type of choice is automatically defined as a redirect attribute. -```erg +```python Ok = Class Impl := Singleton Err = Class Impl := Singleton ErrWithInfo = Inherit {info = Str} @@ -55,7 +55,7 @@ match! stat: Status.ErrWithInfo::{info} -> ... ``` -```erg +```python Status = Enum Ok, Err, ErrWithInfo # is equivalent to Status = Class Ok or Err or ErrWithInfo @@ -69,7 +69,7 @@ Status. method 1: -```erg +```python arr = [...] for! arr.iter().enumerate(start: 1), i => ... @@ -77,7 +77,7 @@ for! arr.iter().enumerate(start: 1), i => method 2: -```erg +```python arr = [...] for! arr.iter().zip(1...) , i => ... @@ -88,12 +88,12 @@ for! arr.iter().zip(1...) , i => The private API in `foo.er` is specially accessible in the module `foo.test.er`. The `foo.test.er` module cannot be imported, so it remains hidden. -```erg +```python # foo.er private x = ... ``` -```erg +```python # foo.test.er foo = import "foo" @@ -108,7 +108,7 @@ foo = import "foo" You can make the attribute private and define a getter. -```erg +```python C = Class {v = Int!} C:: inc_v!(ref! self) = self::v.inc!() @@ -122,7 +122,7 @@ C. You can receive arguments by record. -```erg +```python Point = {x = Int; y = Int} norm: Point -> Int diff --git a/doc/JA/API/funcs.md b/doc/JA/API/funcs.md index 3c99f88d..671a7e99 100644 --- a/doc/JA/API/funcs.md +++ b/doc/JA/API/funcs.md @@ -27,7 +27,7 @@ msgを表示して停止する。 `x`を捨てる。戻り値を使用しないときなどに使う。`del`とは違い、変数`x`を参照できなくするわけではない。 -```erg +```python p! x = # q!は何らかのNoneや()でない値を返すとする # 要らない場合は`discard`を使う @@ -56,7 +56,7 @@ codeをコードとして評価し返す。 ### repeat|T|(x: T) -> RepeatIterator T -```erg +```python rep = repeat 1 # Repeater(1) for! rep, i => print! i @@ -65,7 +65,7 @@ for! rep, i => ### dup|T; N|(x: T, N: Nat) -> [T; N] -```erg +```python [a, b, c] = dup new(), 3 print! a # print! a == b # False @@ -73,7 +73,7 @@ print! a == b # False ### cycle|T|(it: Iterable T) -> CycleIterator T -```erg +```python cycle([0, 1]).take 4 # [0, 1, 0, 1] cycle("hello").take 3 # "hellohellohello" ``` @@ -85,7 +85,7 @@ cycle("hello").take 3 # "hellohellohello" クラスを新しく生成する。`Inherit`とは違い、`Class`を通すとベース型からは独立し、メソッドは失われる。 比較もできなくなるが、パターンマッチなどは行える。 -```erg +```python C = Class {i = Int} NewInt = Class Int Months = Class 1..12 @@ -111,7 +111,7 @@ match jan: 引数の型を返す。実行時のクラスを得たい場合は`classof`を使う。 型指定に使うとWarningが出る。 -```erg +```python x: Typeof i = ... # TypeWarning: Typeof(i) == Int, please replace it ``` diff --git a/doc/JA/API/modules/external/alstruct.md b/doc/JA/API/modules/external/alstruct.md index 7542d9f3..ce7573f8 100644 --- a/doc/JA/API/modules/external/alstruct.md +++ b/doc/JA/API/modules/external/alstruct.md @@ -6,7 +6,7 @@ ## BinOp -```erg +```python BinOp Op: Kind 2 = Subsume Op(Self, Self.ReturnTypeOf Op), Additional: { .ReturnTypeof = TraitType -> Type } @@ -20,7 +20,7 @@ assert Nat.ReturnTypeof(Div) == Positive Ratio ## SemiGroup -```erg +```python SemiGroup Op: Kind 2 = Op(Self, Self) IntIsSemiGroupAdd = Patch Int, Impl=SemiGroup Add @@ -30,7 +30,7 @@ Int <: SemiGroup Add ## Functor -```erg +```python ## * Identity law: x.map(id) == x ## * Composition law: x.map(f).map(g) == x.map(f.then g) Functor = Trait { @@ -40,7 +40,7 @@ Functor = Trait { ## Applicative -```erg +```python ## * Identity law: x.app(X.pure(id)) == x Applicative = Subsume Functor, Additional: { .pure|T: Type| = T -> Self T @@ -50,7 +50,7 @@ Applicative = Subsume Functor, Additional: { ## Monad -```erg +```python Monad = Subsume Applicative, Additional: { .bind|T, U: Type| = (Self(T), T -> Self U) -> Self U } diff --git a/doc/JA/API/modules/repl.md b/doc/JA/API/modules/repl.md index f2ee4894..696fee1e 100644 --- a/doc/JA/API/modules/repl.md +++ b/doc/JA/API/modules/repl.md @@ -18,7 +18,7 @@ provides REPL(Read-Eval-Print-Loop)-related APIs. 与えられた引数と戻り値から、関数を推測する。 -```erg +```python 1.guess((1,), 2) # [1, 2].guess((3, 4), [1, 2, 3, 4]) # ``` diff --git a/doc/JA/API/modules/unit.md b/doc/JA/API/modules/unit.md index a853a43e..2672ff06 100644 --- a/doc/JA/API/modules/unit.md +++ b/doc/JA/API/modules/unit.md @@ -6,7 +6,7 @@ Ergの数値型は`Nat`, `Int`, `Ratio`などがあります。しかしこれ このようなミスは実際に起っており、[単位系の取り間違いで火星探査機が行方不明](http://www.sydrose.com/case100/287/)になるなど、深刻なバグを引き起こしかねません。 数値計算を行う上でコードの堅牢性を高めたいならばこのモジュールを使用しておくべきです。 -```erg +```python {*} = import "unit" x = 6m # `x = Meter.new(6)`と等価 @@ -33,7 +33,7 @@ unitでは以下の単位を型として定義しています。SI(国際単位 例えば、振動数の単位ヘルツ(hertz)は振動周期(秒)の逆数で定義されているので、`UnitDiv(Unit1, Sec)`です。 この型を意味のある型とみなしたい(専用のメソッドを加えたい、など)ときは、[パッチ](./../../syntax/type/07_patch.md)を作成すると良いでしょう。 -```erg +```python Hertz = Patch UnitDiv(Unit1, Sec) SquareMeter = Patch UnitMul(Meter, Meter) ``` diff --git a/doc/JA/API/modules/unsound.md b/doc/JA/API/modules/unsound.md index 59bc56b7..592b4222 100644 --- a/doc/JA/API/modules/unsound.md +++ b/doc/JA/API/modules/unsound.md @@ -6,7 +6,7 @@ Provides APIs perform unsound and unsafe operations that cannot be guaranteed sa Executes a `Unsafe` procedure. Just like Rust, `Unsafe` APIs cannot be called directly, but are all passed as higher-order functions to this procedure. -```erg +```python unsound = import "unsound" i = unsound.unsafe! do!: diff --git a/doc/JA/API/procs.md b/doc/JA/API/procs.md index 852369c9..999b30c4 100644 --- a/doc/JA/API/procs.md +++ b/doc/JA/API/procs.md @@ -2,7 +2,7 @@ ## print! -```erg +```python print!(x) -> NoneType ``` @@ -10,7 +10,7 @@ print!(x) -> NoneType ## debug! -```erg +```python debug!(x, type = Info) -> NoneType ``` diff --git a/doc/JA/API/special.md b/doc/JA/API/special.md index 8ded9cc0..766adffc 100644 --- a/doc/JA/API/special.md +++ b/doc/JA/API/special.md @@ -9,7 +9,7 @@ bodyをpatに変数として代入する。同じスコープにすでに変数が存在する場合と、patにマッチしなかった場合にエラーを送出する。 また、レコードの属性定義やデフォルト引数にも使われる。 -```erg +```python record = {i = 1; j = 2} f(x: Int, y = 2) = ... ``` @@ -17,7 +17,7 @@ f(x: Int, y = 2) = ... bodyが型か関数であるときに`=`は特殊な振る舞いをする。 左辺の変数名を右辺のオブジェクトに埋め込むのである。 -```erg +```python print! Class() # > print! x: Int -> x + 1 # > C = Class() @@ -35,7 +35,7 @@ print! L # `=`演算子は、戻り値が「未定義」である。 多重代入、関数中での`=`は文法エラーとなる。 -```erg +```python i = j = 1 # SyntaxError: multiple assignments are not allowed print!(x=1) # SyntaxError: cannot use `=` in function arguments # hint: did you mean keyword arguments (`x: 1`)? @@ -55,14 +55,14 @@ if True, do: subjectがTに合致しているか判定する。合致していない場合はコンパイルエラーを送出する。 -```erg +```python a: Int f x: Int, y: Int = x / y ``` また、`:`適用スタイルにも使われる。 -```erg +```python f x: y z @@ -70,7 +70,7 @@ f x: `:`も`=`と同じく演算の結果が未定義である。 -```erg +```python _ = x: Int # SyntaxError: print!(x: Int) # SyntaxError: ``` @@ -92,7 +92,7 @@ objの属性を読み込む。 objについて、パターンにマッチしたlambdaを実行する。 -```erg +```python match [1, 2, 3]: (l: Int) -> log "this is type of Int" [[a], b] -> log a, b @@ -104,7 +104,7 @@ match [1, 2, 3]: 変数`x`を削除する。ただし組み込みのオブジェクトは削除できない。 -```erg +```python a = 1 del a # OK @@ -124,7 +124,7 @@ del True # SyntaxError: cannot delete a built-in object Choiceオブジェクトという2つ組のタプルのような構造体を生成する。 `l, r`は遅延評価される。すなわち、`.get_then`または`.get_else`が呼ばれたとき初めて式が評価される。 -```erg +```python choice = 1 else 2 assert choice.get_then() == 1 assert choice.get_else() == 2 @@ -153,7 +153,7 @@ assert True.then(choice) == 1 入れ子になったコレクションを展開する。パターンマッチでも使える。 -```erg +```python [x, ...y] = [1, 2, 3] assert x == 1 and y == [2, 3] assert [x, ...y] == [1, 2, 3] diff --git a/doc/JA/API/types/classes/ArrayWithLen(T,N).md b/doc/JA/API/types/classes/ArrayWithLen(T,N).md index 77fc65bb..7b21972d 100644 --- a/doc/JA/API/types/classes/ArrayWithLen(T,N).md +++ b/doc/JA/API/types/classes/ArrayWithLen(T,N).md @@ -6,7 +6,7 @@ * values_at(self, selectors: [Nat; N]) -> [T; N] -```erg +```python assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] ``` @@ -15,7 +15,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] 要素が0のときはpredに関わらず`True`となるが、Warningを出す。 この仕様自体は多くの言語で採用されており、論理学的な整合性から要請される。 - ```erg + ```python assert [].all(_ -> False) ``` @@ -28,7 +28,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] * freq self -> [{T: Nat}] オブジェクトの出現頻度を返す。 -```erg +```python assert ["a", "b", "c", "b", "c", "b"].freq() \ == [{"a", 1}, {"b": 3}, {"c": 2}] ``` diff --git a/doc/JA/API/types/classes/Function(N).md b/doc/JA/API/types/classes/Function(N).md index 0955f2ec..24195350 100644 --- a/doc/JA/API/types/classes/Function(N).md +++ b/doc/JA/API/types/classes/Function(N).md @@ -4,6 +4,6 @@ * then(self, g: Self) -> Self -```erg +```python assert f(g(x)) == f.then(g) x ``` diff --git a/doc/JA/API/types/classes/IntRange.md b/doc/JA/API/types/classes/IntRange.md index 2b536fcb..139a8912 100644 --- a/doc/JA/API/types/classes/IntRange.md +++ b/doc/JA/API/types/classes/IntRange.md @@ -2,7 +2,7 @@ `L..R`のクラス。 -```erg +```python IntRange L, R: Int == L..R ``` @@ -12,7 +12,7 @@ IntRange L, R: Int == L..R 通常の加算。`Int`や`Nat`の加算はそれぞれのクラスで定義されていると見せかけて、ここで定義されている。 -```erg +```python 0..10 + 1..12 == 1..22 Int + 0..10 == _..|Int|_ + 0..10 == _..|Int|_ == Int Nat + Nat == 0.._ + 0.._ == 0.._ == Nat diff --git a/doc/JA/API/types/classes/Interval.md b/doc/JA/API/types/classes/Interval.md index 20588c1a..e613b493 100644 --- a/doc/JA/API/types/classes/Interval.md +++ b/doc/JA/API/types/classes/Interval.md @@ -2,14 +2,14 @@ 整列集合型(WellOrder)の部分型を表す型です。Interval型にはPreOpen(x<..y)などの派生型が存在します。 -```erg +```python Months = 1..12 Alphabet = "a".."z" Weekdays = Monday..Friday Winter = November..December or January..February ``` -```erg +```python 0..1 # 整数の範囲 0.0..1.0 # 実数(有理数)の範囲 # or 0/1..1/1でも同じ diff --git a/doc/JA/API/types/classes/Kind(N).md b/doc/JA/API/types/classes/Kind(N).md index 4a72aec9..b3103d53 100644 --- a/doc/JA/API/types/classes/Kind(N).md +++ b/doc/JA/API/types/classes/Kind(N).md @@ -1,5 +1,5 @@ # Kind N: Nat -```erg +```python Kind N: Nat = (Type; N) -> Type ``` diff --git a/doc/JA/API/types/classes/Nat.md b/doc/JA/API/types/classes/Nat.md index 5fe1d242..1ea213e2 100644 --- a/doc/JA/API/types/classes/Nat.md +++ b/doc/JA/API/types/classes/Nat.md @@ -4,7 +4,7 @@ ## def -```erg +```python Nat = 0.._ ``` @@ -12,7 +12,7 @@ Nat = 0.._ * times!(self, p: () => NoneType) -> NoneType -```erg +```python 100.times! () => print! "hello!" ``` diff --git a/doc/JA/API/types/classes/Never.md b/doc/JA/API/types/classes/Never.md index 4ab9ff94..a403d83e 100644 --- a/doc/JA/API/types/classes/Never.md +++ b/doc/JA/API/types/classes/Never.md @@ -3,7 +3,7 @@ 全ての型の下位型である。全てのメソッドを持っており、当然`.new`も持っているため`Class`である。しかしインスタンスは持たず、生成されそうになった瞬間にErgは停止する。 `Panic`という同じくインスタンスを持たない型が存在するが、正常に終了する際や意図的な無限ループの際は`Never`、異常終了する際には`Panic`を使う。 -```erg +```python # Never <: Panic f(): Panic = exit 0 # OK g(): Never = panic() # TypeError diff --git a/doc/JA/API/types/classes/Option.md b/doc/JA/API/types/classes/Option.md index 11dc2398..8bfa15e2 100644 --- a/doc/JA/API/types/classes/Option.md +++ b/doc/JA/API/types/classes/Option.md @@ -8,7 +8,7 @@ 中身が`T`型であると期待して取り出す。`None`であった場合`msg`を出力してパニックする。 -```erg +```python x = "...".parse(Int).into(Option Int) x.unwrap() # UnwrappingError: unwrapped a None value x.unwrap("failed to convert from string to number") # UnwrappingError: failed to convert from string to number diff --git a/doc/JA/API/types/classes/Record.md b/doc/JA/API/types/classes/Record.md index 97be5017..6babe571 100644 --- a/doc/JA/API/types/classes/Record.md +++ b/doc/JA/API/types/classes/Record.md @@ -3,7 +3,7 @@ レコードの属するクラス。例えば`{i = 1}`は`Structural {i = Int}`型などの要素であり、`{i = Int}`クラスのインスタンスである。 他のクラスのインスタンスはレコード型の要素であってもレコードクラスのインスタンスではないことに注意。 -```erg +```python assert not Structural({i = Int}) in Class assert {i = Int} in Class diff --git a/doc/JA/API/types/classes/Result.md b/doc/JA/API/types/classes/Result.md index 8364f26f..c4c4dc00 100644 --- a/doc/JA/API/types/classes/Result.md +++ b/doc/JA/API/types/classes/Result.md @@ -1,6 +1,6 @@ # Result T, E -```erg +```python Result T, E <: Error = Either T, E ``` diff --git a/doc/JA/API/types/classes/Subroutine.md b/doc/JA/API/types/classes/Subroutine.md index 09317713..1305de92 100644 --- a/doc/JA/API/types/classes/Subroutine.md +++ b/doc/JA/API/types/classes/Subroutine.md @@ -8,7 +8,7 @@ FuncやProcの基底型です。 サブルーチンを中断して、指定した値を返す。ネストから一気に脱出する際に便利。 -```erg +```python f x = for 0..10, i -> if i == 5: diff --git a/doc/JA/API/types/classes/Tensor.md b/doc/JA/API/types/classes/Tensor.md index 0fdb374c..d3468f41 100644 --- a/doc/JA/API/types/classes/Tensor.md +++ b/doc/JA/API/types/classes/Tensor.md @@ -3,13 +3,13 @@ 多次元配列を効率的に操作するためのクラス。多次元配列に対する積などの演算も定義する。 Matrix, Vectorなどはこの型を継承している。 -```erg +```python Tensor.arange(0..9) # Tensor [10] ``` * reshape(self, NewShape: [Nat; M]) -> Self NewShape -```erg +```python (1..9).into(Tensor).reshape [3, 3] ``` diff --git a/doc/JA/API/types/classes/TransCell(T).md b/doc/JA/API/types/classes/TransCell(T).md index e30d479e..d23cbde8 100644 --- a/doc/JA/API/types/classes/TransCell(T).md +++ b/doc/JA/API/types/classes/TransCell(T).md @@ -3,7 +3,7 @@ 中身を型ごと変えられるセルです。T型のサブタイプとなるので、T型としても振る舞います。 初期化時点ではT型で、ある時点以降はずっとU型、といった場合に便利です。 -```erg +```python a = TransCell!.new None a: TransCell! !NoneType a.set! 1 diff --git a/doc/JA/API/types/classes/Tuple.md b/doc/JA/API/types/classes/Tuple.md index 8ea4182c..891b9bae 100644 --- a/doc/JA/API/types/classes/Tuple.md +++ b/doc/JA/API/types/classes/Tuple.md @@ -8,7 +8,7 @@ 2つの順番付けられたコレクション(配列かタプル)を合成する。 - ```erg + ```python assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4) ``` @@ -17,7 +17,7 @@ zipを一般化したメソッド。合成するための二項演算を指定できる。 演算子には`()`, `[]`, `{}`, `{:}`も指定可能で、それぞれタプル, 配列, セット, ディクトを生成する。 - ```erg + ```python assert ([1, 2, 3].zip([4, 5, 6]))[0] == (1, 4) assert ([1, 2, 3].zip_by((), [4, 5, 6]))[0] == (1, 4) assert ([1, 2, 3].zip_by([], [4, 5, 6]))[0] == [1, 4] diff --git a/doc/JA/API/types/traits/Add(R,O).md b/doc/JA/API/types/traits/Add(R,O).md index 9b5290c1..003a0936 100644 --- a/doc/JA/API/types/traits/Add(R,O).md +++ b/doc/JA/API/types/traits/Add(R,O).md @@ -1,6 +1,6 @@ # Add R -```erg +```python Add R = Trait { .AddO = Type .`_+_` = (Self, R) -> Self.AddO @@ -10,13 +10,13 @@ Add R = Trait { `Add`は加算を定義する型である。加算としての`+`にはメソッドと関数の2種類がある。 二項関数としての`+`、すなわち`_+_`は、以下のように定義されている。 -```erg +```python `_+_`(l: Add(R, O), r: R): O = l.`_+_` r ``` わざわざこの定義があるのは、`+`をメソッドではなく関数として取り扱えるようにである。 -```erg +```python assert [1, 2, 3].fold(0, `_+_`) == 6 call op, x, y = op(x, y) @@ -25,7 +25,7 @@ assert call(`_+_`, 1, 2) == 3 加算はこのように型付けされる。 -```erg +```python f: |O: Type; A <: Add(Int, O)| A -> O f x = x + 1 diff --git a/doc/JA/API/types/traits/Div(R,O).md b/doc/JA/API/types/traits/Div(R,O).md index 3ba59edf..f6e940a3 100644 --- a/doc/JA/API/types/traits/Div(R,O).md +++ b/doc/JA/API/types/traits/Div(R,O).md @@ -2,7 +2,7 @@ ゼロ除算によるエラーがない場合は`SafeDiv`を使ってください。 -```erg +```python Div R, O = Trait { .`/` = Self.(R) -> O or Panic } diff --git a/doc/JA/API/types/traits/Num.md b/doc/JA/API/types/traits/Num.md index 5745c5ce..377da536 100644 --- a/doc/JA/API/types/traits/Num.md +++ b/doc/JA/API/types/traits/Num.md @@ -2,7 +2,7 @@ ## definition -```erg +```python Num R = Add(R) and Sub(R) and Mul(R) and Eq Num = Num Self ``` diff --git a/doc/JA/API/types/traits/SafeDiv(R,O).md b/doc/JA/API/types/traits/SafeDiv(R,O).md index 54c3a1b1..998faf89 100644 --- a/doc/JA/API/types/traits/SafeDiv(R,O).md +++ b/doc/JA/API/types/traits/SafeDiv(R,O).md @@ -1,6 +1,6 @@ # SafeDiv R, O -```erg +```python SafeDiv R, O = Subsume Div, { @Override .`/` = Self.(R) -> O diff --git a/doc/JA/API/types/traits/Sample.md b/doc/JA/API/types/traits/Sample.md index bd286d9d..cfb8a954 100644 --- a/doc/JA/API/types/traits/Sample.md +++ b/doc/JA/API/types/traits/Sample.md @@ -6,7 +6,7 @@ 主要な値クラスは全て`Sample`を実装する。また、`Sample`なクラスで構成されているタプル型やレコード型、Or型、篩型でも実装されている。 -```erg +```python assert Int.sample() == 42 assert Str.sample() == "example" # Intの場合、標準では64bitの範囲でサンプルされる @@ -16,7 +16,7 @@ print! {x = Int; y = Int}.sample!() # {x = -32432892, y = 78458576891} 以下は`Sample`の実装例である。 -```erg +```python EmailAddress = Class {header = Str; domain = Str}, Impl=Sample and Show @Impl Show EmailAddress. diff --git a/doc/JA/API/types/traits/Unpack.md b/doc/JA/API/types/traits/Unpack.md index b82282a8..0d259217 100644 --- a/doc/JA/API/types/traits/Unpack.md +++ b/doc/JA/API/types/traits/Unpack.md @@ -2,7 +2,7 @@ マーカートレイト。実装すると、レコードのようにパターンマッチで要素を分解できる。 -```erg +```python C = Class {i = Int}, Impl=Unpack C.new i = Self::new {i;} {i} = C.new(1) diff --git a/doc/JA/compiler/errors.md b/doc/JA/compiler/errors.md index 9bdbd8f2..8a583dca 100644 --- a/doc/JA/compiler/errors.md +++ b/doc/JA/compiler/errors.md @@ -24,7 +24,7 @@ 明らかに停止しない循環を起こしている場合に発生します。 -```erg +```python i: Int = i f(): Int = g() @@ -91,7 +91,7 @@ SyntaxErrorの派生です。 変数を定義前に使用すると発生します。 正確には、あるスコープ内で定義された変数がそれ以前に使われていると発生します。 -```erg +```python i = 0 f x = y = i + x @@ -102,7 +102,7 @@ f x = このコードでは`y = i + x`の`i`が未定義変数になります。 しかし、定数の場合は定義前に別の関数中で呼び出し可能です。 -```erg +```python f() = g() g() = f() ``` @@ -113,7 +113,7 @@ g() = f() 文法上は問題ありませんが、冗長だったり一般的でないコードを検出した際に発生します(不要な`()`など)。 -```erg +```python if (True): # SyntaxWarning: unnecessary parentheses ... ``` diff --git a/doc/JA/compiler/hir.md b/doc/JA/compiler/hir.md index 45748dce..20ca1bf2 100644 --- a/doc/JA/compiler/hir.md +++ b/doc/JA/compiler/hir.md @@ -5,7 +5,7 @@ HIRはErgコンパイラがASTから生成する構造体です。 ASTは(プレーンテキストとしての)ソースコードと一対一対応しますが、HIRは不要なコードの情報が除去されていたり、また省略された型情報が付記されたりしているため、HIRからソースコードを復元することは困難です。 以下のコードでHIRの例を見てみましょう。 -```erg +```python v = ![] for! 0..10, i => v.push! i @@ -14,7 +14,7 @@ log v.sum() このコードから生成されるASTは以下のようになります。 -```erg +```python AST(Module[ VarDef{ sig: VarSignature{ @@ -71,7 +71,7 @@ AST(Module[ そしてASTから生成されるHIRは以下のようになります。 -```erg +```python HIR(Module[ VarDef{ sig: VarSignature{ diff --git a/doc/JA/compiler/inference.md b/doc/JA/compiler/inference.md index 74b79282..3a6cb04e 100644 --- a/doc/JA/compiler/inference.md +++ b/doc/JA/compiler/inference.md @@ -4,7 +4,7 @@ 以下で用いる表記方法を示します。 -```erg +```python 自由型変数(型、未束縛): ?T, ?U, ... 自由型変数(値、未束縛): ?a, ?b, ... 型環境(Γ): { x: T, ... } @@ -14,7 +14,7 @@ 以下のコードを例にして説明します。 -```erg +```python v = ![] v.push! 1 print! v @@ -100,7 +100,7 @@ pub enum Type { さて、得られた型スキーム(e.g. `'T -> 'T (idの型スキーム)`)を使用箇所(e.g. `id 1`, `id True`)の型推論で使う際は、一般化を解除する必要があります。この逆変換を __具体化(instantiation)__ と呼びます。操作は`inst`と呼ぶことにします。 -```erg +```python gen ?T = 'T inst 'T = ?T (?T ∉ Γ) ``` @@ -114,7 +114,7 @@ inst 'T = ?T (?T ∉ Γ) 型代入規則`{?T --> X}`は、`?T`と`X`を同一の型とみなすよう書き換えるという意味です。この操作を __単一化(Unification)__ といいます。`X`は型変数もありえます。 単一化の詳しいアルゴリズムは[別の項](./unification.md)で解説します。単一化操作は`unify`と表すことにします。 -```erg +```python unify(?T, Int) == Ok(()) # ?T == (Int) # Sは型代入規則、Tは適用する型 @@ -132,7 +132,7 @@ subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y というのも、実引数の型は、仮引数の型のサブタイプでなければなりません。 引数の型が型変数の場合は、それを満たすように部分型関係を更新する必要があるのです。 -```erg +```python # 仮引数の型をTとすると f(x: T): T = ... @@ -147,7 +147,7 @@ f(a) レベル管理の必要性をみるために、まずはレベル管理を導入しない型推論では問題が起こることを確認します。 以下の無名関数の型を推論してみます。 -```erg +```python x -> y = x y @@ -156,7 +156,7 @@ x -> まず、Ergは以下のように型変数を割り当てます。 yの型も未知ですが、現段階では割り当てないでおきます。 -```erg +```python x(: ?T) -> y = x y @@ -165,7 +165,7 @@ x(: ?T) -> まず決定すべきは右辺値xの型です。右辺値は「使用」なので、具体化します。 しかしxの型`?T`は自由変数なのですでに具体化されています。よってそのまま`?T`が右辺値の型になります。 -```erg +```python x(: ?T) -> y = x (: inst ?T) y @@ -173,13 +173,13 @@ x(: ?T) -> 左辺値yの型として登録する際に、一般化します。が、後で判明するようにこの一般化は不完全であり、結果に誤りが生じます。 -```erg +```python x(: ?T) -> y(: gen ?T) = x (: ?T) y ``` -```erg +```python x(: ?T) -> y(: 'T) = x y @@ -187,7 +187,7 @@ x(: ?T) -> yの型は量化型変数`'T`となりました。次の行で、`y`が早速使用されています。具体化します。 -```erg +```python x: ?T -> y(: 'T) = x y(: inst 'T) @@ -195,7 +195,7 @@ x: ?T -> ここで注意してほしいのが、具体化の際にはすでに存在するどの(自由)型変数とも別の(自由)型変数を生成しなくてはならないという点です(一般化も同様です)。このような型変数をフレッシュ(新鮮)な型変数と呼びます。 -```erg +```python x: ?T -> y = x y(: ?U) @@ -207,7 +207,7 @@ x: ?T -> そこで、型変数のレベルを以下の表記で導入します。レベルは自然数で表します。 -```erg +```python # 通常のType型変数 ?T<1>, ?T<2>, ... # 部分型制約を付けられた型変数 @@ -216,7 +216,7 @@ x: ?T -> では、リトライしてみます。 -```erg +```python x -> y = x y @@ -225,7 +225,7 @@ x -> まず、以下のようにレベル付き型変数を割り当てます。トップレベルのレベルは1です。スコープが深くなるたび、レベルが増えます。 関数の引数は内側のスコープに属するため、関数自身より1大きいレベルにいます。 -```erg +```python # level 1 x (: ?T<2>) -> # level 2 @@ -235,7 +235,7 @@ x (: ?T<2>) -> 先に右辺値`x`を具体化します。先ほどと同じで、何も変わりません。 -```erg +```python x (: ?T<2>) -> y = x (: inst ?T<2>) y @@ -245,11 +245,11 @@ x (: ?T<2>) -> さきほどはここで結果がおかしくなっていましたので、一般化のアルゴリズムを変更します。 もし型変数のレベルが現在のスコープのレベル以下なら、一般化しても変化がないようにします。 -```erg +```python gen ?T = if n <= current_level, then= ?T, else= 'T ``` -```erg +```python x (: ?T<2>) -> # current_level = 2 y (: gen ?T<2>) = x (: ?T<2>) @@ -258,7 +258,7 @@ x (: ?T<2>) -> つまり、左辺値`y`の型は`?T<2>`です。 -```erg +```python x (: ?T<2>) -> # ↓ not generalized y (: ?T<2>) = x @@ -267,13 +267,13 @@ x (: ?T<2>) -> yの型は未束縛型変数`?T<2>`となりました。次の行で具体化します。が、`y`の型は一般化されていないので、何も起こりません。 -```erg +```python x (: ?T<2>) -> y (: ?T<2>) = x y (: inst ?T<2>) ``` -```erg +```python x (: ?T<2>) -> y = x y (: ?T<2>) @@ -283,7 +283,7 @@ x (: ?T<2>) -> もう1つの例を見ます。こちらは更に一般的なケースで、関数・演算子適用、前方参照がある場合です。 -```erg +```python f x, y = id(x) + y id x = x @@ -296,7 +296,7 @@ f 10, 1 このような場合、`f`の前に`id`の宣言を仮想的に挿入し、自由型変数を割り当てておきます。 このときの型変数のレベルは`current_level`であることに注意してください。これは、他の関数内で一般化されないようにするためです。 -```erg +```python id: ?T<1> -> ?U<1> f x (: ?V<2>), y (: ?W<2>) = id(x) (: subst_call_ret([inst ?V<2>], inst ?T<1> -> ?U<1>)) + y @@ -308,7 +308,7 @@ f x (: ?V<2>), y (: ?W<2>) = 型変数同士の半単一化では、少し事情が違います。 違うレベルの型変数の場合、相互に型制約をかけてはいけません。 -```erg +```python # BAD f x (: ?V<2>), y (: ?W<2>) = # ?V<2>(<: ?T<1>) @@ -320,24 +320,24 @@ f x (: ?V<2>), y (: ?W<2>) = Type型変数同士の場合、半単一化ではなく、通常の単一化を行います。 つまり、レベルの低い方に単一化させます。 -```erg +```python # OK f x (: ?V<2>), y (: ?W<2>) = # ?V<2> --> ?T<1> id(x) (: ?U<1>) + y (: ?W<2>) ``` -```erg +```python f x (: ?T<1>), y (: ?W<2>) = (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], inst |'L <: Add('R)| ('L, 'R) -> 'L.AddO) ``` -```erg +```python f x (: ?T<1>), y (: ?W<2>) = (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], (?L(<: Add(?R<2>))<2>, ?R<2>) -> ?L<2>.AddO) ``` -```erg +```python id: ?T<1> -> ?U<1> f x (: ?T<1>), y (: ?W<2>) = # ?U<1>(<: Add(?W<2>)) # ?Lの制約を引き継ぐ @@ -346,26 +346,26 @@ f x (: ?T<1>), y (: ?W<2>) = (id(x) + x) (: ?U<1>.AddO) ``` -```erg +```python # current_level = 1 f(x, y) (: gen ?T<1>, gen ?W<2> -> gen ?U<1>.AddO) = id(x) + x ``` -```erg +```python id: ?T<1> -> ?U<1> f(x, y) (: |'W: Type| (?T<1>, 'W) -> gen ?U<1>(<: Add(?W<2>)).AddO) = id(x) + x ``` -```erg +```python f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) = id(x) + x ``` 定義の際には一般化できるようにレベルを上げます。 -```erg +```python # ?T<1 -> 2> # ?U<1 -> 2> id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>) @@ -373,7 +373,7 @@ id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>) 戻り値型が既に割り当てられている場合は、得られた型と単一化します(`?U<2> --> ?T<2>`)。 -```erg +```python # ?U<2> --> ?T<2> f(x, y) (: |'W: Type| (?T<2>, 'W) -> ?T<2>(<: Add(?W<2>)).AddO) = id(x) + x @@ -385,13 +385,13 @@ id(x) (: gen ?T<2> -> gen ?T<2>) = x (: ?T<2>) それに依存する型変数も同じくType型変数になります。 一般化された型変数は各関数で独立です。 -```erg +```python f(x, y) (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = id(x) + x id(x) (: |'T: Type| 'T -> gen 'T) = x ``` -```erg +```python f x, y (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = id(x) + y id(x) (: 'T -> 'T) = x @@ -399,13 +399,13 @@ id(x) (: 'T -> 'T) = x f(10, 1) (: subst_call_ret([inst {10}, inst {1}], inst |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) ``` -```erg +```python f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<1>) -> ?T<1>.AddO)) ``` 型変数は、実装のある最小の型まで上限が拡大されます。 -```erg +```python # ?T(:> {10} <: Add(?W<1>))<1> # ?W(:> {1})<1> # ?W(:> {1})<1> <: ?T<1> (:> {10}, <: Add(?W(:> {1})<1>)) @@ -421,7 +421,7 @@ f(10, 1) (: ({10}, {1}) -> Nat) 結果として、プログラム全体の型はこうなります。 -```erg +```python f|W: Type, T <: Add(W)|(x: T, y: W): T.AddO = id(x) + y id|T: Type|(x: T): T = x @@ -430,7 +430,7 @@ f(10, 1): Nat 元の明示的に型付けられていないプログラムも再掲しておきます。 -```erg +```python f x, y = id(x) + y id x = x diff --git a/doc/JA/compiler/parsing.md b/doc/JA/compiler/parsing.md index aa6ed05c..815b6624 100644 --- a/doc/JA/compiler/parsing.md +++ b/doc/JA/compiler/parsing.md @@ -5,7 +5,7 @@ Ergの文法において特異なのは、space-sensitive(空白による区別がある)である点である。 これは、`()`の省略による表現力の低下を補うためである。同様の文法は同じく`()`を省略可能なNimでも見られる。 -```erg +```python f +1 == f(+1) f + 1 == `+`(f, 1) f (1,) == f((1,)) @@ -20,7 +20,7 @@ Ergにおいて左辺値とは`=`の左側といった単純なものではな 実際、(非常に紛らわしいが)`=`の左側にも右辺値は存在するし、`=`の右側にも左辺値が存在する。 右辺値の中に左辺値が存在することさえある。 -```erg +```python # iは左辺値、Array(Int)と[1, 2, 3]は右辺値 i: Array(Int) = [1, 2, 3] # `[1, 2, 3].iter().map i -> i + 1`は右辺値だが、->の左側のiは左辺値 diff --git a/doc/JA/compiler/refinement_subtyping.md b/doc/JA/compiler/refinement_subtyping.md index a66ca5da..82cd8341 100644 --- a/doc/JA/compiler/refinement_subtyping.md +++ b/doc/JA/compiler/refinement_subtyping.md @@ -2,7 +2,7 @@ 篩型とは、以下のような型である。 -```erg +```python {I: Int | I >= 0} {S: StrWithLen N | N >= 1} {T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0} diff --git a/doc/JA/compiler/trait_method_resolving.md b/doc/JA/compiler/trait_method_resolving.md index b7f8cf25..723aeb64 100644 --- a/doc/JA/compiler/trait_method_resolving.md +++ b/doc/JA/compiler/trait_method_resolving.md @@ -3,7 +3,7 @@ `Nat`は0以上の`Int`、つまり`Int`のサブタイプである。 本来`Nat`はPythonのクラス階層には存在しない。Ergはこのパッチのメソッドをどうやって解決するのだろうか? -```erg +```python 1.times do: log "hello, world" ``` @@ -27,7 +27,7 @@ Ergは`Int`のMROに`Int`, `Object`を持っている。これはPython由来で Ergコンパイラは、全ての提供メソッドとその実装を持つパッチ・型のハッシュマップを持っている。 このテーブルは型が新たに定義されるたびに更新される。 -```erg +```python provided_method_table = { ... "foo": [Foo], @@ -58,7 +58,7 @@ provided_method_table = { 両者に包含関係がない場合は、コンパイルエラーとなる(これはプログラマーの意図に反したメソッドが実行されないための安全策である)。 エラーを解消させるためには、パッチを明示的に指定する必要がある。 -```erg +```python o.method(x) -> P.method(o, x) ``` @@ -66,20 +66,20 @@ o.method(x) -> P.method(o, x) 以下のようなパッチを定義する。 -```erg +```python FnType T: Type = Patch T -> T FnType.type = T ``` `FnType`パッチのもとで以下のようなコードが可能である。これはどのように解決されるのだろうか。 -```erg +```python assert (Int -> Int).type == Int ``` まず、`provided_method_table`には`FnType(T)`が以下の形式で登録される。 -```erg +```python provided_method_table = { ... "type": [FnType(T)], @@ -90,6 +90,6 @@ provided_method_table = { `FnType(T)`のパッチする型が適合するかチェックされる。この場合、`FnType(T)`のパッチ型は`Type -> Type`である。 これは`Int -> Int`に適合する。適合したら、単相化を行って置換する(`T -> T`と`Int -> Int`のdiffを取る。`{T => Int}`)。 -```erg +```python assert FnType(Int).type == Int ``` diff --git a/doc/JA/compiler/transpile.md b/doc/JA/compiler/transpile.md index 90e41482..aab468fa 100644 --- a/doc/JA/compiler/transpile.md +++ b/doc/JA/compiler/transpile.md @@ -11,7 +11,7 @@ namedtupleにトランスパイルされます。 namedtupleについては、[こちら](https://docs.python.jp/3/library/collections.html#collections.namedtuple)を参照してください。 似たような機能にdataclassがありますが、dataclassは`__eq__`や`__hash__`が自動実装されるなどの影響で少しパフォーマンスが落ちます。 -```erg +```python Employee = Class {.name = Str; .id = Int} employee = Employee.new({.name = "John Smith"; .id = 100}) @@ -43,7 +43,7 @@ assert employee.name == 'John Smith' 名前空間内での衝突が起きない場合は、単にマングリングして展開されます。 `x::y`などの名前はバイトコードで使用されるものでPythonコードと対応させる事はできませんが、無理やり表現すると以下のようになります。 -```erg +```python x = y = 1 y + 1 @@ -56,7 +56,7 @@ x = x::y + 1 衝突する場合は、内部的にしか参照できない関数を定義して使用します。 -```erg +```python x = y = 1 y + 1 @@ -75,7 +75,7 @@ x = _() 公開変数に関してはPythonのデフォルトなので何もしません。 非公開変数はマングリングで対処しています。 -```erg +```python x = 1 y = x = 2 diff --git a/doc/JA/dev_guide/faq_syntax.md b/doc/JA/dev_guide/faq_syntax.md index 7972ae30..8dea551e 100644 --- a/doc/JA/dev_guide/faq_syntax.md +++ b/doc/JA/dev_guide/faq_syntax.md @@ -11,7 +11,7 @@ Ergが所有権システムを導入した狙いは「可変状態の局所化 `<>`や`[]`では文法の衝突が起きるからです。 -```erg +```python # []版 id[T: Type] [t]: [T] = t y = id[Int] # これは関数? @@ -30,7 +30,7 @@ y = id|Int| # OK Ergは型自体も値として扱える設計になっているためです。 -```erg +```python A = [Int; 3] assert A[2] == Int T = (Int, Str) @@ -53,7 +53,7 @@ assert S.i == Int Ergでは`?`演算子によってエラーをあまり意識せずに書けます。 -```erg +```python read_file!() = f = open!("foo.txt")? # 失敗したらエラーをすぐさま返すので、fはFile型 f.read_all!() @@ -84,7 +84,7 @@ Pythonのライブラリには継承されることを前提に設計されて デフォルトで構造的トレイトを指すと、型指定が複雑になり、プログラマの意図しない挙動を混入させる恐れがあるためです。 -```erg +```python # If T is a subtype of a structural trait... # f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T f|T| x, y: T = x + y - x diff --git a/doc/JA/dev_guide/terms.md b/doc/JA/dev_guide/terms.md index fa079ffb..7d5677f6 100644 --- a/doc/JA/dev_guide/terms.md +++ b/doc/JA/dev_guide/terms.md @@ -237,7 +237,7 @@ コード中である条件が成立しているか(典型的には実行時に)調べること。`assert`関数などを使用して行う。 -```erg +```python sum = !0 for! 0..10, i => sum.add! i @@ -282,7 +282,7 @@ Ergにおいては、基本オブジェクトと同等。コンパイル時に ### [インスタントブロック](../syntax/00_basic.md#式セパレータ) -```erg +```python x = y = f(a) z = g(b, c) @@ -644,7 +644,7 @@ APIとして利用可能な属性。特に、トレイトによって自動実 ### [デコレータ](../syntax/29_decorator.md) -```erg +```python @deco f x = ... ``` diff --git a/doc/JA/dev_guide/unify_terms.md b/doc/JA/dev_guide/unify_terms.md index fde909fa..e6e71220 100644 --- a/doc/JA/dev_guide/unify_terms.md +++ b/doc/JA/dev_guide/unify_terms.md @@ -51,7 +51,7 @@ Visibility(可視性)を使用する。 * 名前(Name): 識別子とほぼ同じ意味。Ergにおいては代数と同じ意味で使われることもある。 * 代数名(Algebra name): Ergにおいては識別子と同等の意味。C言語では関数名は識別子だが代数名ではない。「代数」は`=`(変数代入演算子)または`=`(定数代入演算子)でオブジェクトを代入できるという言語機能自体を指す。 -```erg +```python 代数名 <: (名前 == 識別子) <: シンボル 変数 + 定数 == 代数 ``` diff --git a/doc/JA/migration_from_py.md b/doc/JA/migration_from_py.md index 4ad1c57b..4f1daf8c 100644 --- a/doc/JA/migration_from_py.md +++ b/doc/JA/migration_from_py.md @@ -9,7 +9,7 @@ s: str i: int = int(s) ``` -```erg +```python s: Str res: Result(Int, IntParseError) = s.parse Int i: Int = res.unwrap() @@ -18,7 +18,7 @@ f: Result(Float, FloatParseError) = s.parse Float `try_from`メソッドも使えます。 -```erg +```python s: Str i: Int = Int.try_from(s).unwrap() f: Float = Float.try_from(s).unwrap() diff --git a/doc/JA/python/class_system.md b/doc/JA/python/class_system.md index dfaf5620..8bed4851 100644 --- a/doc/JA/python/class_system.md +++ b/doc/JA/python/class_system.md @@ -51,7 +51,7 @@ TypeError: can only concatenate str (not "int") to str Ergでは親クラスとの整合性が静的に検査される。 オーバーライド時には`Override`デコレータを付与する必要があり、オーバーライドする関数の型はされる関数の型の部分型とならなくてはならない。 -```erg +```python >>> C = Class() ... .f self = 1 ... .g self = self.f() + 1 @@ -81,7 +81,7 @@ f(c) f(1) # TypeError ``` -```erg +```python # f: |T, X <: {.m = Self.() -> T}| X -> T f(x) = x.m() diff --git a/doc/JA/syntax/00_basic.md b/doc/JA/syntax/00_basic.md index 09c298a6..d2cb5332 100644 --- a/doc/JA/syntax/00_basic.md +++ b/doc/JA/syntax/00_basic.md @@ -9,7 +9,7 @@ まずは恒例の、Hello Worldを行いましょう。 -```erg +```python print!("Hello, World!") ``` @@ -17,7 +17,7 @@ Pythonや同系統の言語とほぼ同じです。目を引くのは`print`の また、Ergでは解釈に紛れのない限り括弧`()`を省略することが出来ます。 括弧の省略ができるのはRubyと似ていますが、複数の解釈ができる括弧省略はできませんし、また引数が0個のときもPythonと同じく`()`の省略が出来ません。 -```erg +```python print! "Hello, World!" # OK print! "Hello,", "World!" # OK print!() # OK @@ -40,7 +40,7 @@ Ergのコードはスクリプトと呼ばれます。スクリプトはファ `#`以降はコメントとして無視されます。コードの意図を説明したいときや一時的にコードを無効化したいときなどに使います。 -```erg +```python # コメント ## `#`以降は改行されるまで無視されるので、`#`は何個あってもOK #[ @@ -55,7 +55,7 @@ Ergのコードはスクリプトと呼ばれます。スクリプトはファ 各式はセパレータ―改行かセミコロン`;`―で区切ります。 Ergのスクリプトは基本的に左から右へ、上から下へ評価されます。 -```erg +```python n = 1 # 代入式 f(1, 2) # 関数適用式 1 + 1 # 演算子適用式 @@ -65,7 +65,7 @@ f(1, 2); 1 + 1 以下のように、ブロック内で最後に評価した式を変数の値とするインスタントブロックという機能があります。 これは引数なし関数とは違い、`()`をつけません。ブロックがその場で1度だけ評価されることに注意してください。 -```erg +```python i = x = 1 x + 1 @@ -74,7 +74,7 @@ assert i == 2 これはセミコロン(`;`)では実現できません。 -```erg +```python i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses ``` @@ -82,7 +82,7 @@ i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses ErgはPythonと同じくインデントを使ってブロックを表します。ブロックの開始を示すトリガーとなる演算子(特殊形式)は、`=`, `->`, `=>`, `do`, `do!`の5種類です(その他に、演算子ではありませんが`:`と`|`もインデントを生成します)。それぞれの意味は後述します。 -```erg +```python f x, y = x + y @@ -101,7 +101,7 @@ ans = match x: また1行が長くなりすぎる場合、`\`を使って途中で改行させることができます。 -```erg +```python # this does not means `x + y + z` but means `x; +y; +z` x + y diff --git a/doc/JA/syntax/01_literal.md b/doc/JA/syntax/01_literal.md index 456b3ff3..6db8d8a5 100644 --- a/doc/JA/syntax/01_literal.md +++ b/doc/JA/syntax/01_literal.md @@ -4,19 +4,19 @@ ### 整数リテラル(Int Literal) -```erg +```python 0, -0, 1, -1, 2, -2, 3, -3, ... ``` ### 有理数リテラル(Ratio Literal) -```erg +```python 0.00, -0.0, 0.1, 400.104, ... ``` `Ratio`リテラルで整数部分または小数部分が`0`のときは、その`0`を省略できます。 -```erg +```python assert 1.0 == 1. assert 0.5 == .5 ``` @@ -29,14 +29,14 @@ assert 0.5 == .5 Unicodeで表現可能な文字列は、すべて使用できます。 Pythonとは違い、`'`ではクオーテーション(囲み)できません。文字列の中で`"`を使いたいときは`\"`としてください。 -```erg +```python "", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "السَّلَامُ عَلَيْكُمْ", ... ``` `{}`によって文字列の中に式を埋めこめます。これを文字列補間(string interpolation)といいます。 `{`, `}`自体を出力したい場合は`\{`, `\}`とします。 -```erg +```python assert "1 + 1 is 2" == "{1} + {1} is {1+1}" s = "1+1" assert "\{1+1}\" == "\{{s}\}" @@ -47,11 +47,11 @@ assert "\{1+1}\" == "\{{s}\}" これは学術計算でよく使用される指数表記を表すリテラルです。`Ratio`型のインスタンスになります。 非常に大きな/小さな数を表すときに使用します。Pythonと表記法は同じです。 -```erg +```python 1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ... ``` -```erg +```python assert 1e-10 == 0.0000000001 ``` @@ -61,37 +61,37 @@ assert 1e-10 == 0.0000000001 ### [配列リテラル(Array Literal)](./10_array.md) -```erg +```python [], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ... ``` ### [辞書リテラル(Dict Literal)](./11_dict.md) -```erg +```python {:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ... ``` ### [組リテラル(Tuple Literal)](./12_tuple.md) -```erg +```python (), (1, 2, 3), (1, "hello", True), ... ``` ### [レコードリテラル(Record Literal)](./13_record.md) -```erg +```python {=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ... ``` ### [集合リテラル(Set Literal)](./14_set.md) -```erg +```python {}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ... ``` `Array`リテラルとの違いとして、`Set`では重複する要素が取り除かれます。 -```erg +```python assert {1, 2, 1} == {1, 2} ``` @@ -99,19 +99,19 @@ assert {1, 2, 1} == {1, 2} ## 真偽値オブジェクト(Boolean Object) -```erg +```python True, False ``` ### Noneオブジェクト -```erg +```python None ``` ## 範囲オブジェクト(Range Object) -```erg +```python assert 0..5 == {1, 2, 3, 4, 5} assert 0..10 in 5 assert 0..<10 notin 10 @@ -120,7 +120,7 @@ assert 0..9 == 0..<10 ## 浮動小数点数オブジェクト(Float Object) -```erg +```python assert 0.0f64 == 0 assert 0.0f32 == 0.0f64 ``` @@ -129,7 +129,7 @@ assert 0.0f32 == 0.0f64 ## 複素数オブジェクト(Complex Object) -```erg +```python 1+2im, 0.4-1.2im, 0im, im ``` @@ -140,7 +140,7 @@ assert 0.0f32 == 0.0f64 Ergでは、解釈に紛れがない限り乗算を表す`*`を省略できます。 ただし、演算子の結合強度は`*`よりも強く設定されています。 -```erg +```python # same as `assert (1*m) / (1*s) == 1*(m/s)` assert 1m / 1s == 1 (m/s) ``` diff --git a/doc/JA/syntax/02_name.md b/doc/JA/syntax/02_name.md index bd18402f..7bb732d9 100644 --- a/doc/JA/syntax/02_name.md +++ b/doc/JA/syntax/02_name.md @@ -5,7 +5,7 @@ 変数は以下のように定義します。 `n`の部分を変数名(または、識別子)、`=`を代入演算子、`1`の部分を代入値と呼びます。 -```erg +```python n = 1 ``` @@ -15,13 +15,13 @@ n = 1 変数の「型」を指定したい場合は以下のようにします。型とは、これも後述しますが、大まかにはオブジェクトの属する集合です。 ここでは`n`は自然数(`Nat`)型であると指定しています。 -```erg +```python n: Nat = 1 ``` 他の言語とは違い、多重代入はできないので注意してください。 -```erg +```python # NG l1 = l2 = [1, 2, 3] # SyntaxError: 多重代入はできません # OK @@ -31,7 +31,7 @@ l2 = l1.clone() また、変数への再代入もできません。その代わりに使える機能、すなわち可変な状態を保持する機能については後述します。 -```erg +```python i = 1 i = i + 1 # AssignError: cannot assign twice ``` @@ -40,7 +40,7 @@ i = i + 1 # AssignError: cannot assign twice これはPythonの「文」のスコープとは違う挙動なので注意してください。 このような機能は一般にシャドーイングと言います。ただし他言語のシャドーイングとは違い同一スコープではシャドーイングできません。 -```erg +```python x = 0 # x = 1 # AssignError: cannot assign twice if x.is_zero(), do: @@ -51,7 +51,7 @@ assert x == 0 以下は一見すると可能なように思えますが、やはりできません。これは技術的な制約ではなく、設計判断です。 -```erg +```python x = 0 if x.is_zero(), do: x = x + 1 # NameError: cannot define variables refer to variables with the same name @@ -64,7 +64,7 @@ assert x == 0 定数も代数の一種です。識別子を大文字で始めると定数として扱われます。一度定義したら変わらないので、定数と呼ばれます。 `N`の部分を定数名(または、識別子)と呼びます。その他は変数と同じです。 -```erg +```python N = 0 if True, do: N = 1 # AssignError: constants cannot be shadowed @@ -77,13 +77,13 @@ if True, do: 定数は、数学的定数、外部リソースに関する情報など不変な値に対して使用すると良いでしょう。 [型](./type/01_type_system.md)以外のオブジェクトは、オールキャップス(全ての文字を大文字にするスタイル)にするのが一般的です。 -```erg +```python PI = 3.141592653589793 URL = "https://example.com" CHOICES = ["a", "b", "c"] ``` -```erg +```python PI = 3.141592653589793 match! x: PI => print! "π" @@ -95,7 +95,7 @@ match! x: 定数には代入できないものがあります。可変オブジェクトなどです。詳しくは後述しますが、可変オブジェクトは内容を変更することができるオブジェクトです。 これは定数には定数式のみを代入できるという規則があるためです。定数式についても後述することとします。 -```erg +```python X = 1 # OK X = !1 # TypeError: cannot define Int! object as a constant ``` @@ -104,7 +104,7 @@ X = !1 # TypeError: cannot define Int! object as a constant `Del`関数を使うことで、代数を削除することが出来ます。その代数に依存している(その代数の値を直接参照している)他の代数もまとめて削除されます。 -```erg +```python x = 1 y = 2 Z = 3 @@ -119,7 +119,7 @@ f(2) # NameError: f is not defined (deleted in line 6) ただし、`Del`によって削除できるのはモジュール内で定義された代数のみです。`True`などの組み込み定数は削除できません。 -```erg +```python Del True # TypeError: cannot delete built-in constants Del print! # TypeError: cannot delete built-in variables ``` @@ -128,7 +128,7 @@ Del print! # TypeError: cannot delete built-in variables 注意として、`x = a`であるとき、`x == a`とは限らない。例としては`Float.NaN`がある。これはIEEE 754により定められた正式な浮動小数点数の仕様である。 -```erg +```python x = Float.NaN assert x != Float.NaN assert x != x @@ -136,7 +136,7 @@ assert x != x その他、そもそも同値関係が定義されていないオブジェクトも存在する。 -```erg +```python f = x -> x**2 + 2x + 1 g = x -> (x + 1)**2 f == g # TypeError: cannot compare function objects @@ -150,7 +150,7 @@ C == D # TypeError: cannot compare class objects 関数オブジェクトやクラスオブジェクトの場合、オブジェクトに変数名の情報を与えるなどの「修飾」を行う。 ただし構造型の場合はその限りではない。 -```erg +```python f x = x print! f # g x = x + 1 diff --git a/doc/JA/syntax/03_declaration.md b/doc/JA/syntax/03_declaration.md index a0077a81..2278a3dc 100644 --- a/doc/JA/syntax/03_declaration.md +++ b/doc/JA/syntax/03_declaration.md @@ -4,7 +4,7 @@ 宣言はコード中のどこでも可能ですが、宣言しただけでその変数を参照することはできません。必ず初期化する必要があります。 代入後の宣言では、代入されたオブジェクトと型が適合するかをチェック可能です。 -```erg +```python i: Int # i: Int = 2のように代入と同時に宣言可能 i = 2 @@ -18,7 +18,7 @@ i: {2} 実行時の`assert`による型チェックは「〇〇型かもしれない」で検査が可能ですが、コンパイル時の`:`による型チェックは厳密です。 「〇〇型である」ことが確定していなくては検査を通らず、エラーとなります。 -```erg +```python i = (-1..10).sample!() assert i in Nat # これは通るかもしれない i: Int # これは通る @@ -27,14 +27,14 @@ i: Nat # これは通らない(-1はNatの要素ではないから) 関数は以下の2種類の方法で宣言が可能です。 -```erg +```python f: (x: Int, y: Int) -> Int f: (Int, Int) -> Int ``` 引数名を明示して宣言した場合、定義時に名前が違うと型エラーとなります。引数名の任意性を与えたい場合は2番目の方法で宣言すると良いでしょう。その場合、型検査で見られるのはメソッド名とその型のみです。 -```erg +```python T = Trait { .f = (x: Int, y: Int): Int } diff --git a/doc/JA/syntax/04_function.md b/doc/JA/syntax/04_function.md index abad4e52..e0262688 100644 --- a/doc/JA/syntax/04_function.md +++ b/doc/JA/syntax/04_function.md @@ -2,7 +2,7 @@ 関数は「引数」を受け取ってそれを加工し、「戻り値」として返すブロックです。以下のように定義します。 -```erg +```python add x, y = x + y # or add(x, y) = x + y @@ -13,7 +13,7 @@ add(x, y) = x + y `add`は`x`と`y`を仮引数として受け取り、それを足したもの、`x + y`を返す関数です。 定義した関数は、以下のようにして呼び出し(適用)ができます。 -```erg +```python add 1, 2 # or add(1, 2) @@ -23,16 +23,16 @@ add(1, 2) 関数は`f x, y, ...`のように呼び出しますが、実引数が多く一行では長くなりすぎる場合は`:`(コロン)を使った適用も可能です。 -```erg +```python f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4 ``` -```erg +```python f some_long_name_variable_1 + some_long_name_variable_2: some_long_name_variable_3 * some_long_name_variable_4 ``` -```erg +```python f: some_long_name_variable_1 + some_long_name_variable_2 some_long_name_variable_3 * some_long_name_variable_4 @@ -40,7 +40,7 @@ f: 上の3つのコードはすべて同じ意味です。このスタイルは`if`関数などを使用するときにも便利です。 -```erg +```python result = if Bool.sample!(): do: log "True was chosen" @@ -57,7 +57,7 @@ result = if Bool.sample!(): 引数の数が多い関数を定義されていると、引数を渡す順番を間違える危険性があります。 そのような場合はキーワード引数を使用して呼び出すと安全です。 -```erg +```python f x, y, z, w, v, u: Int = ... ``` @@ -65,13 +65,13 @@ f x, y, z, w, v, u: Int = ... このような関数は作るべきではありませんが、他人の書いたコードを使うときにこのようなコードにあたってしまうかもしれません。 そこで、キーワード引数を使います。キーワード引数は並びよりも名前が優先されるため、順番を間違えていても名前から正しい引数に値が渡されます。 -```erg +```python f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3 ``` キーワード引数と`:`の後にすぐ改行してしまうとコロン適用スタイルとみなされるので注意してください。 -```erg +```python # means `f(x: y)` f x: y @@ -86,7 +86,7 @@ f x: デフォルト引数は`:=`(or-assign operator)で指定します。`base`が指定されなかったら`math.E`を`base`に代入します。 -```erg +```python math_log x: Ratio, base := math.E = ... assert math_log(100, 10) == 2 @@ -95,7 +95,7 @@ assert math_log(100) == math_log(100, math.E) 引数を指定しないことと`None`を代入することは区別されるので注意してください。 -```erg +```python p! x := 0 = print! x p!(2) # 2 p!() # 0 @@ -104,20 +104,20 @@ p!(None) # None 型指定、パターンと併用することもできます。 -```erg +```python math_log x, base: Ratio := math.E = ... f [x, y] := [1, 2] = ... ``` しかしデフォルト引数内では、後述するプロシージャを呼び出したり、可変オブジェクトを代入したりすることができません。 -```erg +```python f x := p! 1 = ... # NG ``` また、定義したばかりの引数はデフォルト引数に渡す値として使えません。 -```erg +```python f x := 1, y := x = ... # NG ``` @@ -125,13 +125,13 @@ f x := 1, y := x = ... # NG 引数をログ(記録)として出力する`log`関数は、任意の個数の引数を受け取ることができます。 -```erg +```python log "Hello", "World", "!" # Hello World ! ``` このような関数を定義したいときは、引数に`...`を付けます。このようにすると、引数を可変長の配列として受け取ることができます。 -```erg +```python f x: ...Int = for x, i -> log i @@ -142,7 +142,7 @@ f 1, 2, 3, 4, 5 ## 複数パターンによる関数定義 -```erg +```python fib n: Nat = match n: 0 -> 0 @@ -152,7 +152,7 @@ fib n: Nat = 上のような定義直下に`match`が現れる関数は、下のように書き直すことができます。 -```erg +```python fib 0 = 0 fib 1 = 1 fib(n: Nat): Nat = fib(n - 1) + fib(n - 2) @@ -162,7 +162,7 @@ fib(n: Nat): Nat = fib(n - 1) + fib(n - 2) 違うクラスのインスタンスが混在する場合は、最後の定義で関数引数がOr型であることを明示しなくてはなりません。 -```erg +```python f "aa" = ... f 1 = ... # `f x = ...` is invalid @@ -171,7 +171,7 @@ f x: Int or Str = ... また、`match`と同じく網羅性がなくてはなりません。 -```erg +```python fib 0 = 0 fib 1 = 1 # PatternError: pattern of fib's parameter is not exhaustive @@ -179,7 +179,7 @@ fib 1 = 1 しかし、上のような場合でも、後述する[篩型](./type/12_refinement.md)を使って明示的に型指定することで、網羅性を獲得できます。 -```erg +```python fib: 0..1 -> 0..1 fib 0 = 0 fib 1 = 1 @@ -193,7 +193,7 @@ fib 1 = 1 簡単な例として階乗の計算を行う関数`factorial`を定義してみます。階乗とは、「それ以下の正の数をすべてかける」計算です。 5の階乗は`5*4*3*2*1 == 120`となります。 -```erg +```python factorial 0 = 1 factorial 1 = 1 factorial(n: Nat): Nat = n * factorial(n - 1) @@ -207,7 +207,7 @@ factorial(n: Nat): Nat = n * factorial(n - 1) 注意として、型指定を付けなかった場合はこのように推論されます。 -```erg +```python factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int factorial 0 = 1 factorial 1 = 1 @@ -216,7 +216,7 @@ factorial n = n * factorial(n - 1) しかし例え推論が出来たとしても、再帰関数には型を明示的に指定しておくべきです。上の例では、`factorial(-1)`のようなコードは有効ですが、 -```erg +```python factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ... ``` @@ -229,7 +229,7 @@ factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ... コンパイル関数ができることは限られています。コンパイル時関数内で使えるのは定数式のみ、すなわち、いくつかの演算子(四則演算や比較演算、型構築演算など)とコンパイル時関数のみです。代入する引数も定数式である必要があります。 そのかわり、計算をコンパイル時に行うことができるというメリットがあります。 -```erg +```python Add(X, Y: Nat): Nat = X + Y assert Add(1, 2) == 3 @@ -243,7 +243,7 @@ Sin X = math.sin X # ConstantError: this function is not computable at compile t コンパイル時関数は多相型の定義などでもよく使われます。 -```erg +```python Option T: Type = T or NoneType Option: Type -> Type ``` @@ -252,7 +252,7 @@ Option: Type -> Type Ergでは、関数に`==`が定義されていません。それは関数の構造的な同値性判定アルゴリズムが一般には存在しないためです。 -```erg +```python f = x: Int -> (x + 1)**2 g = x: Int -> x**2 + 2x + 1 @@ -271,7 +271,7 @@ assert (lambda x: x) != (lambda x: x) ## Appendix2: ()の補完 -```erg +```python f x: Object = ... # will be completed to f(x: Object) = ... diff --git a/doc/JA/syntax/05_builtin_funcs.md b/doc/JA/syntax/05_builtin_funcs.md index 279755ed..e0f973e0 100644 --- a/doc/JA/syntax/05_builtin_funcs.md +++ b/doc/JA/syntax/05_builtin_funcs.md @@ -4,7 +4,7 @@ `if`は条件に応じて処理を変える関数です。 -```erg +```python result: Option Int = if! Bool.sample!(), do: log "True was chosen" 1 @@ -14,7 +14,7 @@ print! result # None (or 1) `.sample!()`は集合の値をランダムに返します。もし戻り値が真ならば、`print! "True"`が実行されます。 条件が偽であった際の処理も指定できます。2つ目のdoブロックはelseブロックと呼ばれます。 -```erg +```python result: Nat = if Bool.sample!(): do: log "True was chosen" @@ -27,7 +27,7 @@ print! result # 1 (or 0) 処理が1行ならば、インデントを省略できます。 -```erg +```python result = if Bool.sample!(): do 1 do 0 @@ -37,7 +37,7 @@ result = if Bool.sample!(): 繰り返し行う処理を書くときは`for`が使えます。 -```erg +```python match_s(ss: Iterator(Str), pat: Pattern): Option Str = for ss, s -> if pat.match(s).is_some(): diff --git a/doc/JA/syntax/06_operator.md b/doc/JA/syntax/06_operator.md index f2e1e1de..6747385d 100644 --- a/doc/JA/syntax/06_operator.md +++ b/doc/JA/syntax/06_operator.md @@ -5,7 +5,7 @@ 演算子は関数の一種であり、したがってそれ自体も第一級オブジェクトで変数に束縛できます。束縛の際は``で囲む必要があります。 `+`(と`-`)については、単項演算子と二項演算子の両方が存在するため、一意化するために`_+_`(二項演算)/`+_`(単項演算)のどちらかを指定する必要があります。 -```erg +```python add = `+` # SyntaxError: specify `_+_` or `+_` add = `_+_` assert f(1, 2) == 3 @@ -17,7 +17,7 @@ assert g(1, 2) == 2 ただし、特殊形式と呼ばれる一部の演算子は束縛できないことに注意してください。 -```erg +```python def = `=` # SyntaxError: cannot bind `=` operator, this is a special form # NG: def x, 1 function = `->` # SyntaxError: cannot bind `->` operator, this is a special form diff --git a/doc/JA/syntax/07_side_effect.md b/doc/JA/syntax/07_side_effect.md index ab542b48..7c1e5b76 100644 --- a/doc/JA/syntax/07_side_effect.md +++ b/doc/JA/syntax/07_side_effect.md @@ -2,14 +2,14 @@ これまで`print!`の`!`の意味を説明せずにいましたが、いよいよその意味が明かされます。この!は、ズバリこのオブジェクトが「副作用」のある「プロシージャ」であることを示しています。プロシージャは関数に「副作用」という効果を与えたものです。 -```erg +```python f x = print! x # EffectError: functions cannot be assigned objects with side effects # hint: change the name to 'f!' ``` 上のコードはコンパイルエラーになります。関数中でプロシージャを使用しているからです。このような場合は、プロシージャとして定義しなくてはなりません。 -```erg +```python p! x = print! x ``` @@ -21,7 +21,7 @@ p! x = print! x 関数とプロシージャにはそれぞれメソッドが存在します。関数メソッドは`self`の不変参照のみを取れ、プロシージャルメソッドは`self`の可変参照を取れます。 `self`は特殊な引数で、メソッドの文脈では呼び出したオブジェクト自身を指します。参照の`self`は他のいかなる変数にも代入できません。 -```erg +```python C. method ref self = x = self # OwnershipError: cannot move out 'self' @@ -30,7 +30,7 @@ C. メソッドは`self`の所有権を奪うこともできます。そのメソッドの定義では`ref`または`ref!`を外します。 -```erg +```python n = 1 s = n.into(Str) # '1' n # ValueError: n was moved by .into (line 2) @@ -40,7 +40,7 @@ n # ValueError: n was moved by .into (line 2) ただし、可変参照から(不変/可変)参照の生成はできることに注意してください。これによって、プロシージャルメソッド中で再帰したり`self`を`print!`できたりします。 -```erg +```python T -> T # OK (move) T -> Ref T # OK T => Ref! T # OK (only once) @@ -63,14 +63,14 @@ Ref! T => Ref! T # OK 前者の例は`print!`で、後者の例は以下の関数です。 -```erg +```python nan _ = Float.NaN assert nan(1) != nan(1) ``` また、クラスや関数のように同値判定自体ができないオブジェクトも存在します。 -```erg +```python T = Structural {i = Int} U = Structural {i = Int} assert T == U @@ -88,7 +88,7 @@ assert C == D # TypeError: cannot compare classes 例として`print!`プロシージャについて考えます。`print!`は一見何の変数も書き換えていないように見えます。しかし、もしこれが関数だったとすると、例えばこのようなコードで外側変数を書き換えられます。 -```erg +```python camera = import "some_camera_module" ocr = import "some_ocr_module" @@ -107,7 +107,7 @@ n = ocr.read_num(image) # n = 3.141592 とはいえ、関数中で値を一時的に確認するとき、そのためだけに関連する関数まで`!`を付けたくない場合もあるでしょう。その際は`log`関数が使えます。 `log`はコード全体の実行後に値を表示します。これにより、副作用は伝搬されません。 -```erg +```python log "this will be printed after execution" print! "this will be printed immediately" # this will be printed immediately diff --git a/doc/JA/syntax/08_procedure.md b/doc/JA/syntax/08_procedure.md index 1cda8f4f..1cddedc9 100644 --- a/doc/JA/syntax/08_procedure.md +++ b/doc/JA/syntax/08_procedure.md @@ -2,7 +2,7 @@ プロシージャは可変オブジェクトを取り扱う際に必要となりますが、可変オブジェクトを引数に持てばプロシージャであるとは限りません。 -```erg +```python peek_str s: Str! = log s ``` diff --git a/doc/JA/syntax/09_builtin_procs.md b/doc/JA/syntax/09_builtin_procs.md index 95dbdf96..d360673d 100644 --- a/doc/JA/syntax/09_builtin_procs.md +++ b/doc/JA/syntax/09_builtin_procs.md @@ -5,7 +5,7 @@ オブジェクトのユニークな識別番号を返します。 純粋なErgの意味論の中では同一の構造を持つオブジェクトの間に差異を見出す事はできませんが、実際のところ、オブジェクトはメモリ上の位置が異なります。`id!`はこの位置を表す数値を返します。 -```erg +```python ```

diff --git a/doc/JA/syntax/10_array.md b/doc/JA/syntax/10_array.md index d8d16bb2..73706278 100644 --- a/doc/JA/syntax/10_array.md +++ b/doc/JA/syntax/10_array.md @@ -3,7 +3,7 @@ 配列はもっとも基本的な __コレクション(集約)__ です。 コレクションとは、内部にオブジェクトを複数保持できるオブジェクトのことです。 -```erg +```python a = [1, 2, 3] a: [Int; 3] # 型指定: セミコロンの後の数字は要素数 # 要素数がわからない場合は省略可能 @@ -16,13 +16,13 @@ assert mut_a == [2, 2, 3] 配列には、原則として違う型のオブジェクトを入れることはできません。 -```erg +```python [1, "a"] # TypeError: 1st element is Int, but 2nd element is Str ``` しかし、このように明示的に型指定すると制限を回避できます。 -```erg +```python [1, "a"]: [Int or Str] ``` @@ -30,7 +30,7 @@ assert mut_a == [2, 2, 3] 配列は、複数の値をまとめて取り出すこともできます。これをスライスと呼びます。 -```erg +```python l = [1, 2, 3, 4] # Pythonのl[1:3]に相当 assert l[1..<3] == [2, 3] @@ -43,7 +43,7 @@ assert l[..].step(2) == [2, 4] スライスで得られるオブジェクトは配列の(不変)参照です。 -```erg +```python print! Typeof l[1..2] # Ref [Int; 4] ``` diff --git a/doc/JA/syntax/11_tuple.md b/doc/JA/syntax/11_tuple.md index 3523e6a0..b395a601 100644 --- a/doc/JA/syntax/11_tuple.md +++ b/doc/JA/syntax/11_tuple.md @@ -3,7 +3,7 @@ タプルは配列と似ていますが、違う型のオブジェクトを保持できます。 このようなコレクションを非等質なコレクションと呼びます。対して等質なコレクションには配列、セットなどがあります。 -```erg +```python t = (1, True, "a") (i, b, s) = t assert(i == 1 and b == True and s == "a") @@ -12,7 +12,7 @@ assert(i == 1 and b == True and s == "a") タプル`t`は`t.n`の形式でn番目の要素を取り出すことができます。Pythonと違い、`t[n]`ではないことに注意してください。 これは、タプル要素のアクセスはメソッド(配列の`[]`はメソッドです)というより属性に近い(コンパイル時に要素の存在がチェックされる、nによって型が変わりうる)ためです。 -```erg +```python assert t.0 == 1 assert t.1 == True assert t.2 == "a" @@ -20,14 +20,14 @@ assert t.2 == "a" 括弧`()`はネストしないとき省略可能です。 -```erg +```python t = 1, True, "a" i, b, s = t ``` タプルは違う型のオブジェクトを保持できますが、そのかわり配列のようなイテレーションができなくなります。 -```erg +```python t: ({1}, {2}, {3}) = (1, 2, 3) (1, 2, 3).iter().map(x -> x + 1) # TypeError: type ({1}, {2}, {3}) has no method `.iter()` # すべて同じ型の場合配列と同じように`(T; n)`で表せるが、これでもイテレーションは出来ない @@ -38,11 +38,11 @@ assert (Int; 3) == (Int, Int, Int) ただし、非等質なコレクション(タプルなど)はアップキャスト、Intersectionなどによって等質なコレクション(配列など)に変換できます。 これを等質化といいます。 -```erg +```python (Int, Bool, Str) can be [T; 3] | T :> Int, T :> Bool, T :> Str ``` -```erg +```python t: (Int, Bool, Str) = (1, True, "a") # non-homogenous a: [Int or Bool or Str; 3] = [1, True, "a"] # homogenous _a: [Show; 3] = [1, True, "a"] # homogenous @@ -54,21 +54,21 @@ t.try_into([Show; 3])?.iter().map(x -> log x) # OK 要素が0個のタプルはユニットと言います。ユニットは値ですが、自身の型そのものも指します。 -```erg +```python unit = () (): () ``` ユニットはすべての要素0のタプルのスーパークラスです。 -```erg +```python () > (Int; 0) () > (Str; 0) ``` このオブジェクトの使いみちは、引数、戻り値がないプロシージャなどです。Ergのサブルーチンは、必ず引数と戻り値を持つ必要があります。しかしプロシージャなどの場合、副作用を起こすだけで意味のある引数・戻り値がない場合もあります。その際に「意味のない、形式上の値」としてユニットを使うわけです。 -```erg +```python # ↓ 実はこの括弧はユニット p!() = # `print!`は意味のある値を返さない @@ -83,7 +83,7 @@ Ergでの使い分けとしては、プロシージャなどではじめから 実は、Ergの`Callable`オブジェクトは全て1引数で1戻り値です。N個の引数を取るサブルーチンは、「N個の要素を持つタプル1つ」を引数として受け取っているだけだったのです。 -```erg +```python # f x = ...は暗黙にf(x) = ...とみなされる f x = x assert f(1) == 1 @@ -95,14 +95,14 @@ assert (2, 3) == g 1, 2, 3 関数の型もこれで説明が付きます。 -```erg +```python assert f in T: {(T,) -> T | T} assert g in {(Int, ...(Int; N)) -> (Int; N) | N: Nat} ``` 正確には、関数の入力はタプルではなく「デフォルト属性付きNamedタプル」です。これは関数の引数でだけ使える特殊なタプルで、レコードのように名前付けができ、デフォルト値を持つことができます。 -```erg +```python f(x: Int, y=0) = x + y f: (Int, y=Int) -> Int diff --git a/doc/JA/syntax/12_dict.md b/doc/JA/syntax/12_dict.md index d921c6f2..8918200b 100644 --- a/doc/JA/syntax/12_dict.md +++ b/doc/JA/syntax/12_dict.md @@ -2,14 +2,14 @@ Dictはキーと値のペアを持つコレクションです。 -```erg +```python ids = {"Alice": 145, "Bob": 214, "Charlie": 301} assert ids["Alice"] == 145 ``` キーはHashであるならば文字列でなくても構いません。 -```erg +```python # rangeオブジェクトをキーにするのは非推奨(スライスと混同される) r = {1..3: "1~3", 4..6: "4~6", 7..9: "7~9"} assert r[1..3] == "1~3" @@ -20,20 +20,20 @@ assert l[[]] == "empty" Dictに順番は関係ありません。また、重複する要素を持つことも出来ません。この点でDictは[Set](./14_set.md)と似ています。 Dictは値付きのSetと言うこともできるでしょう。 -```erg +```python {"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214} ``` DictリテラルからDictを生成する場合、キーの重複がないかチェックされます。 重複がある場合コンパイルエラーとなります。 -```erg +```python {"Alice": 145, "Alice": 1} # KeyError: Duplicate key "Alice" ``` 空のDictは`{:}`で生成します。`{}`は空の配列を表すことに注意してください。 -```erg +```python mut_dict = !{:} mut_dict.insert! "Alice", 145 mut_dict.insert! "Bob", 214 @@ -44,7 +44,7 @@ assert mut_dict["Alice"] == 145 キー・値の型は単一でなくてもよく、そのような辞書を __非等質な辞書(heterogenous dict)__ といいます。 -```erg +```python d: {Str: Int, Int: Str} = {”a”: 1, 1: “a”} assert d[”a”] == 1 assert d[1] == “a” @@ -53,7 +53,7 @@ assert d[1] == “a” しかし、違う型のキーに同じ型の値、または同じ型のキーに違う型の値をあてることはできません。 このような場合は代わりにOr型(Union)を使います。 -```erg +```python invalid1 = {1: “a”, “a”: “b”} invalid2 = {1: “a”, 2: 2} diff --git a/doc/JA/syntax/13_record.md b/doc/JA/syntax/13_record.md index 2ab07f4a..ff2ba75f 100644 --- a/doc/JA/syntax/13_record.md +++ b/doc/JA/syntax/13_record.md @@ -3,7 +3,7 @@ レコードは、キーでアクセスするDictとコンパイル時にアクセスが検査されるタプルの性質を併せ持つコレクションです。 JavaScriptをやったことがある方ならば、オブジェクトリテラル記法の(より強化された)ようなものと考えてください。 -```erg +```python john = {.name = "John"; .age = 21} assert john.name == "John" @@ -20,7 +20,7 @@ JavaScriptのオブジェクトリテラルとの相違点は、文字列でア 一般的にはレコードの使用を推奨します。レコードには、コンパイル時に要素が存在するかチェックされる、 __可視性(visibility)__ を指定できるなどのメリットがあります。 可視性の指定は、Java言語などでみられるpublic/privateの指定に相当します。詳しくは[可視性](./15_visibility.md)を参照してください。 -```erg +```python a = {x = 1; .y = x + 1} a.x # AttributeError: x is private # Hint: declare as `.x` @@ -31,7 +31,7 @@ assert a.y == 2 属性に対する明示的な型指定もできます。 -```erg +```python anonymous = { .name: Option! Str = !None .age = 20 @@ -41,7 +41,7 @@ anonymous.name.set! "John" レコードはメソッドも持てます。 -```erg +```python o = { .i = !0 .inc! ref! self = self.i.inc!() @@ -55,7 +55,7 @@ assert o.i == 1 レコードに関して特筆すべき文法があります。レコードの属性値が全てクラス(構造型ではダメです)のとき、そのレコード自体が、自身の属性を要求属性とする型としてふるまいます。 このような型をレコード型と呼びます。詳しくは[レコード]の項を参照してください。 -```erg +```python # レコード john = {.name = "John"} # レコード型 @@ -74,7 +74,7 @@ print! Named.name # Str レコードは以下のようにして分解できます。 -```erg +```python record = {x = 1; y = 2} {x = a; y = b} = record assert a == 1 @@ -91,7 +91,7 @@ match point: また、レコードは属性と同名の変数があるとき、例えば`x = x`または`x = .x`を`x`に、`.x = .x`または`.x = x`を`.x`に省略できます。 ただし、属性が一つのときはセットと区別するために`;`を付ける必要があります。 -```erg +```python x = 1 y = 2 xy = {x; y} @@ -108,7 +108,7 @@ assert tuple.1 == 1 この構文を利用して、レコードを分解して変数に代入できます。 -```erg +```python # same as `{x = x; y = y} = xy` {x; y} = xy assert x == 1 @@ -123,7 +123,7 @@ assert b == 2 空のレコードは`{=}`で表されます。空のレコードはUnitと同じく、自身のクラスそのものでもあります。 -```erg +```python empty_record = {=} empty_record: {=} # Object: Type = {=} @@ -137,7 +137,7 @@ empty_record: Structural {=} 逆に、レコードクラスの`{=}`は要求インスタンス属性がないので、全てのオブジェクトがこれの要素になります。`Object`は、これのエイリアスです。 `Object`(のパッチ)は`.__sizeof__`などの極めて基本的な提供メソッドを持ちます。 -```erg +```python AnyPatch = Patch Structural {=} .__sizeof__ self = ... .clone self = ... @@ -153,7 +153,7 @@ Never = Class {} Ergにはもう一つインスタントブロックという構文がありますが、これは単に最後に評価した値を返すだけです。属性の保持はできません。 -```erg +```python x = x = 1 y = x + 1 @@ -169,7 +169,7 @@ y = 素のレコード(レコードリテラルで生成されたレコード)は、これ単体でメソッドを実装しようとすると、直接インスタンスに定義する必要があります。 これは効率が悪く、さらに属性の数が増えていくとエラー表示などが見にくくなり使いにくいです。 -```erg +```python john = { name = "John Smith" age = !20 @@ -183,7 +183,7 @@ john + 1 そこで、このような場合はレコードクラスを継承します。このようなクラスをデータクラスと呼びます。 これについては[クラス](./type/04_class.md)の項で詳しく説明します。 -```erg +```python Person = Inherit {name = Str; age = Nat} Person. greet! ref self = print! "Hello, my name is {self::name} and I am {self::age} years old." diff --git a/doc/JA/syntax/14_set.md b/doc/JA/syntax/14_set.md index 3dd485cc..4a69f085 100644 --- a/doc/JA/syntax/14_set.md +++ b/doc/JA/syntax/14_set.md @@ -2,7 +2,7 @@ セットは集合を表し、データ構造的には重複、順序のない配列です。 -```erg +```python assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3} assert {1, 2} == {1, 1, 2} # 重複は自動で削除される assert {1, 2} == {2, 1} @@ -10,7 +10,7 @@ assert {1, 2} == {2, 1} セットは集合演算を行えます。 -```erg +```python assert 1 in {1, 2, 3} assert not 1 in {} assert {1} or {2} == {1, 2} @@ -20,7 +20,7 @@ assert {1, 2} not {2} == {1} セットは等質なコレクションです。別のクラスのオブジェクトを共存させるためには、等質化させなくてはなりません。 -```erg +```python s: {Int or Str} = {"a", 1, "b", -1} ``` @@ -28,7 +28,7 @@ s: {Int or Str} = {"a", 1, "b", -1} セットは型としても扱えます。このような型は __列挙型(Enum type)__ と呼ばれます。 -```erg +```python i: {1, 2, 3} = 1 assert i in {1, 2, 3} ``` @@ -36,7 +36,7 @@ assert i in {1, 2, 3} セットの要素がそのまま型の要素になります。 セット自身は違うことに注意が必要です。 -```erg +```python mut_set = {1, 2, 3}.into {Int; !3} mut_set.insert!(4) ``` diff --git a/doc/JA/syntax/16_iterator.md b/doc/JA/syntax/16_iterator.md index 2800a5ae..affcb68e 100644 --- a/doc/JA/syntax/16_iterator.md +++ b/doc/JA/syntax/16_iterator.md @@ -2,7 +2,7 @@ イテレータは、コンテナの要素を取り出すためのオブジェクトです。 -```erg +```python for! 0..9, i => print! i ``` @@ -12,7 +12,7 @@ for! 0..9, i => ではここで`for!`プロシージャの型シグネチャを見てみましょう。 -```erg +```python for!: |T: Type, I <: Iterable T| (I, T => None) => None ``` @@ -20,7 +20,7 @@ for!: |T: Type, I <: Iterable T| (I, T => None) => None `Iterable`は`.Iterator`属性, `.iter`メソッドを要求メソッドに持つ型です。 -```erg +```python Iterable T = Trait { .Iterator = {Iterator} .iter = Self(T).() -> Self.Iterator T @@ -29,7 +29,7 @@ Iterable T = Trait { `.Iterator`属性の型`{Iterator}`はいわゆるセットカインド(カインドは[こちら](./type/advanced/kind.md)で説明されています)です。 -```erg +```python assert [1, 2, 3] in Iterable(Int) assert 1..3 in Iterable(Int) assert [1, 2, 3].Iterator == ArrayIterator diff --git a/doc/JA/syntax/17_mutability.md b/doc/JA/syntax/17_mutability.md index 901fdd7c..2271632e 100644 --- a/doc/JA/syntax/17_mutability.md +++ b/doc/JA/syntax/17_mutability.md @@ -3,7 +3,7 @@ すでに見たように、Ergの変数は全て不変です。しかし、Ergのオブジェクトには可変性という概念があります。 以下のコードを例にします。 -```erg +```python a = [1, 2, 3] a = a + [4, 5, 6] print! a # [1, 2, 3, 4, 5, 6] @@ -12,7 +12,7 @@ print! a # [1, 2, 3, 4, 5, 6] 上のコードは実際にはErgでは実現できません。再代入不可だからです。 このコードは実行できます。 -```erg +```python b = ![1, 2, 3] b.concat! [4, 5, 6] print! b # [1, 2, 3, 4, 5, 6] @@ -21,7 +21,7 @@ print! b # [1, 2, 3, 4, 5, 6] `a, b`は、最終的な結果は同じように見えますが、その意味は大きく異なります。 `a`は`Nat`の配列を示す変数ですが、1行目と2行目では指しているオブジェクトが異なります。`a`という名前が同じだけで、中身はさし変わっているのです。 -```erg +```python a = [1, 2, 3] print! id! a # 0x000002A798DFE940 _a = a + [4, 5, 6] @@ -32,14 +32,14 @@ print! id! _a # 0x000002A798DFE980 `b`は`Nat`の「動的」配列です。オブジェクトの中身は変わりますが、変数の指すものは同じです。 -```erg +```python b = [1,2,3].into [Int; !3] print! id! b # 0x000002A798DFE220 b.concat! [4, 5, 6] print! id! b # 0x000002A798DFE220 ``` -```erg +```python i = !0 if! True: do! i.inc!() # or i.add!(1) @@ -50,7 +50,7 @@ print! i # 1 `!`は __可変化演算子(mutation operator)__ とよばれる特殊な演算子です。引数の不変オブジェクトを可変化して返します。 `!`がついたオブジェクトの振る舞いはカスタム可能です。 -```erg +```python Point = Class {.x = Int; .y = Int} # この場合.xは可変化し、yは不変のまま @@ -67,7 +67,7 @@ print! p.x # 1 変数と違い、すべてのスコープで同じものを指すのが定数です。 定数は`=`演算子で宣言します。 -```erg +```python PI = 3.141592653589 match! x: PI => print! "this is pi" diff --git a/doc/JA/syntax/18_ownership.md b/doc/JA/syntax/18_ownership.md index 34e7be1c..4970db77 100644 --- a/doc/JA/syntax/18_ownership.md +++ b/doc/JA/syntax/18_ownership.md @@ -9,7 +9,7 @@ ErgはRustから影響を受けた所有権システムを持っています。 Rustの所有権システムは一般的に難解だと言われていますが、Ergのそれは直感的になるよう簡略化されています。 Ergでは __可変オブジェクト__ に所有権がついており、所有権を失った後はそのオブジェクトを参照できません。 -```erg +```python v = [1, 2, 3].into [Int; !3] push! vec, x = @@ -34,7 +34,7 @@ print! w # [1, 2, 3, 4] 複製はPythonのディープコピーに相当し、同一のオブジェクトをまるごと作り直すので、凍結・借用と比べて一般に計算コスト、メモリコストが高くなります。 オブジェクトを複製する必要があるようなサブルーチンは、「引数を消費する」サブルーチンといいます。 -```erg +```python capitalize s: Str! = s.capitalize!() s @@ -51,7 +51,7 @@ log s2, s1 # !"HELLO hello" 可変配列からは直接イテレータを作ることができないので、不変配列に変換します。 配列を壊したくない場合は、[`.freeze_map`メソッド](./type/mut.md)等を使います。 -```erg +```python # イテレータが出す値の合計を計算する sum|T <: Add + HasUnit| i: Iterator T = ... @@ -69,7 +69,7 @@ y # この後もyは触れられる 借用は複製や凍結よりも低コストです。 以下のような単純な場合では、借用を行えます。 -```erg +```python peek_str ref(s: Str!) = log s @@ -80,7 +80,7 @@ peek_str s 借用した値は元のオブジェクトに対する __参照__ と呼ばれます。 参照をまた別のサブルーチンに渡す「又貸し」はできますが、借りているだけなので消費することはできません。 -```erg +```python steal_str ref(s: Str!) = # log関数は引数を借用するだけなので、又貸しできる log s @@ -89,7 +89,7 @@ steal_str ref(s: Str!) = # hint: use `clone` method ``` -```erg +```python steal_str ref(s: Str!) = # これもダメ(=は右辺を消費する) x = s # OwnershipError: cannot consume a borrowed value diff --git a/doc/JA/syntax/19_visibility.md b/doc/JA/syntax/19_visibility.md index e28163df..489cce62 100644 --- a/doc/JA/syntax/19_visibility.md +++ b/doc/JA/syntax/19_visibility.md @@ -4,12 +4,12 @@ Ergの変数には __可視性__ という概念が存在します。 今まで見てきた変数は全て __プライベート変数(非公開変数)__ と呼ばれます。これは、外部から不可視の変数です。 例えば`foo`モジュールで定義したプライベート変数は、別のモジュールから参照できないのです。 -```erg +```python # foo.er x = "this is an invisible variable" ``` -```erg +```python # bar.er foo = import "foo" foo.x # AttributeError: Module 'foo' has no attribute 'x' ('x' is private) @@ -18,12 +18,12 @@ foo.x # AttributeError: Module 'foo' has no attribute 'x' ('x' is private) 対して、 __パブリック(公開)変数__ というものもあり、こちらは外部から参照できます。 公開変数は`.`を付けて定義します。 -```erg +```python # foo.er .x = "this is a visible variable" ``` -```erg +```python # bar.er foo = import "foo" assert foo.x == "this is a visible variable" @@ -31,7 +31,7 @@ assert foo.x == "this is a visible variable" 非公開変数には何も付ける必要はないのですが、非公開であることを明示するために`::`または`self::`(型などなら`Self::`)を付けることもできます。またモジュールなら`module::`とすることもできます。 -```erg +```python ::x = "this is a invisible variable" assert ::x == x assert self::x == ::x @@ -40,7 +40,7 @@ assert module::x == ::x 単なる逐次実行の文脈では、プライベート変数はローカル変数とほぼ同義です。内側のスコープからは参照することが出来ます。 -```erg +```python ::x = "this is a private variable" y = x + 1 # 正確にはmodule::x @@ -50,7 +50,7 @@ y = 参照したい変数のスコープを左側に指定します。トップレベルの場合は`module`を指定します。 指定しなかった場合は通常の場合と同じく最も内側の変数が参照されます。 -```erg +```python ::x = 0 assert x == 0 y = @@ -66,7 +66,7 @@ y = 無名サブルーチンのスコープでは`self`で自身のスコープを指定します。 -```erg +```python x = 0 f = x -> log module::x, self::x @@ -75,7 +75,7 @@ f 1 # 0 1 `::`は、プライベートインスタンス属性にアクセスするという役割も持っています。 -```erg +```python x = 0 C = Class {x = Int} C. @@ -89,12 +89,12 @@ C. あるモジュールで定義されたクラスは、実は外部モジュールからでもメソッドを定義できます。 -```erg +```python # foo.er .Foo = Class() ``` -```erg +```python # bar.er {Foo; ...} = import "foo" @@ -113,7 +113,7 @@ Foo. 外部で定義された非公開メソッドは、定義モジュール内でのみ`Foo`クラスのメソッドから参照できます。 公開メソッドはクラスの外には公開されますが、モジュール外までは公開されません。 -```erg +```python # baz.er {Foo; ...} = import "foo" @@ -124,7 +124,7 @@ foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defi また、Re-exportする型にメソッドを定義することはできません。 インポート元のモジュールによってメソッドが見つかったり見つからなかったりといった混乱を防ぐためです。 -```erg +```python # bar.er {.Foo; ...} = import "foo" @@ -136,7 +136,7 @@ foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defi このようなことを行いたい場合は[パッチ](./type/07_patch.md)を定義します。 -```erg +```python # bar.er {Foo; ...} = import "foo" @@ -147,7 +147,7 @@ FooImpl. public self = self::private() ``` -```erg +```python # baz.er {Foo; ...} = import "foo" {FooImpl; ...} = import "bar" @@ -161,7 +161,7 @@ foo.public() 変数の可視性は完全な公開・非公開しかないわけではありません。 制限付きで公開することもできます。 -```erg +```python # foo.er .record = { .a = { @@ -179,7 +179,7 @@ _ = .record.a.y # OK _ = .record.a.z # OK ``` -```erg +```python foo = import "foo" _ = foo.record.a.x # VisibilityError _ = foo.record.a.y # VisibilityError diff --git a/doc/JA/syntax/20_naming_rule.md b/doc/JA/syntax/20_naming_rule.md index 82c33236..5b8617de 100644 --- a/doc/JA/syntax/20_naming_rule.md +++ b/doc/JA/syntax/20_naming_rule.md @@ -2,7 +2,7 @@ 変数を定数式として使いたい場合は、必ず大文字で始めます。二文字以降は小文字でもよいです。 -```erg +```python i: Option Type = Int match i: t: Type -> log "type" @@ -12,7 +12,7 @@ match i: 副作用のあるオブジェクトは、必ず`!`で終わります。プロシージャとプロシージャルメソッド、そして可変型です。 ただし、`Proc`型自体は可変型ではありません。 -```erg +```python # Callable == Func or Proc c: Callable = print! match c: @@ -22,7 +22,7 @@ match c: 属性を外部に公開したい場合は、初めに`.`をつけて定義します。`.`を初めにつけなかった場合は非公開になります。混乱を避けるため同一のスコープ内で共存はできません。 -```erg +```python o = {x = 1; .x = 2} # SyntaxError: private and public variables with the same name cannot coexist ``` @@ -32,7 +32,7 @@ o = {x = 1; .x = 2} # SyntaxError: private and public variables with the same na このようにシングルクォートで囲まれた文字列による識別子をリテラル識別子といいます。 これは、Pythonなど他言語のAPI(FFI)を呼び出す際に使います。 -```erg +```python bar! = pyimport("foo").'bar' ``` @@ -40,7 +40,7 @@ Ergでも有効な識別子の場合は、''で囲む必要はありません。 さらに、リテラル識別子中では記号も空白も入れることができるため、通常は識別子として使えない文字列を識別子として使うことができます。 -```erg +```python '∂/∂t' y 'test 1: pass x to y'() ``` diff --git a/doc/JA/syntax/21_lambda.md b/doc/JA/syntax/21_lambda.md index f99d9c25..7a29084f 100644 --- a/doc/JA/syntax/21_lambda.md +++ b/doc/JA/syntax/21_lambda.md @@ -2,7 +2,7 @@ 無名関数は、関数オブジェクトを名付けずその場で生成するための文法です。 -```erg +```python # `->`は無名関数演算子 # same as `f x, y = x + y` f = (x, y) -> x + y @@ -12,7 +12,7 @@ g = (x, y: Int): Int -> x + y 引数が1つの場合は`()`を省略できます。 -```erg +```python assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4] assert ((i, j) -> [i, j])(1, 2) == [1, 2] ``` @@ -20,14 +20,14 @@ assert ((i, j) -> [i, j])(1, 2) == [1, 2] 下の場合`0..9, (i -> ...)`であって`(0..9, i) -> ...`ではありません。 `->`は左辺に一つだけ引数をとります。複数の引数は一つのタプルとして受け取ります。 -```erg +```python for 0..9, i: Int -> ... ``` 無名関数では、空白による構文解釈の差異が存在します。 -```erg +```python # この場合は`T(() -> Int)`と解釈される i: T () -> Int # この場合は(U()) -> Intと解釈される @@ -36,7 +36,7 @@ k: U() -> Int 無名関数は引数なしでも使えます。 -```erg +```python # `=>`は無名プロシージャ演算子 p! = () => print! "`p!` was called" # `() ->`, `() =>`には`do`, `do!`という糖衣構文がある @@ -46,7 +46,7 @@ p!() # `p!` was called 引数なし関数は遅延初期化に使えます。 -```erg +```python time = import "time" date = import "datetime" now = if! True: @@ -59,7 +59,7 @@ now = if! True: 型付け、パターンマッチもできます。このため、`match`関数はほとんど無名関数の力で実現されています。 `match`関数の引数に与える無名関数は上から順番にトライされます。なので、上の方は特殊なケースを、下に行くほど一般的なケースを記述する必要があります。順番を間違えると(可能な限り)コンパイラがWarningを出します。 -```erg +```python n = (Complex or Ratio or Int).sample!() i = match n: PI -> PI # 定数PIに等しい場合 @@ -71,7 +71,7 @@ i = match n: エラーハンドリングも`?`か`match`を使用して行うのが一般的です。 -```erg +```python res: ParseResult Int match res: i: Int -> i @@ -85,7 +85,7 @@ match res2: ## 無名多相関数 -```erg +```python # same as id|T| x: T = x id = |T| x: T -> x ``` diff --git a/doc/JA/syntax/22_subroutine.md b/doc/JA/syntax/22_subroutine.md index b13a57d4..6bc287b2 100644 --- a/doc/JA/syntax/22_subroutine.md +++ b/doc/JA/syntax/22_subroutine.md @@ -2,14 +2,14 @@ ## Func -```erg +```python some_func(x: T, y: U) -> V some_func: (T, U) -> V ``` ## Proc -```erg +```python some_proc!(x: T, y: U) => V some_proc!: (T, U) => V ``` @@ -18,7 +18,7 @@ some_proc!: (T, U) => V メソッド型は、外部からは`Self`で指定できません。 -```erg +```python .some_method(self, x: T, y: U) => () # Self.(T, U) => ()はselfの所有権を奪う .some_method: Ref(Self).(T, U) => () @@ -28,7 +28,7 @@ some_proc!: (T, U) => V 以下で、型`T!`は`N: Nat`という型引数を取るとします。外部から指定する場合は型変数を使用します。 -```erg +```python T!: Nat -> Type # ~>は適用前後の型引数の状態を示す(このときselfは可変参照でなくてはならない) T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => () @@ -39,7 +39,7 @@ T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => () 所有権が奪われる場合は以下のようになります。 -```erg +```python # Nを使わないなら_で省略可 # .some_method!: |N, X: Nat| T!(N).({X}) => T!(N+X) .some_method!|N, X: Nat|(self(N), X: Nat) => T!(N+X) @@ -50,7 +50,7 @@ T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => () ``で囲むことで通常の関数と同じように定義できます。 `and`や`or`などの中置アルファベット演算子は囲むことで中置演算子として定義できます。 -```erg +```python and(x, y, z) = x and y and z `_+_`(x: Foo, y: Foo) = x.a + y.a `-_`(x: Foo) = Foo.new(-x.a) diff --git a/doc/JA/syntax/23_closure.md b/doc/JA/syntax/23_closure.md index 5d0408a6..f8ff31d8 100644 --- a/doc/JA/syntax/23_closure.md +++ b/doc/JA/syntax/23_closure.md @@ -2,7 +2,7 @@ Ergのサブルーチンには、外部変数を捕捉する「クロージャ」という機能があります。 -```erg +```python outer = 1 f x = outer + x assert f(1) == 2 @@ -10,7 +10,7 @@ assert f(1) == 2 不変オブジェクトと同じく、可変オブジェクトも捕捉できます。 -```erg +```python sum = !0 for! 1..10, i => sum.add! i @@ -25,7 +25,7 @@ assert sum == 46 しかし、関数は可変オブジェクトを捕捉できないので注意が必要です。 仮に可変オブジェクトが関数内で参照できると、以下のようなコードが書けてしまいます。 -```erg +```python # !!! このコードは実際にはエラーになる !!! i = !0 f x = i + x @@ -39,7 +39,7 @@ assert f 1 == 2 関数定義時点での可変オブジェクトの内容がほしい場合は`.clone`を呼び出します。 -```erg +```python i = !0 immut_i = i.clone().freeze() f x = immut_i + x @@ -50,7 +50,7 @@ assert f 1 == 1 ## 可変状態の回避、関数型プログラミング -```erg +```python # Erg sum = !0 for! 1..10, i => @@ -71,7 +71,7 @@ assert sum == 45 しかし、Ergではもっとシンプルな書き方を推奨します。 サブルーチンと可変オブジェクトを使って状態を持ち回す代わりに、関数を使用する状態を局所化するスタイルを使います。これは関数型プログラミングと呼ばれます。 -```erg +```python # Functional style sum = (1..10).sum() assert sum == 45 @@ -83,7 +83,7 @@ assert sum == 45 `fold`はイテレータのメソッドで、各イテレーションごとに引数`f`を実行します。 結果を蓄積するカウンタの初期値は`init`で指定し、`acc`に蓄積されていきます。 -```erg +```python # start with 0, result will sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i) assert sum == 45 diff --git a/doc/JA/syntax/24_module.md b/doc/JA/syntax/24_module.md index 9fc334f4..613f6ee9 100644 --- a/doc/JA/syntax/24_module.md +++ b/doc/JA/syntax/24_module.md @@ -2,17 +2,17 @@ Ergでは、ファイル自体を1つのレコードとみなすことができます。これをモジュールと呼びます。 -```erg: foo.er +```python: foo.er # foo.er .i = 1 ``` -```erg +```python # fooモジュールを定義するのはこのレコードを定義するのとほとんど同じ foo = {.i = 1} ``` -```erg: bar.er +```python: bar.er # bar.er foo = import "foo" print! foo # @@ -21,7 +21,7 @@ assert foo.i == 1 モジュール型はレコード型でもあるので、分解代入が可能です。 -```erg +```python {sin; cos; ...} = import "math" ``` diff --git a/doc/JA/syntax/25_object_system.md b/doc/JA/syntax/25_object_system.md index b2a840e8..4a387b0a 100644 --- a/doc/JA/syntax/25_object_system.md +++ b/doc/JA/syntax/25_object_system.md @@ -15,7 +15,7 @@ レコードリテラル(`{attr = value; ...}`)で生成されるオブジェクトです。 このオブジェクトは`.clone`や`.__sizeof__`などの基本的なメソッドを持ちます。 -```erg +```python obj = {.x = 1} assert obj.x == 1 @@ -27,7 +27,7 @@ assert obj2.x == 1 and obj2.y == 2 オブジェクトと関連付けられたオブジェクトです。特に自身(`self`)を暗黙の第一引数にとるサブルーチン属性はメソッド(method)と呼ばれます。 -```erg +```python # private_attrには`.`がないことに注意 record = {.public_attr = j; private_attr = 2; .method = self -> self.i + 1} record.public_attr == 2 diff --git a/doc/JA/syntax/26_pattern_matching.md b/doc/JA/syntax/26_pattern_matching.md index c86cc43f..1c2399a8 100644 --- a/doc/JA/syntax/26_pattern_matching.md +++ b/doc/JA/syntax/26_pattern_matching.md @@ -4,7 +4,7 @@ ### 変数パターン -```erg +```python # basic assignment i = 1 # with type @@ -28,7 +28,7 @@ a: Array Int, 4 = [0, 1, 2, 3] ### リテラルパターン -```erg +```python # もし`i`がコンパイル時に1と判断できない場合は、TypeErrorが発生する。 # `_: {1} = i`を省略したもの 1 = i @@ -47,7 +47,7 @@ fib n: Nat = fib n-1 + fib n-2 ### 定数パターン -```erg +```python cond = False match! cond: True => print! "cond is True" @@ -64,7 +64,7 @@ name = match num: ### 篩パターン -```erg +```python # この2つは同じ Array(T, N: {N | N >= 3}) Array(T, N | N >= 3) @@ -75,7 +75,7 @@ f(1, 0) # TypeError: N (2nd parameter) must be 1 or more ### 破棄(ワイルドカード)パターン -```erg +```python _ = 1 _: Int = 1 zero _ = 0 @@ -86,7 +86,7 @@ right(_, r) = r 後述するタプル/配列/レコードパターンと組み合わせて使います。 -```erg +```python [i, ...j] = [1, 2, 3, 4] assert j == [2, 3, 4] first|T|(fst: T, ...rest: T) = fst @@ -95,7 +95,7 @@ assert first(1, 2, 3) == 1 ### タプルパターン -```erg +```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) # ネストしていないなら()を省略可能(1, 2は(1, 2)として扱われる) @@ -106,7 +106,7 @@ f(x, y) = ... ### 配列パターン -```erg +```python [i, j] = [1, 2] [[k, l], _] = [[1, 2], [3, 4]] @@ -116,7 +116,7 @@ length [_, ...rest] = 1 + length rest #### レコードパターン -```erg +```python record = {i = 1; j = 2; k = 3} {j; ...} = record # i, k will be freed @@ -133,7 +133,7 @@ f {x: Int; y: Int} = ... ### データクラスパターン -```erg +```python Point = Inherit {x = Int; y = Int} p = Point::{x = 1; y = 2} Point::{x; y} = p @@ -156,7 +156,7 @@ List T. ※実際には単なる列挙型 -```erg +```python match x: i: {1, 2} -> "one or two: {i}" _ -> "other" @@ -166,7 +166,7 @@ match x: ※実際には単なる区間型 -```erg +```python # 0 < i < 1 i: 0<..<1 = 0.5 # 1 < j <= 2 diff --git a/doc/JA/syntax/27_comprehension.md b/doc/JA/syntax/27_comprehension.md index 4448dfed..70edab21 100644 --- a/doc/JA/syntax/27_comprehension.md +++ b/doc/JA/syntax/27_comprehension.md @@ -9,7 +9,7 @@ 内包表記の例 -```erg +```python # レイアウト節はi # バインド節はi <- [0, 1, 2] assert [i | i <- [0, 1, 2]] == [0, 1, 2] @@ -36,7 +36,7 @@ Haskellのリスト内包表記の場合、変数の順番は結果に違いを [(i, j) | j <- [3..5], i <- [1..3]] == [(1,3),(2,3),(3,3),(1,4),(2,4),(3,4),(1,5),(2,5),(3,5)] ``` -```erg +```python # Erg assert [(i, j) | i <- 1..<3; j <- 3..<5] == [(i, j) | j <- 3..<5; i <- 1..<3] ``` @@ -53,7 +53,7 @@ assert [(i, j) for i in range(1, 3) for j in range(3, 5)] == [(i, j) for j in ra 内包表記と似たものに、篩型があります。篩型は`{Name: Type | Predicate}`という形式で作られる型(列挙型)です。 篩型の場合、Nameは1つまででレイアウトは指定できず(ただしタプル型などにすれば複数の値は扱えます)、Predicateはコンパイル時計算できるもの、つまり定数式のみが指定できます。 -```erg +```python Nat = {I: Int | I >= 0} # 述語式がandだけの場合、;で代替できる # Nat2D = {(I, J): (Int, Int) | I >= 0; J >= 0} diff --git a/doc/JA/syntax/28_spread_syntax.md b/doc/JA/syntax/28_spread_syntax.md index 52c2c658..1c16844d 100644 --- a/doc/JA/syntax/28_spread_syntax.md +++ b/doc/JA/syntax/28_spread_syntax.md @@ -2,7 +2,7 @@ 分解代入において、変数の前に`...`を置くと残りの要素を全てその変数に展開できます。これを展開代入と呼びます。 -```erg +```python [x, ...y] = [1, 2, 3] assert x == 1 assert y == [2, 3] @@ -16,7 +16,7 @@ assert y == (2, 3) `...`のあとに何も書かない場合、残りの要素は無視して代入されます。このタイプの展開代入を特に抽出代入と呼びます。 抽出代入は、モジュールやレコード内にある特定の属性をローカルに持ってくる際に便利な構文です。 -```erg +```python {sin; cos; tan; ..} = import "math" ``` @@ -24,14 +24,14 @@ assert y == (2, 3) レコードでも同じようにできます。 -```erg +```python record = {x = 1; y = 2} {x; y; ...} = record ``` 全て展開したい場合は`{*} = record`とします。OCamlなどでいう`open`です。 -```erg +```python record = {x = 1; y = 2} {*} = record assert x == 1 and y == 2 diff --git a/doc/JA/syntax/29_decorator.md b/doc/JA/syntax/29_decorator.md index 90fd1587..34f02216 100644 --- a/doc/JA/syntax/29_decorator.md +++ b/doc/JA/syntax/29_decorator.md @@ -3,7 +3,7 @@ デコレータは型や関数に特定の状態や振る舞いを追加したり明示するために使われます。 デコレータの文法は以下の通りです。 -```erg +```python @deco X = ... ``` @@ -12,7 +12,7 @@ X = ... デコレータは特別なオブジェクトではなく、その実体は単なる1引数関数です。デコレータは以下の疑似コードと等価です。 -```erg +```python X = ... X = deco(X) ``` @@ -20,7 +20,7 @@ X = deco(X) Ergでは変数の再代入が出来ないので、上のようなコードは通りません。 単なる変数の場合は`X = deco(...)`と同じなのですが、インスタントブロックやサブルーチンの場合はそうすることができないので、デコレータが必要になってきます。 -```erg +```python @deco f x = y = ... @@ -50,7 +50,7 @@ C = Class ... 引数のトレイトを実装することを示します。 -```erg +```python Add = Trait { .`_+_` = Self.(Self) -> Self } @@ -71,7 +71,7 @@ C. トレイトにデフォルトで付属するアタッチメントパッチを指定します。 これによって、Rustのトレイトと同じ挙動を再現できます。 -```erg +```python # foo.er Add R = Trait { .AddO = Type @@ -88,7 +88,7 @@ AddForOdd.AddO = Even こうすると、他のモジュールからトレイトをインポートした際に、アタッチメントパッチが自動で適用されます。 -```erg +```python # 本来IntIsBinAdd, OddIsBinAddも同時にインポートする必要があるが、アタッチメントパッチなら省略可 {BinAdd; ...} = import "foo" @@ -98,7 +98,7 @@ assert Odd.AddO == Even 内部的にはトレイトの`.attach`メソッドを使って結びつけているだけです。コンフリクトする場合はトレイトの`.detach`メソッドで外すことができます。 -```erg +```python @Attach X T = Trait ... assert X in T.attaches diff --git a/doc/JA/syntax/30_error_handling.md b/doc/JA/syntax/30_error_handling.md index 841296fa..f870b0d2 100644 --- a/doc/JA/syntax/30_error_handling.md +++ b/doc/JA/syntax/30_error_handling.md @@ -30,7 +30,7 @@ except e: 上の例では、例外がどの関数から送出されたものなのか、このコードだけでは分かりません。関数定義まで遡っても、その関数が例外を出すかを判別するのは難しいです。 -```erg +```python # Erg try!: do!: @@ -50,7 +50,7 @@ try!: `Error`/`Result`型単体では副作用が発生しないので、例外と違い送出場所などの情報(Context、文脈)を持てませんが、`.context`メソッドを使えば`Error`オブジェクトに情報を付加できます。`.context`メソッドは`Error`オブジェクト自身を消費して新しい`Error`オブジェクトを作るタイプのメソッドです。チェイン可能であり、複数のコンテクストを保持できます。 -```erg +```python f() = todo() \ .context "to be implemented in ver 1.2" \ @@ -71,7 +71,7 @@ f() `.stack`は呼び出し元オブジェクトの配列です。Errorオブジェクトは`return`(`?`によるものも含む)されるたびにその呼出元サブルーチンを`.stack`に積んでいきます。 そして`return`ができないコンテクストで`?`されるなり`.unwrap`されるなりすると、トレースバックを表示しながらパニックします。 -```erg +```python f x = ... y = foo.try_some(x)? @@ -100,7 +100,7 @@ Ergには回復不能なエラーへの対処として __パニッキング__ パニックは`panic`関数で行います。 -```erg +```python panic "something went wrong!" ``` diff --git a/doc/JA/syntax/31_pipeline.md b/doc/JA/syntax/31_pipeline.md index f4b708cd..ab861a70 100644 --- a/doc/JA/syntax/31_pipeline.md +++ b/doc/JA/syntax/31_pipeline.md @@ -2,7 +2,7 @@ パイプライン演算子は、次のように使います。 -```erg +```python assert f(g(x)) == (x |> g |> f) assert f(g(x, y)) == ((x, y) |> g |> f) ``` @@ -11,7 +11,7 @@ assert f(g(x, y)) == ((x, y) |> g |> f) パイプライン演算子はメソッドに対しても使えます。メソッドの場合、`object.method(args)`が`object |>.method(args)`と変わります。 単に`|>`が増えただけにも見えるが、結合強度が低めなので`()`の量を減らせる場合があります。 -```erg +```python rand = -1.0..1.0 |>.sample!() log rand # 0.2597... diff --git a/doc/JA/syntax/32_integration_with_Python.md b/doc/JA/syntax/32_integration_with_Python.md index 3d3b388a..473d4334 100644 --- a/doc/JA/syntax/32_integration_with_Python.md +++ b/doc/JA/syntax/32_integration_with_Python.md @@ -5,7 +5,7 @@ Ergスクリプトをコンパイルすると.pycファイルが生成されますが、これは単純にPythonのモジュールとして読み込むことができます。 ただし、Erg側で非公開に設定した変数はPythonからアクセスできません。 -```erg +```python # foo.er .public = "this is a public variable" private = "this is a private variable" @@ -30,7 +30,7 @@ Pythonから取り込んだオブジェクトはデフォルトですべて`Obje Python標準ライブラリにあるAPIはすべてErg開発チームにより型が指定されています。 -```erg +```python time = pyimport "time" time.sleep! 1 ``` @@ -49,7 +49,7 @@ def baz(): ... ``` -```erg +```python # foo.d.er foo = pyimport "foo" .X = declare foo.'X', Int @@ -57,14 +57,14 @@ foo = pyimport "foo" .baz! = declare foo.'baz', () => Int ``` -```erg +```python foo = pyimport "foo" assert foo.bar(1) in Int ``` これは、実行時に型チェックを行うことで型安全性を担保しています。`declare`関数は概ね以下のように動作します。 -```erg +```python declare|S: Subroutine| sub!: S, T = # 実は、=>はブロックの副作用がなければ関数にキャストできる x => diff --git a/doc/JA/syntax/33_package_system.md b/doc/JA/syntax/33_package_system.md index 8ae76114..79a1229e 100644 --- a/doc/JA/syntax/33_package_system.md +++ b/doc/JA/syntax/33_package_system.md @@ -25,7 +25,7 @@ libパッケージのエントリポイントは`src/lib.er`です。パッケ `foo`モジュールはファイルからなるモジュールで、`bar`モジュールはディレクトリからなるモジュールです。`bar`モジュールはさらに`baz`, `qux`モジュールを内部に持ちます。 このモジュールは単に`bar`モジュールの属性であり、`app.er`からは以下のようにアクセスできます。 -```erg +```python # app.er foo = import "foo" bar = import "bar" @@ -47,7 +47,7 @@ main args = └─ foo.test.er ``` -```erg +```python # app.er foo = import "foo" @@ -66,14 +66,14 @@ main args = └─ qux.er ``` -```erg +```python # foo.er bar = import "bar" bar.qux bar.baz # AttributeError: module 'baz' is private ``` -```erg +```python # qux.er baz = import "baz" ``` diff --git a/doc/JA/syntax/34_generator.md b/doc/JA/syntax/34_generator.md index eee9b31c..8d883748 100644 --- a/doc/JA/syntax/34_generator.md +++ b/doc/JA/syntax/34_generator.md @@ -2,7 +2,7 @@ ジェネレータは、ブロック中で`yield!`プロシージャを使う特殊なプロシージャです。 -```erg +```python g!() = yield! 1 yield! 2 @@ -13,7 +13,7 @@ g!() = これは`return`と同じく渡された値を戻り値として返すものですが、その時点でのブロックの実行状態を保存し、もう一度呼び出された際に続きから実行するという特徴があります。 ジェネレータはプロシージャでありながらイテレータでもあります。Pythonのジェネレータはイテレータを生成する関数ですが、Ergは直接イテレートします。プロシージャ自体は一般に可変オブジェクトではありません(`!`が付かない)が、ジェネレータは実行ごとに自身の内容が変わる得るので可変オブジェクトです。 -```erg +```python # Generator! < Proc g!: Generator!((), Int) assert g!() == 1 @@ -23,7 +23,7 @@ assert g!() == 3 Pythonスタイルのジェネレータは以下のようにして定義できます。 -```erg +```python make_g() = () => yield! 1 yield! 2 diff --git a/doc/JA/syntax/container_ownership.md b/doc/JA/syntax/container_ownership.md index f48b4aa3..c464e579 100644 --- a/doc/JA/syntax/container_ownership.md +++ b/doc/JA/syntax/container_ownership.md @@ -2,7 +2,7 @@ `[]`は通常のメソッドとは異なっています。 -```erg +```python a = [!1, !2] a[0].inc!() assert a == [2, 2] @@ -13,7 +13,7 @@ assert a == [2, 2] よって、`[]`は実際には`.`と同じく特別な構文の一部です。Pythonとは違い、オーバーロードできません。 メソッドで`[]`の挙動を再現することもできません。 -```erg +```python C = Class {i = Int!} C.get(ref self) = self::i # TypeError: `self::i` is `Int!` (require ownership) but `get` doesn't own `self` @@ -33,7 +33,7 @@ own_do! C.new({i = 1}).steal(), i => i.inc!() また、`[]`は所有権を奪うこともできますが、その際に要素がシフトするわけではありません。 -```erg +```python a = [!1, !2] i = a[0] i.inc!() diff --git a/doc/JA/syntax/quick_tour.md b/doc/JA/syntax/quick_tour.md index 66ddbdd3..414803d2 100644 --- a/doc/JA/syntax/quick_tour.md +++ b/doc/JA/syntax/quick_tour.md @@ -10,7 +10,7 @@ 変数は`=`で定義します。Haskellと同じように、一度定義した変数は書き換えられません。ただし別のスコープではシャドーイングできます。 -```erg +```python i = 0 if True: i = 1 @@ -20,7 +20,7 @@ assert i == 0 大文字で始まるものは定数です。コンパイル時計算できるものだけが定数にできます。 また、定数は定義以降すべてのスコープで同一です。 -```erg +```python PI = 3.141592653589793 match random.random!(0..10): PI: @@ -32,7 +32,7 @@ match random.random!(0..10): Pythonと違い、変数の型のみを先に宣言することが可能です。 当然、宣言の型と実際に代入されるオブジェクトの型は互換していなくてはなりません。 -```erg +```python i: Int i = 10 ``` @@ -41,7 +41,7 @@ i = 10 Haskellと同じように定義できます。 -```erg +```python fib 0 = 0 fib 1 = 1 fib n = fib(n - 1) + fib(n - 2) @@ -49,7 +49,7 @@ fib n = fib(n - 1) + fib(n - 2) 無名関数は以下のように定義できます。 -```erg +```python i -> i + 1 assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4] ``` @@ -62,7 +62,7 @@ Erg独自の演算子は以下の通りです。 Ocamlの`ref`のようなものです。 -```erg +```python i = !0 i.update! x -> x + 1 assert i == 1 @@ -72,13 +72,13 @@ assert i == 1 副作用のあるサブルーチンはプロシージャと呼ばれ、`!`がついています。 -```erg +```python print! 1 # 1 ``` ## ジェネリック関数(多相関数) -```erg +```python id|T|(x: T): T = x id(1): Int id("a"): Str @@ -88,7 +88,7 @@ id("a"): Str ML系言語にあるレコード(あるいはJSのオブジェクトリテラル)に相当するものを利用できます。 -```erg +```python p = {x = 1; y = 2} ``` @@ -96,7 +96,7 @@ p = {x = 1; y = 2} Ergは可変オブジェクト(`!`演算子で可変化したオブジェクト)に所有権がついており、複数の場所から書き換えられません。 -```erg +```python i = !0 j = i assert j == 0 @@ -109,13 +109,13 @@ i # MoveError 変数の頭に`.`をつけると、その変数は公開変数となり、外部モジュールから参照できるようになります。 -```erg +```python # foo.er .x = 1 y = 1 ``` -```erg +```python foo = import "foo" assert foo.x == 1 foo.y # VisibilityError @@ -125,7 +125,7 @@ foo.y # VisibilityError ### 変数パターン -```erg +```python # basic assignment i = 1 # with type @@ -137,7 +137,7 @@ fn: Int -> Int = x -> x + 1 ### リテラルパターン -```erg +```python # if `i` cannot be determined to be 1 at compile time, TypeError occurs. # short hand of `_: {1} = i` 1 = i @@ -154,7 +154,7 @@ fib n: Nat = fib n-1 + fib n-2 ### 定数パターン -```erg +```python PI = 3.141592653589793 E = 2.718281828459045 num = PI @@ -166,7 +166,7 @@ name = match num: ### 破棄(ワイルドカード)パターン -```erg +```python _ = 1 _: Int = 1 right(_, r) = r @@ -176,7 +176,7 @@ right(_, r) = r 後述するタプル/配列/レコードパターンと組み合わせて使う。 -```erg +```python [i, ...j] = [1, 2, 3, 4] assert j == [2, 3, 4] first|T|(fst: T, ...rest: T) = fst @@ -185,7 +185,7 @@ assert first(1, 2, 3) == 1 ### タプルパターン -```erg +```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) # ネストしていないなら()を省略可能(1, 2は(1, 2)として扱われる) @@ -194,14 +194,14 @@ m, n = 1, 2 ### 配列パターン -```erg +```python length [] = 0 length [_, ...rest] = 1 + length rest ``` #### レコードパターン -```erg +```python {sin; cos; tan; ...} = import "math" {*} = import "math" # import all @@ -213,7 +213,7 @@ age = match person: ### データクラスパターン -```erg +```python Point = Inherit {x = Int; y = Int} p = Point::{x = 1; y = 2} Point::{x; y} = p @@ -221,7 +221,7 @@ Point::{x; y} = p ## 内包表記 -```erg +```python odds = [i | i <- 1..100; i % 2 == 0] ``` @@ -234,7 +234,7 @@ Ergでは多重・多段継承をサポートしていません。 Rustのトレイトと似ていますが、より本来の意味に近いもので、合成や分離ができ、属性とメソッドは対等に扱われます。 また、実装を伴いません。 -```erg +```python XY = Trait {x = Int; y = Int} Z = Trait {z = Int} XYZ = XY and Z @@ -254,13 +254,13 @@ Point. 述語式で型に制限をかけられます。 -```erg +```python Nat = {I: Int | I >= 0} ``` ## 値を含むパラメトリック型(依存型) -```erg +```python a: [Int; 3] b: [Int; 4] a + b: [Int; 7] diff --git a/doc/JA/syntax/type/01_type_system.md b/doc/JA/syntax/type/01_type_system.md index f8c07359..238af1bc 100644 --- a/doc/JA/syntax/type/01_type_system.md +++ b/doc/JA/syntax/type/01_type_system.md @@ -6,7 +6,7 @@ Ergの特徴的な点として、(通常の)変数、関数(サブルーチン)、型(カインド)の定義にあまり大きな構文上の違いがないというところがあります。すべて、通常の変数・関数定義の文法に従って定義されます。 -```erg +```python f i: Int = i + 1 f # f(1) # 2 @@ -64,7 +64,7 @@ Ergの配列(Array)はPythonでいうところのリストとなります。`[In > __Note__: `(Type; N)`は型であり値でもあるので、このような使い方もできます。 > -> ```erg +> ```python > Types = (Int, Str, Bool) > > for! Types, T => @@ -73,7 +73,7 @@ Ergの配列(Array)はPythonでいうところのリストとなります。`[In > a: Types = (1, "aaa", True) > ``` -```erg +```python pop|T, N|(l: [T; N]): ([T; N-1], T) = [...l, last] = l (l, last) @@ -86,7 +86,7 @@ lpop|T, N|(l: [T; N]): (T, [T; N-1]) = `!`の付く型はオブジェクトの内部構造書き換えを許可する型です。例えば`[T; !N]`クラスは動的配列となります。 `T`型オブジェクトから`T!`型オブジェクトを生成するには、単項演算子の`!`を使います。 -```erg +```python i: Int! = !1 i.update! i -> i + 1 assert i == 2 @@ -101,7 +101,7 @@ assert mut_arr == [1, 2, 3, 4] 型は以下のように定義します。 -```erg +```python Point2D = {.x = Int; .y = Int} ``` @@ -114,7 +114,7 @@ Point2D = {.x = Int; .y = Int} 以下は`+`(中置演算子)を要求する `Add`型の定義です。`R, O`はいわゆる型引数で、`Int`や`Str`など実装のある型(クラス)が入れられます。他の言語で型引数には特別な記法(ジェネリクス、テンプレートなど)が与えられていますが、Ergでは通常の引数と同じように定義できます。 なお型引数は型オブジェクト以外も使用できます。例えば配列型`[Int; 3]`は`Array Int, 3`の糖衣文法です。型の実装がかぶる場合、ユーザは明示的に選択しなくてはなりません。 -```erg +```python Add R = Trait { .AddO = Type .`_+_` = Self.(R) -> Self.AddO @@ -123,7 +123,7 @@ Add R = Trait { .`_+_`は Add.`_+_`の省略形です。前置演算子の.`+_`は`Num`型のメソッドです。 -```erg +```python Num = Add and Sub and Mul and Eq NumImpl = Patch Num NumImpl. @@ -133,7 +133,7 @@ NumImpl. 多相型は関数のように扱えます。`Mul Int, Str`などのように指定して単相化します(多くの場合は指定しなくても実引数で推論されます)。 -```erg +```python 1 + 1 `_+_` 1, 1 Nat.`_+_` 1, 1 @@ -145,7 +145,7 @@ Int.`_+_` 1, 1 これは、`Int <: Ratio`であるために`1`が`Ratio`にダウンキャストされるからです。 しかしこれはキャストされません。 -```erg +```python i = 1 if i: # TypeError: i: Int cannot cast to Bool, use Int.is_zero() instead. log "a" @@ -158,7 +158,7 @@ if i: # TypeError: i: Int cannot cast to Bool, use Int.is_zero() instead. Ergは静的ダックタイピングを採用しており、明示的に型を指定する必要は殆どありません。 -```erg +```python f x, y = x + y ``` @@ -167,7 +167,7 @@ f x, y = x + y `{0}`と`{1}`は`Int`や`Nat`などの部分型となる列挙型です。 列挙型などには名前を付けて要求/実装メソッドを付けられます。その型にアクセスできる名前空間では、要求を満たすオブジェクトは実装メソッドを使用できます。 -```erg +```python Binary = Patch {0, 1} Binary. # selfにはインスタンスが格納される。この例では0か1のどちらか。 @@ -184,7 +184,7 @@ Binary. 以降は`0.to_bool()`というコードが可能となります(もっとも`0 as Bool == False`がビルトインで定義されていますが)。 コード中に示されたように、実際に`self`を書き換える事のできる型の例を示します。 -```erg +```python Binary! = Patch {0, 1}! Binary!. switch! ref! self = match! self: @@ -198,7 +198,7 @@ print! b # => 0 ## 構造型(無名型) -```erg +```python Binary = {0, 1} ``` @@ -211,14 +211,14 @@ Binary = {0, 1} 下のような指定はできません。`Add`はそれぞれ別のものを指すと解釈されるからです。 例えば、`Int`と`Str`はともに`Add`だが、`Int`と`Str`の加算はできません。 -```erg +```python add l: Add, r: Add = l + r # TypeError: there is no implementation of `_+_`: |T, U <: Add| (T, U) -> ``` また、下の`A`, `B`は同じ型とはみなされません。しかし、型`O`は一致するとみなされます。 -```erg +```python ... |R1; R2; O; A <: Add(R1, O); B <: Add(R2, O)| ``` diff --git a/doc/JA/syntax/type/02_basic.md b/doc/JA/syntax/type/02_basic.md index 922b5a35..9eeefc1a 100644 --- a/doc/JA/syntax/type/02_basic.md +++ b/doc/JA/syntax/type/02_basic.md @@ -4,7 +4,7 @@ Ergでは以下のように`:`の後に変数の型を指定します。代入と同時に行うこともできます。 -```erg +```python i: Int # これから使う変数iはInt型であると宣言する i: Int = 1 j = 1 # type specification can be omitted @@ -12,7 +12,7 @@ j = 1 # type specification can be omitted 通常の式に対しても型指定することができます。 -```erg +```python i = 1: Int f([1, "a"]: [Int or Str]) ``` @@ -20,7 +20,7 @@ f([1, "a"]: [Int or Str]) 単純な変数代入の場合、ほとんどの型指定は省略可能です。 型指定は単純な変数よりもサブルーチンや型の定義時に役立ちます。 -```erg +```python # 引数の型指定 f x, y: Array Int = ... T X, Y: Array Int = ... @@ -28,20 +28,20 @@ T X, Y: Array Int = ... 上の場合、`x, y`は共に`Array Int`であることに注意して下さい。 -```erg +```python # 大文字変数の値は定数式でなくてはならない f X: Int = X ``` あるいは、型引数の情報が完全にいらない場合は`_`で省略することもできます。 -```erg +```python g v: [T; _] = ... ``` ただし、型指定の箇所で`_`を指定するとそれは`Object`を意味することに注意して下さい。 -```erg +```python f x: _, y: Int = x + y # TypeError: + is not implemented between Object and Int ``` @@ -52,7 +52,7 @@ Ergでは`:`(型宣言演算子)による型と式の関係指定の他に、`<: これも単純な変数の指定より、サブルーチンや型の定義時に使うことが多いです。 -```erg +```python # 引数の部分型指定 f X <: T = ... @@ -66,7 +66,7 @@ Iterable T = Trait { また、クラス定義時に部分型指定を行うと、クラスが指定した型のサブタイプか静的に検査できます。 -```erg +```python # クラスCはShowのサブタイプ C = Class Object, Impl=Show C.show self = ... # Showの要求属性 @@ -74,7 +74,7 @@ C.show self = ... # Showの要求属性 特定の場合だけ部分型指定することもできます。 -```erg +```python K T: Eq K Int <: Show and Eq K T = Class Object @@ -87,7 +87,7 @@ K(Int). 構造型を実装する際は、部分型指定を行うことを推奨します。 構造的部分型付けの特性から、要求属性の実装をする際にタイポや型指定の間違いがあってもエラーが出ないためです。 -```erg +```python C = Class Object C.shoe self = ... # TypoのせいでShowが実装できていない(単なる固有のメソッドとみなされる) ``` @@ -96,7 +96,7 @@ C.shoe self = ... # TypoのせいでShowが実装できていない(単なる固 トレイトやクラスには、モジュール内でのみ属性を定義できます。 -```erg +```python C = Class() C.pub_attr = "this is public" C::private_attr = "this is private" @@ -107,7 +107,7 @@ assert c.pub_attr == "this is public" `C.`か`C::`のあとに改行してインデント以下にまとめて定義する文法を一括定義(batch definition)といいます。 -```erg +```python C = Class() C.pub1 = ... C.pub2 = ... @@ -127,7 +127,7 @@ C:: 型には別名(エイリアス)を付けることができます。これにより、レコード型など長い型を短く表現できます。 -```erg +```python Id = Int Point3D = {x = Int; y = Int; z = Int} IorS = Int or Str @@ -140,7 +140,7 @@ Vector = Array Int これは、違う目的の型は別々の型として新しく定義するべき、ということです。 また、すでにエイリアスのある型に重ねてエイリアスを付けることを防ぐ目的もあります。 -```erg +```python Id = Int UserId = Int # TypeWarning: duplicate aliases: Id and UserId diff --git a/doc/JA/syntax/type/03_trait.md b/doc/JA/syntax/type/03_trait.md index 5b234c07..8f794755 100644 --- a/doc/JA/syntax/type/03_trait.md +++ b/doc/JA/syntax/type/03_trait.md @@ -3,7 +3,7 @@ トレイトは、レコード型に型属性の要求を追加した記名型です。 Pythonでいう抽象基底クラス(Abstract Base Class, ABC)に類似しますが、代数的演算を行えるという特徴があります。 -```erg +```python Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int} ``` @@ -12,7 +12,7 @@ Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int} トレイトは宣言ができるのみで実装を持てないことに注意してください(実装は後に述べるパッチという機能で実現します)。 トレイトは部分型指定でクラスに実装されているかチェックできます。 -```erg +```python Point2D <: Norm Point2D = Class {.x = Int; .y = Int} Point2D.norm self = self.x**2 + self.y**2 @@ -20,14 +20,14 @@ Point2D.norm self = self.x**2 + self.y**2 要求属性を実装していないとエラーになります。 -```erg +```python Point2D <: Norm # TypeError: Point2D is not a subtype of Norm Point2D = Class {.x = Int; .y = Int} ``` トレイトは構造型と同じく合成、置換、排除などの演算を適用できます(e.g. `T and U`)。このようにしてできたトレイトをインスタントトレイトと呼びます。 -```erg +```python T = Trait {.x = Int} U = Trait {.y = Int} V = Trait {.x = Int; y: Int} @@ -40,7 +40,7 @@ assert Structural(W) == Structural(T.replace {.x = Ratio}) トレイトは型でもあるので、通常の型指定にも使えます。 -```erg +```python points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)] assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25] ``` @@ -51,7 +51,7 @@ assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25] 下の例でいうと、`BinAddSub`は`BinAdd`と`BinSub`を包摂しています。 これはクラスにおける継承(Inheritance)に対応しますが、継承と違い複数の基底型を`and`で合成して指定できます。`not`によって一部を除外したトレイトでもOKです。 -```erg +```python Add R = Trait { .AddO = Type .`_+_` = Self.(R) -> Self.AddO @@ -69,7 +69,7 @@ ClosedAddSub = Subsume ClosedAdd and ClosedSub トレイトは構造化できます。 -```erg +```python SAdd = Structural Trait { .`_+_` = Self.(Self) -> Self } @@ -87,7 +87,7 @@ assert add(C.new(1), C.new(2)) == C.new(3) 記名的トレイトは単に要求メソッドを実装しただけでは使えず、実装したことを明示的に宣言する必要があります。 以下の例では明示的な実装の宣言がないため、`add`が`C`型の引数で使えません。`C = Class {i = Int}, Impl := Add`としなくてはならないのです。 -```erg +```python Add = Trait { .`_+_` = Self.(Self) -> Self } @@ -109,7 +109,7 @@ add C.new(1), C.new(2) # TypeError: C is not subclass of Add トレイトは引数を取ることができます。これは依存型と同じです。 -```erg +```python Mapper T: Type = Trait { .MapIter = {Iterator} .map = Self(T).(T -> U) -> Self.MapIter U @@ -127,7 +127,7 @@ assert [1, 2, 3].iter().map(x -> "{x}").collect(Array) == ["1", "2", "3"] 派生トレイトでは基底トレイトの型定義をオーバーライドできます。 この場合、オーバーライドするメソッドの型は、基底メソッドの型の部分型でなければなりません。 -```erg +```python # `Self.(R) -> O`は`Self.(R) -> O or Panic`の部分型 Div R, O: Type = Trait { .`/` = Self.(R) -> O or Panic @@ -142,7 +142,7 @@ SafeDiv R, O = Subsume Div, { 実際の`Add`, `Sub`, `Mul`の定義はこのようになっています。 -```erg +```python Add R = Trait { .Output = Type .`_+_` = Self.(R) -> .Output @@ -159,7 +159,7 @@ Mul R = Trait { `.Output`という変数の名前が重複しています。これら複数のトレイトを同時に実装したい場合、以下のように指定します。 -```erg +```python P = Class {.x = Int; .y = Int} # P|Self <: Add(P)|はP|<: Add(P)|に省略可能 P|Self <: Add(P)|. @@ -172,7 +172,7 @@ P|Self <: Mul(Int)|. このようにして実装した重複のあるAPIは、使用時は殆どの場合型推論されますが、`||`で明示的に型指定することで解決もできます。 -```erg +```python print! P.Output # TypeError: ambiguous type resolution print! P|<: Mul(Int)|.Output # ``` diff --git a/doc/JA/syntax/type/04_class.md b/doc/JA/syntax/type/04_class.md index cbd1464a..7eff7f0d 100644 --- a/doc/JA/syntax/type/04_class.md +++ b/doc/JA/syntax/type/04_class.md @@ -3,7 +3,7 @@ Ergにおけるクラスは、大まかには自身の要素(インスタンス)を生成できる型と言えます。 以下は単純なクラスの例です。 -```erg +```python Person = Class {.name = Str; .age = Nat} # .newが定義されなかった場合、自動で`Person.new = Person::__new__`となります Person. @@ -22,7 +22,7 @@ print! classof(john) # Person 以下のように改行せず定義すると文法エラーになるので注意してください。 -```erg +```python Person.new name, age = ... # SyntaxError: cannot define attributes directly on an object ``` @@ -39,7 +39,7 @@ class Person: age: int ``` -```erg +```python # Ergでこの書き方はクラス属性の宣言を意味する(インスタンス属性ではない) Person = Class() Person. @@ -47,7 +47,7 @@ Person. age: Int ``` -```erg +```python # 上のPythonコードに対応するErgコード Person = Class { .name = Str @@ -61,7 +61,7 @@ Person = Class { 下の例で説明する。`species`という属性は全てのインスタンスで共通なので、クラス属性とした方が自然である。だが`name`という属性は各インスタンスが個々に持っておくべきなのでインスタンス属性とすべきなのである。 -```erg +```python Person = Class {name = Str} Person:: species = "human" @@ -85,7 +85,7 @@ alice.greet() # Hello, My name is Alice. 因みに、インスタンス属性と型属性で同名、同型のものが存在する場合、コンパイルエラーとなる。これは混乱を避けるためである。 -```erg +```python C = Class {.i = Int} C. i = 1 # AttributeError: `.i` is already defined in instance fields @@ -104,7 +104,7 @@ Ergではクラスメソッドを追加したりはできませんが、[パッ 既存のクラスを継承することも出来ます([Inheritable](./../27_decorator.md/#inheritable)クラスの場合)。 `Inherit`は継承を意味します。左辺の型を派生クラス、右辺の`Inherit`の引数型を基底クラスと言います。 -```erg +```python MyStr = Inherit Str # other: StrとしておけばMyStrでもOK MyStr. @@ -119,7 +119,7 @@ Pythonと違い、定義されたErgのクラスはデフォルトで`final`(継 継承可能にするためには`Inheritable`デコレータをクラスに付ける必要があります。 `Str`は継承可能クラスのひとつです。 -```erg +```python MyStr = Inherit Str # OK MyStr2 = Inherit MyStr # NG @@ -133,7 +133,7 @@ MyStr3 = Inherit InheritableMyStr # OK クラスは型とは同値判定の仕組みが異なります。 型は構造に基づいて同値性が判定されます。 -```erg +```python Person = {.name = Str; .age = Nat} Human = {.name = Str; .age = Nat} @@ -142,7 +142,7 @@ assert Person == Human クラスは同値関係が定義されていません。 -```erg +```python Person = Class {.name = Str; .age = Nat} Human = Class {.name = Str; .age = Nat} @@ -153,7 +153,7 @@ Person == Human # TypeError: cannot compare classes クラスは自身の要素を生成することができる型といいましたが、それだけは厳密な説明ではありません。実際はレコード型+パッチでも同じことができるからです。 -```erg +```python Person = {.name = Str; .age = Nat} PersonImpl = Patch Person PersonImpl. @@ -176,7 +176,7 @@ john = Person.new("John Smith", 25) ErgではクラスでNSTを実現します。NSTの利点として、堅牢性などが挙げられます。 大規模なプログラムを書いていると、オブジェクトの構造が偶然一致することはままあります。 -```erg +```python Dog = {.name = Str; .age = Nat} DogImpl = Patch Dog DogImpl. @@ -194,7 +194,7 @@ john.bark() # "Yelp!" `Dog`と`Person`の構造は全く同一ですが、動物が挨拶したり人間が吠えたりできるようにするのは明らかにナンセンスです。 後者はともかく、前者は不可能なので適用できないようにする方が安全です。このような場合はクラスを使用すると良いでしょう。 -```erg +```python Dog = Class {.name = Str; .age = Nat} Dog. bark = log "Yelp!" @@ -211,7 +211,7 @@ john.bark() # TypeError: `Person` object has no method `.bark` つまり、`T.x`, `T.bar`は`{i = Int}`と互換性のある型がアクセスできる(コンパイル時に結びつける)オブジェクトであり、`{i = Int}`や`C`に定義されているわけではありません。 対してクラス属性はクラス自身が保持しています。なので、構造が同じであっても継承関係にないクラスからはアクセスできません。 -```erg +```python C = Class {i = Int} C. foo self = ... @@ -237,7 +237,7 @@ print! C.new({i = 1}).bar # データクラスはレコードの機能を受け継いでおり、分解代入ができる、`==`や`hash`がデフォルトで実装されているなどの特徴があります。 逆に独自の同値関係やフォーマット表示を定義したい場合は通常のクラスを使用するとよいでしょう。 -```erg +```python C = Class {i = Int} c = C.new {i = 1} d = C.new {i = 2} @@ -255,7 +255,7 @@ assert e != f Or型のクラスを定義しやすくするために、`Enum`が用意されています。 -```erg +```python X = Class() Y = Class() XorY = Enum X, Y @@ -264,7 +264,7 @@ XorY = Enum X, Y それぞれの型には`XorY.X`, `XorY.Y`のようにしてアクセスでき、コンストラクタは`XorY.cons(X)`のようにして取得できます。 `.cons`はクラスを受け取ってそのコンストラクタを返すメソッドです。 -```erg +```python x1 = XorY.new X.new() x2 = XorY.cons(X)() assert x1 == x2 @@ -274,7 +274,7 @@ assert x1 == x2 クラスは、要件型のサブタイプです。要件型のメソッド(パッチメソッド含む)を使用できます。 -```erg +```python T = Trait {.foo = Foo} C = Class(..., Impl: T) C. diff --git a/doc/JA/syntax/type/05_inheritance.md b/doc/JA/syntax/type/05_inheritance.md index 82c2c6b8..eab04bd0 100644 --- a/doc/JA/syntax/type/05_inheritance.md +++ b/doc/JA/syntax/type/05_inheritance.md @@ -3,7 +3,7 @@ 継承を使うと、既存のクラスに機能を加えたり特化したりした新しいクラスを定義できます。 継承はトレイトにおける包摂に似ています。継承してできたクラスは、もとのクラスのサブタイプになります。 -```erg +```python NewInt = Inherit Int NewInt. plus1 self = self + 1 @@ -16,7 +16,7 @@ assert NewInt.new(1) + NewInt.new(1) == 2 オプション引数`additional`を指定すると追加のインスタンス属性を持つことができます。ただし値クラスの場合はインスタンス属性を追加できません。 -```erg +```python @Inheritable Person = Class {name = Str} Student = Inherit Person, additional: {id = Int} @@ -34,7 +34,7 @@ Ergでは例外的に`Never`型の継承はできない設計となっている [Or型](./13_algebraic.md)をクラス化した列挙クラスも継承ができます。この際、オプション引数`Excluding`を指定することで選択肢のどれか(`or`で複数選択可)を外せます。 なお追加はできません。選択肢を追加したクラスは、元のクラスのサブタイプとはならないからです。 -```erg +```python Number = Class Int or Float or Complex Number. abs(self): Float = @@ -49,7 +49,7 @@ RealNumber = Inherit Number, Excluding: Complex 同様に、[篩型](./12_refinement.md)も指定できます。 -```erg +```python Months = Class 0..12 MonthsNot31Days = Inherit Months, Excluding: {1, 3, 5, 7, 8, 10, 12} @@ -74,7 +74,7 @@ StrMoreThan4 = Inherit StrMoreThan3, Excluding: StrWithLen N | N == 3 最後に、3つ目の条件について考えます。この条件はErg特有で、他のオブジェクト指向言語ではあまり見られないものですが、これも安全のためです。これがなかったとき、どんなまずいことが起こりうるか見てみましょう。 -```erg +```python # Bad example @Inheritable Base! = Class {x = Int!} @@ -95,7 +95,7 @@ Inherited!. なので、オーバーライドの影響を受ける可能性のあるメソッドは一般に全て書き直す必要があるわけです。Ergはこのルールを仕様に組み込んでいます。 -```erg +```python # OK @Inheritable Base! = Class {x = Int!} @@ -124,7 +124,7 @@ Inherited!. 例えば`Real`(`Add()`を実装する)のサブタイプである`Int`では`Add()`を再実装しているようにみえます。 -```erg +```python Int = Class ..., Impl := Add() and ... ``` @@ -135,13 +135,13 @@ Int = Class ..., Impl := Add() and ... Ergでは通常のクラス同士でIntersection(交差), Diff(除外), Complement(否定)が行えません。 -```erg +```python Int and Str # TypeError: cannot unite classes ``` このルールにより、複数のクラスを継承すること、すなわち多重継承が行えません。 -```erg +```python IntAndStr = Inherit Int and Str # SyntaxError: multiple inheritance of classes is not allowed ``` @@ -161,7 +161,7 @@ Ergでは継承元の属性を書き換えることができません。これ オーバーライドはより特化したメソッドで上書きする操作であるため書き換えとは異なります。オーバーライドの際も互換性のある型で置き換えなくてはなりません。 -```erg +```python @Inheritable Base! = Class {.pub = !Int; pri = !Int} Base!. @@ -180,7 +180,7 @@ Inherited!. 2つ目は、継承元の(可変)インスタンス属性に対する更新操作です。これも禁止されています。基底クラスのインスタンス属性は、基底クラスの用意したメソッドからのみ更新できます。 属性の可視性にかかわらず、直接更新はできません。ただし読み取りはできます。 -```erg +```python @Inheritable Base! = Class {.pub = !Int; pri = !Int} Base!. @@ -209,7 +209,7 @@ Ergが多重継承、多層継承を禁止したのはこの危険性を低減 Ergはサブタイプ判定の一部を型システムが自動で判定してくれます(e.g. 0以上のIntであるところのNat)。 しかし例えば、「有効なメールアドレスを表す文字列型」をErgの型システムのみに頼って作成することは困難です。通常の文字列にバリデーションを行うべきでしょう。そして、バリデーションが通った文字列オブジェクトには何らかの「保証書」を付加したいところです。それが継承クラスへのダウンキャストに相当するわけです。`Strオブジェクト`を`ValidMailAddressStr`にダウンキャストすることは、文字列が正しいメールアドレスの形式であるか検証することと一対一対応します。 -```erg +```python ValidMailAddressStr = Inherit Str ValidMailAddressStr. init s: Str = @@ -229,7 +229,7 @@ valid: ValidMailAddressStr # assurance that it is in the correct email address f こうすれば、引数として受け付けるのは`Person`オブジェクトとそれを継承したクラス、`Student`オブジェクトのみです。 この方が保守的で、不必要に多くの責任を負う必要がなくなります。 -```erg +```python Named = {name = Str; ...} Dog = Class {name = Str; breed = Str} Person = Class {name = Str} diff --git a/doc/JA/syntax/type/06_nst_vs_sst.md b/doc/JA/syntax/type/06_nst_vs_sst.md index 4884f630..20e23b39 100644 --- a/doc/JA/syntax/type/06_nst_vs_sst.md +++ b/doc/JA/syntax/type/06_nst_vs_sst.md @@ -1,6 +1,6 @@ # 記名的部分型 vs. 構造的部分型 -```erg +```python Months = 0..12 # NST diff --git a/doc/JA/syntax/type/07_patch.md b/doc/JA/syntax/type/07_patch.md index f79c7f53..a535d769 100644 --- a/doc/JA/syntax/type/07_patch.md +++ b/doc/JA/syntax/type/07_patch.md @@ -4,7 +4,7 @@ Ergでは、既存の型・クラスに手を加えることはできません クラスにメソッドを追加で定義することはできず、特殊化(specialization, 多相に宣言された型を単相化し専用のメソッドを定義する機能。C++などが持つ)も行えません。 しかし、既存の型・クラスに機能を追加したいという状況は多々あり、これを実現するためにパッチという機能があります。 -```erg +```python StrReverse = Patch Str StrReverse. reverse self = self.iter().rev().collect(Str) @@ -18,7 +18,7 @@ assert "abc".reverse() == "cba" ただし、パッチのメソッドは記名型(クラス)のメソッドより優先度が低く、既存のクラスのメソッドをオーバーライド(上書き)できません。 -```erg +```python StrangeInt = Patch Int StrangeInt. `_+_` = Int.`_-_` # AssignError: .`_+_` is already defined in Int @@ -28,7 +28,7 @@ StrangeInt. ただし、基本的にはオーバーライドを行わず、別の名前のメソッドを定義することを推奨します。 オーバーライドは安全のためいくつかの制約が課されており、それほど気軽に行えるものではないからです。 -```erg +```python StrangeInt = Inherit Int StrangeInt. # オーバーライドするメソッドにはOverrideデコレータを付与する必要がある @@ -41,7 +41,7 @@ StrangeInt. パッチは一つの型に対して複数定義し、まとめることもできます。 -```erg +```python # foo.er StrReverse = Patch(Str) @@ -60,7 +60,7 @@ StrToKebabCase. StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase ``` -```erg +```python {StrBoosterPack; ...} = import "foo" assert "abc".reverse() == "cba" @@ -71,7 +71,7 @@ assert "to kebab case".to_kebab_case() == "to-kebab-case" 複数のパッチが定義できると、中には実装の重複が発生する可能性があります。 -```erg +```python # foo.er StrReverse = Patch(Str) @@ -87,13 +87,13 @@ StrReverseMk2. そのような場合は、メソッド形式ではなく関連関数形式とすることで一意化できます。 -```erg +```python assert StrReverseMk2.reverse("hello") == "olleh" ``` また、選択的にインポートすることでも一意化できます。 -```erg +```python {StrReverseMk2; ...} = import "foo" assert StrReverseMk2.reverse("hello") == "olleh" @@ -105,7 +105,7 @@ assert StrReverseMk2.reverse("hello") == "olleh" このようなパッチは接着パッチ(Glue Patch)と呼ばれます。 `Str`は組み込みの型であるため、ユーザーがトレイトを後付けするためには接着パッチが必要なわけです。 -```erg +```python Reverse = Trait { .reverse = Self.() -> Self } @@ -120,7 +120,7 @@ StrReverse. これは、仮に複数の接着パッチが同時に「見える」場合、どの実装を選択するか一意に決められなくなるからです。 ただし、別のスコープ(モジュール)に移る際にパッチを入れ替えることはできます。 -```erg +```python NumericStr = Inherit Str NumericStr. ... @@ -151,7 +151,7 @@ impl Reverse for String { RustのトレイトはErgのトレイトとパッチの機能を併せ持つ機能だと言えるでしょう。こう言うとRustのトレイトの方が便利に聞こえますが、実はそうとも限りません。 -```erg +```python # Erg Reverse = Trait { .reverse = Self.() -> Self @@ -166,7 +166,7 @@ StrReverse. Ergではimplブロックがパッチとしてオブジェクト化されているため、他のモジュールから取り込む際に選択的な取り込みが可能になります。さらに副次的な効果として、外部構造体への外部トレイトの実装も可能となっています。 また、dyn traitやimpl traitといった文法も構造型によって必要なくなります。 -```erg +```python # Erg reversible: [Reverse; 2] = [[1, 2, 3], "hello"] @@ -188,7 +188,7 @@ fn iter(i: I) -> impl Iterator where I: IntoIterator { この場合、自由度を与えたい項を引数にします(下の場合は`T: Type`)。このようにして定義したパッチを全称パッチといいます。 見れば分かる通り、全称パッチは正確にはパッチを返す関数ですが、それ自体もパッチとみなすことが可能です。 -```erg +```python FnType T: Type = Patch(T -> T) FnType(T). type = T @@ -203,7 +203,7 @@ assert (Int -> Int).type == Int 以下のように拡張によって成り立たなくなる性質もあるので、構造的パッチを定義する際は慎重に設計してください。 -```erg +```python # これはStructuralにするべきではない Norm = Structural Patch {x = Int; y = Int} Norm. diff --git a/doc/JA/syntax/type/08_value.md b/doc/JA/syntax/type/08_value.md index 2e2fb77c..ae81cd95 100644 --- a/doc/JA/syntax/type/08_value.md +++ b/doc/JA/syntax/type/08_value.md @@ -2,7 +2,7 @@ 値型はErg組み込み型のうちコンパイル時評価が可能な型で、具体的には以下のものです。 -```erg +```python Value = ( Int or Nat @@ -23,7 +23,7 @@ Value = ( 値型のオブジェクト・定数、およびそれにコンパイル時サブルーチンを適用したものを定数式と呼びます。 -```erg +```python 1, 1.0, 1+2im, True, None, "aaa", [1, 2, 3], Fib(12) ``` diff --git a/doc/JA/syntax/type/10_interval.md b/doc/JA/syntax/type/10_interval.md index 38d308ba..75c489c5 100644 --- a/doc/JA/syntax/type/10_interval.md +++ b/doc/JA/syntax/type/10_interval.md @@ -2,7 +2,7 @@ `Range`オブジェクトの最も基本的な使い方は、イテレータとしての使用です。 -```erg +```python for! 0..9, i => print! i ``` @@ -11,7 +11,7 @@ Pythonと違い、末尾の数字は含まれることに注意してくださ しかし、`Range`オブジェクトの使い道はこれだけではありません。型としても使うことが出来ます。このような型を区間型(Interval type)と呼びます。 -```erg +```python i: 0..10 = 2 ``` @@ -21,7 +21,7 @@ i: 0..10 = 2 イテレータとしても使えるため、`10..0`などのように逆順で指定することも出来ますが、 `<..`, `..<`, `<..<`の向きは逆転できません。 -```erg +```python a = 0..10 # OK b = 0..<10 # OK c = 10..0 # OK @@ -32,6 +32,6 @@ f = 10<..<0 # Syntax error 範囲演算子(range operator)は、`Ord`な不変型であるならば数値以外の型にも使用できます。 -```erg +```python Alphabet = "A".."z" ``` diff --git a/doc/JA/syntax/type/11_enum.md b/doc/JA/syntax/type/11_enum.md index bb040c5d..b82dcdc9 100644 --- a/doc/JA/syntax/type/11_enum.md +++ b/doc/JA/syntax/type/11_enum.md @@ -4,14 +4,14 @@ 列挙型はそのままでも型指定で使えますが、クラス化したりパッチを定義することで更にメソッドを定義できます。 列挙型による部分型システムを列挙的部分型付けといいます。 -```erg +```python Bool = {True, False} Status = {"ok", "error"} ``` `1..7`は`{1, 2, 3, 4, 5, 6, 7}`と書き換えられるので、要素が有限の場合は本質的に列挙型と区間型は等価です。 -```erg +```python Binary! = Class {0, 1}!. invert! ref! self = if! self == 0: @@ -31,7 +31,7 @@ b.invert!() enum Status { Ok, Error } ``` -```erg +```python # Erg Status = {"Ok", "Error"} ``` @@ -52,7 +52,7 @@ impl ExtraStatus { } ``` -```erg +```python # Status > ExtraStatusであり、Statusの要素はExtraStatusのメソッドを使える Status = Trait {"Ok", "Error"} # ... @@ -64,7 +64,7 @@ patchingによってメソッドの追加もできます。 明示的に包含関係を示したい場合、または既存のEnum型に選択肢を追加したい場合は`or`演算子を使います。 -```erg +```python ExtraStatus = Status or {"Unknown"} ``` @@ -72,7 +72,7 @@ ExtraStatus = Status or {"Unknown"} デフォルトでは、等質な列挙型を要件型とするクラスは、要素が属しているクラスのサブクラスとして扱えます。 あえてそうしたくない場合は、ラッパークラスとするとよいでしょう。 -```erg +```python Abc = Class {"A", "B", "C"} Abc.new("A").is_uppercase() diff --git a/doc/JA/syntax/type/12_refinement.md b/doc/JA/syntax/type/12_refinement.md index f87decec..b49d5774 100644 --- a/doc/JA/syntax/type/12_refinement.md +++ b/doc/JA/syntax/type/12_refinement.md @@ -5,7 +5,7 @@ Refinement type(篩型、ふるいがた)は、述語式によって制約付け 篩型の標準形は`{Elem: Type | (Pred)*}`です。これは、`Pred`を満たす`Elem`を要素とする型である、という意味です。 篩型に使えるのは[Const型](./advanced/const.md)のみです。 -```erg +```python Nat = 0.._ Odd = {N: Int | N % 2 == 1} Char = StrWithLen 1 @@ -22,7 +22,7 @@ Array3OrMore == {A: Array _, N | N >= 3} `Pred`は(左辺)述語式と呼ばれます。これは代入式と同じく意味のある値を返すものではなく、左辺にはパターンしか置けません。 すなわち、`X**2 - 5X + 6 == 0`のような式は篩型の述語式としては使えません。この点において、右辺式の述語式とは異なります。 -```erg +```python {X: Int | X**2 - 5X + 6 == 0} # SyntaxError: the predicate form is invalid. Only names can be on the left-hand side ``` @@ -34,14 +34,14 @@ Array3OrMore == {A: Array _, N | N >= 3} `Odd`を定義したのはいいですが、このままではリテラル以外ではあまり使えないようにみえます。通常の`Int`オブジェクトの中の奇数を`Odd`に昇格させる、つまり`Int`を`Odd`にダウンキャストするためには、`Odd`のコンストラクタを通す必要があります。 篩型の場合、通常のコンストラクタ`.new`はパニックする可能性があり、`.try_new`という`Result`型を返す補助的なコンストラクタもあります。 -```erg +```python i = Odd.new (0..10).sample!() i: Odd # or Panic ``` また、`match`中で型指定として使用することもできます。 -```erg +```python # i: 0..10 i = (0..10).sample!() match i: @@ -58,7 +58,7 @@ match i: 今まで紹介した列挙型と区間型は、篩型の糖衣構文です。 `{a, b, ...}`は`{I: Typeof(a) | I == a or I == b or ... }`に、`a..b`は`{I: Typeof(a) | I >= a and I <= b}`に脱糖されます。 -```erg +```python {1, 2} == {I: Int | I == 1 or I == 2} 1..10 == {I: Int | I >= 1 and I <= 10} 1..<10 == {I: Int | I >= 1 and I < 10} == {I: Int | I >= 1 and I <= 9} @@ -68,7 +68,7 @@ match i: `_: {X}`を`X`と書き換えられるように(定数パターン)、`_: {X: T | Pred}`は`X: T | Pred`と書き換えることができます。 -```erg +```python # メソッド.mは長さ3以上の配列に定義される Array(T, N | N >= 3) .m(&self) = ... diff --git a/doc/JA/syntax/type/13_algebraic.md b/doc/JA/syntax/type/13_algebraic.md index 99246287..51238f0d 100644 --- a/doc/JA/syntax/type/13_algebraic.md +++ b/doc/JA/syntax/type/13_algebraic.md @@ -9,7 +9,7 @@ Union型では型について複数の可能性を与える事ができる。名前の通り、`or`演算子で生成されます。 代表的なUnionは`Option`型です。`Option`型は`T or NoneType`のpatch typeで、主に失敗するかもしれない値を表現します。 -```erg +```python IntOrStr = Int or Str assert dict.get("some key") in (Int or NoneType) @@ -21,7 +21,7 @@ Option T = T or NoneType Intersection型は型同士を`and`演算で結合して得られます。 -```erg +```python Num = Add and Sub and Mul and Eq ``` @@ -32,7 +32,7 @@ Num = Add and Sub and Mul and Eq Diff型は`not`演算で得られます。 英文に近い表記としては`and not`とした方が良いですが、`and`, `or`と並べて収まりが良いので`not`だけで使うのが推奨されます。 -```erg +```python CompleteNum = Add and Sub and Mul and Div and Eq and Ord Num = CompleteNum not Div not Ord @@ -46,7 +46,7 @@ Complementは`not`演算で得られますが、これは単項演算です。`n `not T`型によるIntersectionはDiffと同等で、`not T`型によるDiffはIntersectionと同等です。 しかしこのような書き方は推奨されません。 -```erg +```python # the simplest definition of the non-zero number type NonZero = Not {0} # deprecated styles @@ -60,7 +60,7 @@ Bool == {True} not not {False} # 2 == 1 - -1 そうではない「見かけの代数型」には、Enum型やInterval型、レコード型の`or`や`and`があります。 これらは簡約が可能なので真の代数演算型ではなく、型指定に使うとWarningが出ます。Warningを消すためには簡約化するか型定義を行うかする必要があります。 -```erg +```python assert {1, 2, 3} or {2, 3} == {1, 2, 3} assert {1, 2, 3} and {2, 3} == {2, 3} assert -2..-1 or 1..2 == {-2, -1, 1, 2} @@ -76,7 +76,7 @@ q: Point2D = {x = 1; y = 2; z = 3} 真の代数演算型には、`Or`型、`And`型があります。クラス同士の`or`などは`Or`型です。 -```erg +```python assert Int or Str == Or(Int, Str) assert Int and Marker == And(Int, Marker) ``` diff --git a/doc/JA/syntax/type/14_dependent.md b/doc/JA/syntax/type/14_dependent.md index 754ae782..f8e4f6ae 100644 --- a/doc/JA/syntax/type/14_dependent.md +++ b/doc/JA/syntax/type/14_dependent.md @@ -6,7 +6,7 @@ 依存型は、`[T; N]`(`Array(T, N)`)などがそれに相当します。 この型は、中身の型`T`だけでなく、中身の個数`N`にも依存して決まる型です。`N`には`Nat`型のオブジェクトが入ります。 -```erg +```python a1 = [1, 2, 3] assert a1 in [Nat; 3] a2 = [4, 5, 6, 7] @@ -16,7 +16,7 @@ assert a1 + a2 in [Nat; 7] 関数引数で渡した型オブジェクトが戻り値型に関連する場合は、以下のように記述します。 -```erg +```python narray: |N: Nat| {N} -> [{N}; N] narray(N: Nat): [N; N] = [N; N] assert narray(3) == [3, 3, 3] @@ -26,7 +26,7 @@ assert narray(3) == [3, 3, 3] 依存型そのものは既存の言語にも存在するものですが、Ergでは依存型にプロシージャルメソッドを定義できるという特徴があります。 -```erg +```python x = 1 f x = print! f::x, module::x @@ -42,7 +42,7 @@ T(1).x() # 1 可変依存型の型引数はメソッドの適用によって遷移させることができます。 遷移指定は`~>`で行います。 -```erg +```python # `Id`は不変型なので遷移させることはできないことに注意 VM!(State: {"stopped", "running"}! := _, Id: Nat := _) = Class(..., Impl := Phantom! State) VM!(). @@ -66,7 +66,7 @@ vm.stop!() # TypeError: VM!(!"stopped", 1) doesn't have .stop!() 既存の型を組み込んだり継承して依存型を作ることもできます。 -```erg +```python MyArray(T, N) = Inherit [T; N] # .arrayと連動してself: Self(T, N)の型が変わる diff --git a/doc/JA/syntax/type/15_quantified.md b/doc/JA/syntax/type/15_quantified.md index 86bb9c6f..9a134bf3 100644 --- a/doc/JA/syntax/type/15_quantified.md +++ b/doc/JA/syntax/type/15_quantified.md @@ -3,14 +3,14 @@ 型変数はサブルーチン引数の型指定などに使用する変数で、その型が任意である(単相化しない)ことを示します。 まず、型変数を導入するモチベーションとして、入力をそのまま返す`id`関数について考えましょう。 -```erg +```python id x: Int = x ``` 入力をそのまま返す`id`関数が`Int`型に対して定義されていますが、この関数は明らかに任意の型に対して定義できます。 最大のクラスを表す`Object`を使用してみましょう。 -```erg +```python id x: Object = x i = id 1 @@ -21,7 +21,7 @@ b = id True 確かに任意の型を受け付けるようになりましたが、1つ問題があります。戻り値の型が`Object`に拡大されてしまうのです。 入力が`Int`型なら`Int`型、`Str`型なら`Str`型が返るようになっていてほしいですね。 -```erg +```python print! id 1 # id(1) + 1 # TypeError: cannot add `Object` and `Int` ``` @@ -29,7 +29,7 @@ id(1) + 1 # TypeError: cannot add `Object` and `Int` 入力の型と戻り値の型が同じであるようにするには、 __型変数__ を使います。 型変数は`||`(型変数リスト)中で宣言します。 -```erg +```python id|T: Type| x: T = x assert id(1) == 1 assert id("foo") == "foo" @@ -39,7 +39,7 @@ assert id(True) == True これを関数の __全称量化(全称化)__ と呼びます。細かい違いはありますが、他言語でジェネリクスと呼ばれる機能に相当します。そして全称量化された関数を __多相関数__ と呼びます。 多相関数の定義は、全ての型に対して同じ形の関数を定義するようなものです(Ergはオーバーロードを禁止しているので、下のコードは実際には書けません)。 -```erg +```python id|T: Type| x: T = x # pseudo code # == @@ -57,7 +57,7 @@ id x: NoneType = x また、任意の型では大きすぎる場合、制約を与えることも出来ます。 制約を与えることにはメリットもあり、例えばサブタイプ指定をすると、特定のメソッドを使えるようになります。 -```erg +```python # T <: Add # => TはAddのサブクラス # => 加算ができる @@ -69,7 +69,7 @@ add|T <: Add| l: T, r: T = l + r このような型付けもできます。 -```erg +```python f| Y, Z: Type X <: Add Y, O1 @@ -81,7 +81,7 @@ f| 注釈リストが長くなる場合は、事前宣言するとよいでしょう。 -```erg +```python f: |Y, Z: Type, X <: Add(Y, O1), O1 <: Add(Z, O2), O2 <: Add(X, O3)| (X, Y, Z) -> O3 f|X, Y, Z| x: X, y: Y, z: Z = x + y + z + x @@ -91,7 +91,7 @@ f|X, Y, Z| x: X, y: Y, z: Z = これは、型変数はすべて実引数から推論可能であるというErgの言語設計からの要求です。 なので、戻り値の型など推論ができない情報は、実引数から渡します。Ergは型を実引数から渡すことができるのです。 -```erg +```python Iterator T = Trait { # 戻り値の型を引数から渡している # .collect: |K: Type -> Type| Self(T).({K}) -> K(T) @@ -105,7 +105,7 @@ it.collect(Array) # [2, 3, 4] 型変数が宣言できるのは`||`の間のみである。ただし、宣言した後はスコープを抜けるまで任意の場所で使用できる。 -```erg +```python f|X|(x: X): () = y: X = x.clone() log X.__name__ @@ -118,14 +118,14 @@ f 1 以下のようにして、使用時に明示的に単相化もできます。 -```erg +```python f: Int -> Int = id|Int| ``` その場合、実引数の型よりも指定された型の方が優先されます(合致していないと実引数の型が間違っているという型エラーになる)。 すなわち、実際に渡されたオブジェクトが指定された型に変換可能ならば変換され、そうでなければコンパイルエラーとなります。 -```erg +```python assert id(1) == 1 assert id|Int|(1) in Int assert id|Ratio|(1) in Ratio @@ -136,14 +136,14 @@ id|Int|("str") # TypeError: id|Int| is type `Int -> Int` but got Str この文法が内包表記とバッティングする際は`()`で囲む必要があります。 -```erg +```python # {id|Int| x | x <- 1..10}だと{id | ...}だと解釈される {(id|Int| x) | x <- 1..10} ``` 既に存在する型と同名の型変数は宣言出来ません。これは、型変数がすべて定数であるためです。 -```erg +```python I: Type # ↓ invalid type variable, already exists f|I: Type| ... = ... @@ -153,7 +153,7 @@ f|I: Type| ... = ... 左辺における型引数はデフォルトで束縛型変数として扱われます。 -```erg +```python K(T: Type, N: Nat) = ... K(T, N). foo(x) = ... @@ -161,7 +161,7 @@ K(T, N). 別の型変数名を使用すると警告が出ます。 -```erg +```python K(T: Type, N: Nat) = ... K(U, M). # Warning: K's type variable names are 'T' and 'N' foo(x) = ... @@ -169,7 +169,7 @@ K(U, M). # Warning: K's type variable names are 'T' and 'N' 定数は定義以降すべての名前空間で同一なので、当然型変数名にも使用できません。 -```erg +```python N = 1 K(N: Nat) = ... # NameError: N is already defined @@ -184,7 +184,7 @@ L(M). 型引数ごとに多重定義することはできませんが、型引数を代入していない依存型(非原始カインド)と代入した依存型(原始カインド)は関係がないので同名のメソッドを定義できます。 -```erg +```python K(I: Int) = ... K. # Kは真の型(原子カインド)ではないので、メソッドを定義できない @@ -198,7 +198,7 @@ K(0). 前章で定義した`id`関数は任意の型になれる関数です。では、「`id`関数自体の型」は何なのでしょうか? -```erg +```python print! classof(id) # |T: Type| T -> T ``` @@ -208,7 +208,7 @@ print! classof(id) # |T: Type| T -> T 無名関数と同じく、多相関数型には型変数名の任意性がありますが、これらはすべて同値となります。 -```erg +```python assert (|T: Type| T -> T) == (|U: Type| U -> U) ``` @@ -223,14 +223,14 @@ assert (|T: Type| T -> T) == (|U: Type| U -> U) 開いた全称型は、同形な全ての「真の型」のスーパータイプになります。対して、閉じた全称型は、同形な全ての「真の型」のサブタイプになります。 -```erg +```python (|T: Type| T -> T) < (Int -> Int) < (T -> T) ``` 閉じている方が小さい/開いている方が大きい、と覚えるとよいでしょう。 しかし、どうしてそうなるのでしょうか。理解を深めるため、それぞれのインスタンスを考えてみます。 -```erg +```python # id: |T: Type| T -> T id|T|(x: T): T = x @@ -266,7 +266,7 @@ id_int_fn(f3: Int -> Int): (Int -> Int) = f Ergでは型自体も値であるため、引数を取る型、例えば関数型なども須らく依存型になります。つまり、多相関数型は全称型でかつ依存型でもあるといえます。 -```erg +```python PolyFn = Patch(|T| T -> T) PolyFn. type self = T # NameError: cannot find 'T' diff --git a/doc/JA/syntax/type/16_subtyping.md b/doc/JA/syntax/type/16_subtyping.md index d7f33f84..96d0e1ba 100644 --- a/doc/JA/syntax/type/16_subtyping.md +++ b/doc/JA/syntax/type/16_subtyping.md @@ -2,7 +2,7 @@ Ergでは、クラス同士の包含関係は比較演算子`<`, `>`で判定可能です。 -```erg +```python Nat < Int Int < Object 1.._ < Nat @@ -13,7 +13,7 @@ Int < Object `<:`演算子とは別の意味を持つことに注意してください。左辺のクラスが右辺の型のサブタイプであると宣言するもので、コンパイル時にのみ意味を持ちます。 -```erg +```python C <: T # T: StructuralType f|D <: E| ... @@ -26,7 +26,7 @@ assert F < G 構造型は構造的型付けを実現するための型であり、構造が同じならば同じオブジェクトとみなされます。 -```erg +```python T = Structural {i = Int} U = Structural {i = Int} @@ -38,7 +38,7 @@ assert t in U 対してクラスは記名的型付けを実現するための型であり、型およびインスタンスを構造的に比較することができません。 -```erg +```python C = Class {i = Int} D = Class {i = Int} @@ -54,7 +54,7 @@ assert not c in D すなわち、構造型やトレイトを関数の型として直接指定することはできない。 部分型指定を使って「その型のサブタイプである単一のクラス」として指定する必要がある。 -```erg +```python # OK f1 x, y: Int = x + y # NG @@ -68,7 +68,7 @@ f3 x, y: A = x + y ## クラスのアップキャスト -```erg +```python i: Int i as (Int or Str) i as (1..10) diff --git a/doc/JA/syntax/type/17_type_casting.md b/doc/JA/syntax/type/17_type_casting.md index 44cd1363..d30a919b 100644 --- a/doc/JA/syntax/type/17_type_casting.md +++ b/doc/JA/syntax/type/17_type_casting.md @@ -8,7 +8,7 @@ Pythonはダックタイピングを採用する言語のため、キャスト ~~Erg拡張バイトコードはBINARY_ADDに型情報を加えますが、この際の型情報はRatio-Ratioとなります。この場合はBINARY_ADD命令がIntのキャストを行うため、キャストを指定する特別な命令は挿入されません。なので、例えば子クラスでメソッドをオーバーライドしても、親を型に指定すれば型強制(type coercion)が行われ、親のメソッドで実行されます(コンパイル時に親のメソッドを参照するように名前修飾が行われます)。コンパイラが行うのは型強制の妥当性検証と名前修飾のみです。ランタイムがオブジェクトをキャストすることはありません(現在のところ。実行最適化のためにキャスト命令が実装される可能性はあります)。~~ -```erg +```python @Inheritable Parent = Class() Parent. @@ -31,7 +31,7 @@ greet! child # "Hello from Parent" この挙動はPythonとの非互換性を生むことはありません。そもそもPythonでは変数に型が指定されないので、いわば全ての変数が型変数で型付けされている状態となります。型変数は適合する最小の型を選ぶので、Ergで型を指定しなければPythonと同じ挙動が達成されます。 -```erg +```python @Inheritable Parent = Class() Parent. @@ -52,7 +52,7 @@ greet! child # "Hello from Child" 継承関係にある型同士では`.from`, `.into`が自動実装されるので、それを使うこともできます。 -```erg +```python assert 1 == 1.0 assert Ratio.from(1) == 1.0 assert 1.into() == 1.0 @@ -62,7 +62,7 @@ assert 1.into() == 1.0 ダウンキャストは一般に安全ではなく、変換方法も自明ではないため、代わりに`TryFrom.try_from`の実装で実現します。 -```erg +```python IntTryFromFloat = Patch Int IntTryFromFloat. try_from r: Float = diff --git a/doc/JA/syntax/type/18_mut.md b/doc/JA/syntax/type/18_mut.md index ec232cab..24c97a81 100644 --- a/doc/JA/syntax/type/18_mut.md +++ b/doc/JA/syntax/type/18_mut.md @@ -5,7 +5,7 @@ Ergではデフォルトですべての型が不変型、すなわち内部状態を更新できないようになっています。 しかし可変な型ももちろん定義できます。可変型は`!`を付けて宣言します。 -```erg +```python Person! = Class({name = Str; age = Nat!}) Person!. greet! ref! self = print! "Hello, my name is {self::name}. I am {self::age}." @@ -19,7 +19,7 @@ Person!. 可変型オブジェクトの破壊的操作は、主に`.update!`メソッドを介して行います。`.update!`メソッドは高階プロシージャで、`self`に関数`f`を適用して更新します。 -```erg +```python i = !1 i.update! old -> old + 1 assert i == 2 @@ -27,7 +27,7 @@ assert i == 2 `.set!`メソッドは単に古い内容を捨てて新しい値に差し替えます。`.set! x = .update! _ -> x`です。 -```erg +```python i = !1 i.set! 2 assert i == 2 @@ -35,14 +35,14 @@ assert i == 2 `.freeze_map`メソッドは値を不変化して操作を行います。 -```erg +```python a = [1, 2, 3].into [Nat; !3] x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(Array) ``` 多相不変型において型の型引数`T`は暗黙に不変型であると仮定されます。 -```erg +```python # ImmutType < Type K T: ImmutType = Class ... K! T: Type = Class ... @@ -53,7 +53,7 @@ K! T: Type = Class ... 注意として、オブジェクトの可変性にはいくつかの種類があります。 以下では組み込みのコレクション型について、その不変/可変型の意味を確認します。 -```erg +```python # 配列型 ## 不変型(immutable types) [T; N] # 可変操作は実行できない @@ -72,7 +72,7 @@ K! T: Type = Class ... これらの配列型は糖衣構文であり、実際の型は以下の通りです。 -```erg +```python # 実際は4種類の型 [T; N] = Array(T, N) [T; !N] = Array!(T, !N) @@ -85,7 +85,7 @@ K! T: Type = Class ... なお、型を変更可能とはこのような意味です。 -```erg +```python a = [1, 2, 3].into [!Nat; 3] a.map!(_ -> "a") a: [!Str; 3] @@ -93,7 +93,7 @@ a: [!Str; 3] 他のコレクション型についても同様です。 -```erg +```python # タプル型 ## 不変型(immutable types) (T, U) # 要素数不変、中身を変更できない @@ -103,7 +103,7 @@ a: [!Str; 3] ... ``` -```erg +```python # セット型 ## 不変型(immutable types) {T; N} # 不変要素数、中身を変更できない @@ -114,7 +114,7 @@ a: [!Str; 3] ... ``` -```erg +```python # 辞書型 ## 不変型(immutable types) {K: V} # 不変長、中身を変更できない @@ -124,7 +124,7 @@ a: [!Str; 3] ... ``` -```erg +```python # レコード型 ## 不変型(immutable types) {x = Int; y = Str} # 中身を変更できない @@ -137,7 +137,7 @@ a: [!Str; 3] `T = (...)`のとき単に`T! = (...)!`となる型`(...)`を単純構造型と呼びます。単純構造型は(意味論上)内部構造を持たない型ともいえます。 配列、タプル、セット、辞書、レコード型は全て単純構造型ではありませんが、Int型や篩型は単純構造型です。 -```erg +```python # 篩型 ## 列挙型 {1, 2, 3} # 1, 2, 3のうちどれか、変更できない diff --git a/doc/JA/syntax/type/19_bound.md b/doc/JA/syntax/type/19_bound.md index 3024ebc8..ea121878 100644 --- a/doc/JA/syntax/type/19_bound.md +++ b/doc/JA/syntax/type/19_bound.md @@ -9,7 +9,7 @@ 変数の満たす条件を、`Bool`を返す式(述語式)で指定できる。 使用できるのは[値オブジェクト](./08_value.md)と演算子だけである。コンパイル時関数は今後のバージョンで対応される可能性がある。 -```erg +```python f a: [T; N] | T, N, N > 5 = ... g a: [T; N | N > 5] | T, N = ... Odd = {I: Int | I % 2 == 1} diff --git a/doc/JA/syntax/type/advanced/GADTs.md b/doc/JA/syntax/type/advanced/GADTs.md index 2b8a8a7d..6a7d7958 100644 --- a/doc/JA/syntax/type/advanced/GADTs.md +++ b/doc/JA/syntax/type/advanced/GADTs.md @@ -2,7 +2,7 @@ ErgはOr型をクラス化することで一般化代数的データ型(GADTs)を作成出来ます。 -```erg +```python Nil T = Class(Impl := Phantom T) Cons T = Class {head = T; rest = List T}, Impl := Unpack List T: Type = Class(Nil T or Cons T) @@ -20,7 +20,7 @@ print! nil.head() # RuntimeError: "empty list" `List(T).nil() = ...`ではなく`List.nil|T|() = ...`としているのは、使用時に型指定が不要になるからです。 -```erg +```python i = List.nil() _: List Int = cons 1, i ``` @@ -28,7 +28,7 @@ _: List Int = cons 1, i ここで定義した`List T`はGADTsですが、素朴な実装であり、GADTsの真価を発揮していません。 例えば、上の`.head`メソッドはもし中身が空なら実行時エラーを出しますが、この検査はコンパイル時に行うことができます。 -```erg +```python List: (Type, {"Empty", "Nonempty"}) -> Type List T, "Empty" = Class(Impl := Phantom T) List T, "Nonempty" = Class {head = T; rest = List(T, _)}, Impl := Unpack @@ -46,7 +46,7 @@ print! nil().head() # TypeError 巷でよく説明されるGADTsの例は、以上のように中身が空か否か型で判定できるリストです。 Ergではさらに精密化して、長さを持つリストを定義できます。 -```erg +```python List: (Type, Nat) -> Type List T, 0 = Class(Impl := Phantom T) List T, N = Class {head = T; rest = List(T, N-1)}, Impl := Unpack diff --git a/doc/JA/syntax/type/advanced/_rank2type.md b/doc/JA/syntax/type/advanced/_rank2type.md index 79fdd3ae..e98cdc19 100644 --- a/doc/JA/syntax/type/advanced/_rank2type.md +++ b/doc/JA/syntax/type/advanced/_rank2type.md @@ -6,7 +6,7 @@ Ergでは`id|T|(x: T): T = x`などのように色々な型を受け取れる関 では、多相関数を受け取れる関数は定義できるだろうか? 例えば、このような関数である(この定義は誤りを含むことに注意してほしい)。 -```erg +```python # tuple_map(i -> i * 2, (1, "a")) == (2, "aa")になってほしい tuple_map|T|(f: T -> T, tup: (Int, Str)): (Int, Str) = (f(tup.0), f(tup.1)) ``` @@ -15,7 +15,7 @@ tuple_map|T|(f: T -> T, tup: (Int, Str)): (Int, Str) = (f(tup.0), f(tup.1)) 今まで説明してきた型の範疇では、このような関数の定義はできない。型変数にスコープの概念がないからである。 ここで一旦型を離れて、値レベルでのスコープの概念を確認する。 -```erg +```python arr = [1, 2, 3] arr.map i -> i + 1 ``` @@ -25,7 +25,7 @@ arr.map i -> i + 1 今までの型は、全ての型変数で生存期間が同一なのである。すなわち、`T`, `X`, `Y`は同時に決定されていて、以降は不変でなければならない。 逆に言えば、`T`を「内側のスコープ」にある型変数とみなすことができるならば`tuple_map`関数を構成できる。そのために用意されたのが、 __ランク2型__ である。 -```erg +```python # tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) tuple_map f: (|T: Type| T -> T), tup: (Int, Str) = (f(tup.0), f(tup.1)) assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa") @@ -34,7 +34,7 @@ assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa") `{(型) | (型変数のリスト)}`という形式の型を全称型といった(詳しくは[全称型](./../quantified.md)を参照)。 いままで見てきた`id`関数は、典型的な全称関数=多相関数である。 -```erg +```python id x = x id: |T: Type| T -> T ``` @@ -43,7 +43,7 @@ id: |T: Type| T -> T これについて、単純な1引数関数を使って考える。 -```erg +```python f1: (T -> T) -> Int | T # 任意の関数を受け取り、Intを返す関数 f2: (|T: Type| T -> T) -> Int # 多相関数を受け取り、Intを返す関数 f3: Int -> (|T: Type| T -> T) # Intを受け取り、閉じた全称型関数を返す関数 @@ -52,7 +52,7 @@ f4: |T: Type|(Int -> (T -> T)) # 上と同じ意味(こちらが推奨) `f3`と`f4`が同じなのに対して、`f1`と`f2`は異なるというのは奇妙に思える。実際にそのような型の関数を構成してみる。 -```erg +```python # id: |T: Type| T -> T id x = x # same type as `f1` @@ -67,7 +67,7 @@ take_i_and_return_arbit_f|T: Type|(_: Int): (T -> T) = id 適用してみると、その違いがわかってくる。 -```erg +```python _ = take_univq_f_and_return_i(x -> x, 1) # OK _ = take_univq_f_and_return_i(x: Int -> x, 1) # NG _ = take_univq_f_and_return_i(x: Str -> x, 1) # NG @@ -90,7 +90,7 @@ assert f2 == g2 ランクの定義だが、まず量化されていない型、すなわち`Int`, `Str`, `Bool`, `T`, `Int -> Int`, `Option Int`などは「ランク0」とされる。 -```erg +```python # KはOptionなどの多項カインド R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0) ``` @@ -99,7 +99,7 @@ R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0) さらに二階の全称量化が行われている型(`(|T| T -> T) -> Int`などランク1型を引数に持つ型)、またはそれらを戻り値型に含む型を「ランク2」とする。 以上を繰り返して「ランクN」型が定義される。また、ランクN型はN以下のランクの型をすべて含む。ゆえに、複数のランクが混在する型のランクは、その中で最も高いランクと同じになる。 -```erg +```python R1 = (|...| R0) or (R0 -> R1) or K(R1) or R0 R2 = (|...| R1) or (R1 -> R2) or K(R2) or R1 ... @@ -108,7 +108,7 @@ Rn = (|...| Rn-1) or (Rn-1 -> Rn) or K(Rn) or Rn-1 いくつか例をみてみよう。 -```erg +```python (|T: Type| T -> T) -> (|U: Type| U -> U) => R1 -> R1 => R1 -> R2 @@ -122,7 +122,7 @@ Option(|T: Type| T -> T) 定義より、`tuple_map`はランク2型である。 -```erg +```python tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) => (R1, R0) -> R0 @@ -133,7 +133,7 @@ tuple_map: Ergでは、ランク2までの型を扱うことができる(ランクN型はN以下のランクの型をすべて含むため、正確にいうとErgの型はすべてランク2型である)。それ以上の型の関数を構成しようとするとエラーになる。 例えば、多相関数を多相関数のまま扱う関数はすべて他の引数の型指定が必要である。また、このような関数は構成できない。 -```erg +```python # this is a rank-3 type function # |X, Y: Type|((|T: Type| T -> T), (X, Y)) -> (X, Y) generic_tuple_map|X, Y: Type| f: (|T: Type| T -> T), tup: (X, Y) = (f(tup.0), f(tup.1)) diff --git a/doc/JA/syntax/type/advanced/default_param.md b/doc/JA/syntax/type/advanced/default_param.md index e183cd97..48714c73 100644 --- a/doc/JA/syntax/type/advanced/default_param.md +++ b/doc/JA/syntax/type/advanced/default_param.md @@ -2,7 +2,7 @@ まず、デフォルト引数の使用例を見る。 -```erg +```python f: (Int, Int, z := Int) -> Int f(x, y, z := 0) = x + y + z @@ -19,7 +19,7 @@ assert fold(g, [1, 2, 3]) == 8 `:=`以降の引数はデフォルト引数である。 部分型付け規則は以下の通り。 -```erg +```python ((X, y := Y) -> Z) <: (X -> Z) ((X, y := Y, ...) -> Z) <: ((X, ...) -> Z) ``` diff --git a/doc/JA/syntax/type/advanced/erasure.md b/doc/JA/syntax/type/advanced/erasure.md index 08c0c66c..df15e071 100644 --- a/doc/JA/syntax/type/advanced/erasure.md +++ b/doc/JA/syntax/type/advanced/erasure.md @@ -6,7 +6,7 @@ しかし、型消去された型は、されていない型のスーパータイプになる(e.g. `[T; N] < [T; _]`)ため、より多くのオブジェクトを受け取れるようになります。 `[T; N]`型のオブジェクトはもちろん`[T; _]`型のメソッドを使用できますが、使用後`n`の情報は消去されます。長さが変わってしまっているかもしれないからです。長さが変わらないならばシグネチャで示さなくてはなりません。 -```erg +```python # 配列の長さが変わらないことが保証される関数(sortなど) f: [T; N] -> [T; N] # されない関数(filterなど) @@ -16,14 +16,14 @@ g: [T; n] -> [T; _] 型指定自体で`_`を使うとその型は`Object`までアップキャストされます。 型でない型引数(Int, Bool型など)の場合、`_`としたパラメータは未定義になります。 -```erg +```python i: _ # i: Object [_; _] == [Object; _] == Array ``` 型消去は型指定の省略とは違います。一度型引数情報を消去してしまうと、再びアサーションしなければ情報は戻りません。 -```erg +```python implicit = (1..5).iter().map(i -> i * 2).to_arr() explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat)) ``` @@ -36,7 +36,7 @@ let partial = (1..6).iter().map(|i| i * 2).collect::>(); Ergでは型の部分省略はできず、代わりに高階カインド多相を使用します。 -```erg +```python # collectはカインドを受け取る高階カインドのメソッド hk = (1..5).iter().map(i -> i * 2).collect(Array) hk: Array(Int) diff --git a/doc/JA/syntax/type/advanced/existential.md b/doc/JA/syntax/type/advanced/existential.md index 4e433516..fe346e93 100644 --- a/doc/JA/syntax/type/advanced/existential.md +++ b/doc/JA/syntax/type/advanced/existential.md @@ -3,7 +3,7 @@ ∀に対応する全称型があるならば、∃に対応する存在型があると考えるのが自然です。 存在型は難しいものではありません。そうと意識していないだけで、既にあなたは存在型を知っています。 -```erg +```python T: Trait f x: T = ... ``` @@ -11,7 +11,7 @@ f x: T = ... 上のトレイト`T`は存在型として使われています。 対して下の場合の`T`はトレイトでしかなく、`X`は全称型です。 -```erg +```python f|X <: T| x: X = ... ``` @@ -19,7 +19,7 @@ f|X <: T| x: X = ... まず、上で見たように存在型は型変数を伴わないので、型指定をシンプルにできます。 また、型変数を除去できるので全称型ならランク2を超えてしまうような型も構成できます。 -```erg +```python show_map f: (|T| T -> T), arr: [Show; _] = arr.map x -> y = f x @@ -30,7 +30,7 @@ show_map f: (|T| T -> T), arr: [Show; _] = しかし、見ればわかるように存在型は元の型を忘却・拡大してしまうので、戻り値の型を広げたくない場合などは全称型を使う必要があります。 逆に、引数として受け取るだけで戻り値に関係のない型は存在型で記述して構いません。 -```erg +```python # id(1): Intになって欲しい id|T|(x: T): T = x # |S <: Show|(s: S) -> ()は冗長 diff --git a/doc/JA/syntax/type/advanced/keyword_param.md b/doc/JA/syntax/type/advanced/keyword_param.md index bc2ea537..af031750 100644 --- a/doc/JA/syntax/type/advanced/keyword_param.md +++ b/doc/JA/syntax/type/advanced/keyword_param.md @@ -1,13 +1,13 @@ # キーワード引数付き関数型 -```erg +```python h(f) = f(y: 1, x: 2) h: |T: Type|((y: Int, x: Int) -> T) -> T ``` キーワード引数付き関数の部分型付け規則は以下の通り。 -```erg +```python ((x: T, y: U) -> V) <: ((T, U) -> V) # x, y are arbitrary keyword parameters ((y: U, x: T) -> V) <: ((x: T, y: U) -> V) ((x: T, y: U) -> V) <: ((y: U, x: T) -> V) @@ -18,7 +18,7 @@ h: |T: Type|((y: Int, x: Int) -> T) -> T すなわち、`(x: T, y: U) -> V`を`(U, T) -> V`にキャストすることはできない。 なお、キーワード引数がつくのはトップレベルのタプル内のみで、配列やネストしたタプルでキーワード引数は付かない。 -```erg +```python Valid: [T, U] -> V Invalid: [x: T, y: U] -> V Valid: (x: T, ys: (U,)) -> V diff --git a/doc/JA/syntax/type/advanced/kind.md b/doc/JA/syntax/type/advanced/kind.md index 38399fca..2140a96c 100644 --- a/doc/JA/syntax/type/advanced/kind.md +++ b/doc/JA/syntax/type/advanced/kind.md @@ -9,7 +9,7 @@ Ergでは全てが型付けられている。型自体も例外ではない。 また、原子カインドでないカインドは型ではないことに注意してほしい。`-1`は数値だが`-`は数値ではないのと同じように、`Option Int`は型だが`Option`は型ではない。`Option`などは型構築子と呼ばれることもある。 -```erg +```python assert not Option in Type assert Option in Type -> Type ``` @@ -17,7 +17,7 @@ assert Option in Type -> Type なので、以下のようなコードはエラーになる。 Ergではメソッドを定義できるのは原子カインドのみで、メソッドの第一引数以外の場所で`self`という名前を使えない。 -```erg +```python # K is an unary kind K: Type -> Type K T = Class ... @@ -32,7 +32,7 @@ K(T). 0項のカインド`() -> Type`も存在する。これは型理論的には原子カインドと同一視されることもあるが、Ergでは区別される。例としては`Class`などがある。 -```erg +```python Nil = Class() ``` @@ -40,7 +40,7 @@ Nil = Class() 多項カインド間にも部分型関係、もとい部分カインド関係があります。 -```erg +```python K T = ... L = Inherit K L <: K @@ -48,7 +48,7 @@ L <: K すなわち、任意の`T`に対し`L T <: K T`ならば`L <: K`であり、その逆も成り立ちます。 -```erg +```python ∀T. L T <: K T <=> L <: K ``` @@ -56,7 +56,7 @@ L <: K 高階カインド(higher-order kind)というものもある。これは高階関数と同じコンセプトのカインドで、カインド自体を受け取るカインドである。`(Type -> Type) -> Type`などが高階カインドである。高階カインドに属するオブジェクトを定義してみよう。 -```erg +```python IntContainerOf K: Type -> Type = K Int assert IntContainerOf Option == Option Int assert IntContainerOf Result == Result Int @@ -69,26 +69,26 @@ assert IntContainerOf in (Type -> Type) -> Type 型理論において、レコードという概念がある。これはErgのレコードとほぼ同じものである[2](#2)。 -```erg +```python # This is a record, and it corresponds to what is called a record in type theory {x = 1; y = 2} ``` レコードの値が全て型であるとき、それはレコード型といって型の一種であった。 -```erg +```python assert {x = 1; y = 2} in {x = Int; y = Int} ``` レコード型はレコードを型付けする。察しの良い方は、レコード型を型付けする「レコードカインド」があるはずだと考えたかもしれない。実際に、それは存在する。 -```erg +```python log Typeof {x = Int; y = Int} # {{x = Int; y = Int}} ``` `{{x = Int; y = Int}}`のような型がレコードカインドである。これは特別な記法ではない。単に、`{x = Int; y = Int}`のみを要素に持つ列挙型である。 -```erg +```python Point = {x = Int; y = Int} Pointy = {Point} ``` @@ -96,7 +96,7 @@ Pointy = {Point} レコードカインドの重要な特性は、`T: |T|`であり、`U <: T`であるとき、`U: |T|`であるという点にある。 これは列挙型が実際には篩型の糖衣構文であることからもわかる。 -```erg +```python # 通常のオブジェクトでは{c} == {X: T | X == c}だが、 # 型の場合等号が定義されない場合があるので|T| == {X | X <: T}となる {Point} == {P | P <: Point} @@ -105,7 +105,7 @@ Pointy = {Point} 型制約中の`U <: T`は、実は`U: |T|`の糖衣構文である。 このような型のセットであるカインドは一般にセットカインドと呼ばれる。セットカインドはIteratorパターンでも現れる。 -```erg +```python Iterable T = Trait { .Iterator = {Iterator} .iter = Self(T).() -> Self.Iterator T @@ -114,7 +114,7 @@ Iterable T = Trait { ## 多項カインドの型推論 -```erg +```python Container K: Type -> Type, T: Type = Patch K(T, T) Container(K). f self = ... diff --git a/doc/JA/syntax/type/advanced/marker_trait.md b/doc/JA/syntax/type/advanced/marker_trait.md index be11716b..529b8007 100644 --- a/doc/JA/syntax/type/advanced/marker_trait.md +++ b/doc/JA/syntax/type/advanced/marker_trait.md @@ -6,15 +6,15 @@ すべてのマーカートレイトは`Marker`トレイトに包摂される。 標準で提供されている`Light`はマーカートレイトの一種である。 -```erg +```python Light = Subsume Marker ``` -```erg +```python Person = Class {.name = Str; .age = Nat} and Light ``` -```erg +```python M = Subsume Marker MarkedInt = Inherit Int, Impl := M @@ -26,6 +26,6 @@ assert i in M マーカークラスは`Excluding`引数で外すことも可能である。 -```erg +```python NInt = Inherit MarkedInt, Impl := N, Excluding: M ``` diff --git a/doc/JA/syntax/type/advanced/mut_struct.md b/doc/JA/syntax/type/advanced/mut_struct.md index d1efe69b..b3a5cffb 100644 --- a/doc/JA/syntax/type/advanced/mut_struct.md +++ b/doc/JA/syntax/type/advanced/mut_struct.md @@ -2,7 +2,7 @@ `T!`型は任意の`T`型オブジェクトを入れられて差し替え可能なボックス型であると説明した。 -```erg +```python Particle! State: {"base", "excited"}! = Class(..., Impl := Phantom State) Particle!. # このメソッドはStateを"base"から"excited"に遷移させる @@ -19,7 +19,7 @@ Particle!. それを実現するのが可変構造(可変)型である。 -```erg +```python v = [Str; !0].new() v.push! "Hello" v: [Str; !1] @@ -30,7 +30,7 @@ v: [Str; !1] 可変構造型はもちろんユーザー定義も可能である。ただし、不変構造型とは構成法に関していくつか違いがあるので注意が必要である。 -```erg +```python Nil T = Class(Impl := Phantom T) List T, !0 = Inherit Nil T List T, N: Nat! = Class {head = T; rest = List(T, !N-1)} diff --git a/doc/JA/syntax/type/advanced/newtype.md b/doc/JA/syntax/type/advanced/newtype.md index 6859b904..121cc5ab 100644 --- a/doc/JA/syntax/type/advanced/newtype.md +++ b/doc/JA/syntax/type/advanced/newtype.md @@ -4,7 +4,7 @@ Ergはでは以下のように型のエイリアスを定義できますが、これはあくまで同じ型を指します。 -```erg +```python UserId = Int ``` @@ -14,7 +14,7 @@ UserId = Int newtypeパターンはこのような場合に適したデザインパターンです。 -```erg +```python UserId = Class {id = Nat} UserId. new id: Nat = diff --git a/doc/JA/syntax/type/advanced/overloading.md b/doc/JA/syntax/type/advanced/overloading.md index af0633ac..0fe43edf 100644 --- a/doc/JA/syntax/type/advanced/overloading.md +++ b/doc/JA/syntax/type/advanced/overloading.md @@ -3,7 +3,7 @@ Ergでは __アドホック多相__ をサポートしない。すなわち、関数・カインドの多重定義(オーバーロード)ができない。が、トレイトクラスとパッチを組み合わせることでオーバーロードの挙動を再現できる。 トレイトクラスのかわりにトレイトを使用しても良いが、その場合`.add1`を実装している型全てが対象になってしまう。 -```erg +```python Add1 = Trait { .add1: Self.() -> Self } @@ -24,7 +24,7 @@ assert add1(1.0) == 2.0 各型での処理が完全に同じなら下のように書くこともできる。上の書き方は、クラスによって挙動を変える(が、戻り値型は同じ)場合に使う。 型引数を使う多相を __パラメトリック多相__ という。パラメトリック多相は下のように部分型指定と併用する場合が多く、その場合はパラメトリック多相とサブタイピング多相の合わせ技ということになる。 -```erg +```python add1|T <: Int or Str| x: T = x + 1 assert add1(1) == 2 assert add1(1.0) == 2.0 @@ -32,7 +32,7 @@ assert add1(1.0) == 2.0 また、引数の数が違うタイプのオーバーロードはデフォルト引数で再現できる。 -```erg +```python C = Class {.x = Int; .y = Int} C. new(x, y := 0) = Self::__new__ {.x; .y} @@ -47,7 +47,7 @@ assert C.new(0, 0) == C.new(0) まず、オーバーロードされた関数は定義が分散する。このため、エラーが発生した際に原因となる箇所を報告するのが難しい。 また、サブルーチンをインポートすることによって、すでに定義されたサブルーチンの挙動が変わる恐れもある。 -```erg +```python {id; ...} = import "foo" ... id x: Int = x @@ -60,7 +60,7 @@ id "str" # TypeError: id is not implemented for Str 次に、デフォルト引数との相性が悪い。デフォルト引数のある関数がオーバーロードされているとき、どれが優先されるかという問題がある。 -```erg +```python f x: Int = ... f(x: Int, y := 0) = ... @@ -70,7 +70,7 @@ f(1) # which is chosen? さらに、宣言との相性が悪い。 宣言`f: Num -> Num`は、どちらの定義のことを指しているのか特定できない。`Int -> Ratio`と`Ratio -> Int`は包含関係がないためである。 -```erg +```python f: Num -> Num f(x: Int): Ratio = ... f(x: Ratio): Int = ... @@ -79,7 +79,7 @@ f(x: Ratio): Int = ... そして、文法の一貫性を損なう。Ergは変数の再代入を禁止するが、オーバーロードの文法は再代入のように見えてしまう。 無名関数に置換することもできない。 -```erg +```python # same as `f = x -> body` f x = body diff --git a/doc/JA/syntax/type/advanced/phantom.md b/doc/JA/syntax/type/advanced/phantom.md index 6933bdf9..f2df3fed 100644 --- a/doc/JA/syntax/type/advanced/phantom.md +++ b/doc/JA/syntax/type/advanced/phantom.md @@ -3,7 +3,7 @@ 幽霊型は、コンパイラに注釈を与えるためだけに存在するマーカートレイトである。 幽霊型の使い方として、リストの構成をみる。 -```erg +```python Nil = Class() List T, 0 = Inherit Nil List T, N: Nat = Class {head = T; rest = List(T, N-1)} @@ -11,7 +11,7 @@ List T, N: Nat = Class {head = T; rest = List(T, N-1)} このコードはエラーとなる。 -```erg +```python 3 | List T, 0 = Inherit Nil ^^^ TypeConstructionError: since Nil does not have a parameter T, it is not possible to construct List(T, 0) with Nil @@ -21,7 +21,7 @@ hint: use 'Phantom' trait to consume T このエラーはつまり、`List(_, 0).new Nil.new()`とされたときに`T`の型推論ができないという文句である。Ergでは型引数を未使用のままにすることができないのである。 このような場合は何でもよいので`T`型を右辺で消費する必要がある。サイズが0の型、例えば長さ0のタプルならば実行時のオーバーヘッドもなく都合がよい。 -```erg +```python Nil T = Class((T; 0)) List T, 0 = Inherit Nil T List T, N: Nat = Class {head = T; rest = List(T, N-1)} @@ -31,7 +31,7 @@ List T, N: Nat = Class {head = T; rest = List(T, N-1)} このようなときにちょうどよいのが幽霊型である。幽霊型はサイズ0の型を一般化した型である。 -```erg +```python Nil T = Class(Impl := Phantom T) List T, 0 = Inherit Nil T List T, N: Nat = Class {head = T; rest = List(T, N-1)} @@ -45,7 +45,7 @@ assert nil.__size__ == 0 また、`Phantom`は型以外にも任意の型引数を消費することができる。以下の例では`State`という`Str`のサブタイプオブジェクトである型引数を`Phantom`が保持している。 この場合も、`state`はオブジェクトの実体に現れないハリボテの型変数である。 -```erg +```python VM! State: {"stopped", "running"}! = Class(..., Impl := Phantom! State) VM!("stopped"). start ref! self("stopped" ~> "running") = diff --git a/doc/JA/syntax/type/advanced/projection.md b/doc/JA/syntax/type/advanced/projection.md index 404edff6..119ffe3d 100644 --- a/doc/JA/syntax/type/advanced/projection.md +++ b/doc/JA/syntax/type/advanced/projection.md @@ -2,7 +2,7 @@ 射影型は、次のコードにおける`Self.AddO`のような型を表します。 -```erg +```python Add R = Trait { .`_+_` = Self, R -> Self.AddO .AddO = Type @@ -16,7 +16,7 @@ AddForInt. `Add(R)`型は何らかのオブジェクトとの加算が定義されている型といえます。メソッドは型属性であるべきなので、`+`の型宣言はインデント以下に記述します。 `Add`型のミソとなるのが`.AddO = Type`という宣言で、射影型である`.AddO`型の実体は、`Add`のサブタイプである型が持ちます。例えば、`Int.AddO = Int`, `Odd.AddO = Even`です。 -```erg +```python assert Int < Add assert Int.AddO == Int assert Odd < Add diff --git a/doc/JA/syntax/type/advanced/quantified_dependent.md b/doc/JA/syntax/type/advanced/quantified_dependent.md index b778acf3..80abf07e 100644 --- a/doc/JA/syntax/type/advanced/quantified_dependent.md +++ b/doc/JA/syntax/type/advanced/quantified_dependent.md @@ -2,7 +2,7 @@ Ergには量化型、依存型が存在します。すると当然、その二つを組み合わせた型を作ることができます。それが量化依存型です。 -```erg +```python NonNullStr = |N: Nat| StrWithLen N | N != 0 # same as {S | N: Nat; S: StrWithLen N; N != 0} NonEmptyArray = |N: Nat| [_; N | N > 0] # same as {A | N: Nat; A: Array(_, N); N > 0} ``` @@ -11,7 +11,7 @@ NonEmptyArray = |N: Nat| [_; N | N > 0] # same as {A | N: Nat; A: Array(_, N); N 左辺値としての量化依存型は、元の型と同じモジュール内でのみメソッドを定義出来ます。 -```erg +```python K A: Nat = Class ... K(A). ... @@ -21,7 +21,7 @@ K(A | A >= 1). 右辺値としての量化依存型は、使用する型変数を型変数リスト(`||`)で宣言する必要がある。 -```erg +```python # Tは具体的な型 a: |N: Nat| [T; N | N > 1] ``` diff --git a/doc/JA/syntax/type/advanced/shared.md b/doc/JA/syntax/type/advanced/shared.md index ea2a8700..f3c6d4bb 100644 --- a/doc/JA/syntax/type/advanced/shared.md +++ b/doc/JA/syntax/type/advanced/shared.md @@ -21,7 +21,7 @@ console.log(vip_area) # [NormalMember] Ergでは、所有権システムのおかげでこのようなコードは弾かれます。 -```erg +```python NormalMember = Class() VIPMember = Class() @@ -35,7 +35,7 @@ log vip_area # OwnershipError: `vip_room` was moved to `normal_room` しかし、オブジェクトの所有権が一箇所にしかない状態は不便である場合もあります。 そのためにErgは`SharedCell! T!`という型があり、これが共有状態を表します。 -```erg +```python $p1 = SharedCell!.new(!1) $p2 = $p1.mirror!() $p3 = SharedCell!.new(!1) @@ -57,7 +57,7 @@ assert $p3 == 1 重要な事実として、`SharedCell! T!`は非変(non-variant)です。すなわち、型引数の違いによる包含関係が定義されません。 -```erg +```python $vip_area = SharedCell!.new([].into [VIPMember; !_]) $normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError: expected SharedCell!([NormalMember; !_]), but got SharedCell!([VIPMember; !_]) # hint: SharedCell!(T) is non-variant, which means it cannot have a supertype or a subtype. @@ -65,7 +65,7 @@ $normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError: しかし、以下のコードは問題ありません。最後の行では、型変換されたのは引数の`VIPMember`の方です。 -```erg +```python $normal_area = SharedCell!.new([].into [NormalMember; !_]) $normal_area.push!(NormalMember.new()) # OK $normal_area.push!(VIPMember.new()) # OK diff --git a/doc/JA/syntax/type/advanced/special.md b/doc/JA/syntax/type/advanced/special.md index 482ad174..22de410a 100644 --- a/doc/JA/syntax/type/advanced/special.md +++ b/doc/JA/syntax/type/advanced/special.md @@ -2,7 +2,7 @@ `Self`は自身の型を表します。単にエイリアスとして使うことも出来ますが、派生型中では意味が変わる(自身の型を指す)ので注意してください。 -```erg +```python @Inheritable C = Class() C. @@ -16,7 +16,7 @@ classof D.new_c() # C `Super`は基底クラスの型を表します。メソッド自体は基底クラスのものを参照しますが、インスタンスは自身の型を使います。 -```erg +```python @Inheritable C = Class() @@ -33,7 +33,7 @@ classof D.new_c() # C `Self`, `Super`は、構造型・トレイト中では型変数として使用できます。これは、その型のサブタイプであるところのクラスを指します。すなわち、型`T`中で`Self`は`Self <: T`を意味します。 -```erg +```python Add R = Trait { .AddO = Type .`_+_`: Self, R -> Self.AddO diff --git a/doc/JA/syntax/type/advanced/typeof.md b/doc/JA/syntax/type/advanced/typeof.md index f9fa02aa..b0535cc4 100644 --- a/doc/JA/syntax/type/advanced/typeof.md +++ b/doc/JA/syntax/type/advanced/typeof.md @@ -2,7 +2,7 @@ `Typeof`はErgの型推論システムを覗くことができる関数であり、その挙動は複雑である。 -```erg +```python assert Typeof(1) == {I: Int | I == 1} i: 1..3 or 5..10 = ... assert Typeof(i) == {I: Int | (I >= 1 and I <= 3) or (I >= 5 and I <= 10)} @@ -21,7 +21,7 @@ assert {X: C | X == I} < C and C <= {i = Int} 値クラスに関しては本来対応するレコード型が存在しない。この問題を解消するため、値クラスは`__valueclass_tag__`属性を持っているレコード型ということになっている。 なお、この属性にアクセスすることはできず、ユーザー定義型で`__valueclass_tag__`属性を定義することもできない。 -```erg +```python i: Int = ... assert Typeof(i) == {__valueclass_tag__ = Phantom Int} s: Str = ... @@ -38,7 +38,7 @@ Ergは可能な限りオブジェクトの型を篩型として推論し、そ すべてのクラスは構造型に変換することができる。これを __構造化__ という。クラスの構造化された型は`Structure`関数で取得できる。 クラスが`C = Class T`で定義されているとき(すべてのクラスはこの形式で定義されている)、`Structure(C) == T`になる。 -```erg +```python C = Class {i = Int} assert Structure(C) == {i = Int} D = Inherit C diff --git a/doc/JA/syntax/type/advanced/variance.md b/doc/JA/syntax/type/advanced/variance.md index 7ff493af..010dbad0 100644 --- a/doc/JA/syntax/type/advanced/variance.md +++ b/doc/JA/syntax/type/advanced/variance.md @@ -49,7 +49,7 @@ Ergにはもう一つ変性がある。それは非変性(non-variance)である 全称型の型変数は、その上限・下限を指定できます。 -```erg +```python |A <: T| K(A) |B :> T| K(B) ``` @@ -59,14 +59,14 @@ Ergにはもう一つ変性がある。それは非変性(non-variance)である 変性指定は重ねがけすることもできます。 -```erg +```python # U < A < T {... | A <: T; A :> U} ``` 以下に変性指定を使ったコードの例を示します。 -```erg +```python show|S <: Show| s: S = log s Nil T = Class(Impl=Phantom T) @@ -90,7 +90,7 @@ List(T). ここで、メソッドの変性指定を省略した場合どうなるか考えます。 -```erg +```python ... List T = Class {head = T; rest = Cons T} List(T). @@ -109,7 +109,7 @@ List(T). では、このアップキャストを許可するようにした場合はどうなるか考えます。 変性指定を反転させてみましょう。 -```erg +```python ... List T = Class {head = T; rest = Cons T} List(T). @@ -128,7 +128,7 @@ List(T). `Inputs(T)`と指定すると、その型は`T`に関して反変となる。 `Outputs(T)`と指定すると、その型は`T`に関して共変となる。 -```erg +```python K T = Class(...) assert not K(Str) <= K(Object) assert not K(Str) >= K(Object) diff --git a/doc/JA/syntax/type/advanced/widening.md b/doc/JA/syntax/type/advanced/widening.md index da0ecf24..50f3f40f 100644 --- a/doc/JA/syntax/type/advanced/widening.md +++ b/doc/JA/syntax/type/advanced/widening.md @@ -2,7 +2,7 @@ 例えば以下のような多相関数を定義する。 -```erg +```python ids|T|(x: T, y: T) = x, y ``` @@ -10,7 +10,7 @@ ids|T|(x: T, y: T) = x, y 包含関係にある別のクラスのインスタンスペアを代入すると、大きい方にアップキャストされて同じ型になる。 また、包含関係にない別のクラスを代入するとエラーになるのも容易に理解できる。 -```erg +```python assert ids(1, 2) == (1, 2) assert ids(1, 2.0) == (1.0, 2.0) ids(1, "a") # TypeError @@ -18,7 +18,7 @@ ids(1, "a") # TypeError さて、では別の構造型を持つ型の場合はどうなるのだろうか。 -```erg +```python i: Int or Str j: Int or NoneType ids(i, j) # ? @@ -26,7 +26,7 @@ ids(i, j) # ? これの説明を行う前に、Ergの型システムが実は(実行時の)クラスを見ていないという事実に注目しなくてはならない。 -```erg +```python 1: {__valueclass_tag__ = Phantom Int} 2: {__valueclass_tag__ = Phantom Int} 2.0: {__valueclass_tag__ = Phantom Ratio} @@ -43,7 +43,7 @@ ids(1, "a"): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phanto さて、別の構造型の例に戻ろう。結論から言うと上のコードは型があっていないとしてTypeErrorになる。 しかし型注釈で型拡大を行えばコンパイルが通る。 -```erg +```python i: Int or Str j: Int or NoneType ids(i, j) # TypeError: types of i and j not matched @@ -67,7 +67,7 @@ ids(i, j) # OK Ergでは、戻り値型が一致しない場合デフォルトでエラーとなる。 -```erg +```python parse_to_int s: Str = if not s.is_numeric(): do parse_to_int::return error("not numeric") @@ -81,7 +81,7 @@ parse_to_int s: Str = これを解決するためには、戻り値型を明示的にOr型と指定する必要がある。 -```erg +```python parse_to_int(s: Str): Int or Error = if not s.is_numeric(): do parse_to_int::return error("not numeric") diff --git a/doc/JA/tips.md b/doc/JA/tips.md index 85c326fd..700964dc 100644 --- a/doc/JA/tips.md +++ b/doc/JA/tips.md @@ -7,7 +7,7 @@ ## レコードの特定の属性だけ可変化したい -```erg +```python record: {.name = Str; .age = Nat; .height = CentiMeter} {height; rest; ...} = record mut_record = {.height = !height; ...rest} @@ -17,7 +17,7 @@ mut_record = {.height = !height; ...rest} Ergで同一スコープ内でのシャドーイングはできません。しかし、スコープが変われば定義しなおせるので、インスタントブロックを使うといいでしょう。 -```erg +```python # T!型オブジェクトを取得し、最終的にT型として変数へ代入 x: T = x: T! = foo() @@ -29,7 +29,7 @@ x: T = ラッパークラスを作りましょう。これはいわゆるコンポジション(合成)と言われるパターンです。 -```erg +```python FinalWrapper = Class {inner = FinalClass} FinalWrapper. method self = @@ -43,7 +43,7 @@ FinalWrapper. `Singleton`を実装すると、クラスとインスタンスが同一視されます。 また、`Enum`を使うと、その選択肢となる型がリダイレクト属性として自動的に定義されます。 -```erg +```python Ok = Class Impl := Singleton Err = Class Impl := Singleton ErrWithInfo = Inherit {info = Str} @@ -55,7 +55,7 @@ match! stat: Status.ErrWithInfo::{info;} -> ... ``` -```erg +```python Status = Enum Ok, Err, ErrWithInfo # is equivalent to Status = Class Ok or Err or ErrWithInfo @@ -69,7 +69,7 @@ Status. method 1: -```erg +```python arr = [...] for! arr.iter().enumerate(start: 1), i => ... @@ -77,7 +77,7 @@ for! arr.iter().enumerate(start: 1), i => method 2: -```erg +```python arr = [...] for! arr.iter().zip(1..), i => ... @@ -88,12 +88,12 @@ for! arr.iter().zip(1..), i => `foo.er`の非公開APIは`foo.test.er`というモジュールでは特別にアクセス可能となります。 `foo.test.er`モジュールはインポートできないので、隠蔽性は保たれます。 -```erg +```python # foo.er private x = ... ``` -```erg +```python # foo.test.er foo = import "foo" @@ -108,7 +108,7 @@ foo = import "foo" 属性をプライベートにして、ゲッタを定義するとよいでしょう。 -```erg +```python C = Class {v = Int!} C:: inc_v!(ref! self) = self::v.inc!() @@ -122,7 +122,7 @@ C. 引数をレコードで受け取ると良いでしょう。 -```erg +```python Point = {x = Int; y = Int} norm: Point -> Int diff --git a/doc/JA/tools/pack.md b/doc/JA/tools/pack.md index 0363fd0e..ee241ab8 100644 --- a/doc/JA/tools/pack.md +++ b/doc/JA/tools/pack.md @@ -34,7 +34,7 @@ Ergは標準でパッケージマネージャーが付属しており、`pack` `erg pack init`すると以下のようなファイル、`package.er`が生成される。`package.er`にはパッケージの設定を記述する。 以下は`package.er`の記述例である。 -```erg +```python name = "example" # package name author = "John Smith" # package author name version = "0.1.0" diff --git a/doc/JA/tools/test.md b/doc/JA/tools/test.md index c2264c05..80073614 100644 --- a/doc/JA/tools/test.md +++ b/doc/JA/tools/test.md @@ -7,7 +7,7 @@ ergコマンドにはtestというサブコマンドがあり、テスト実装 Ergではパッケージ中の`tests`ディレクトリか`*.test.er`ファイル中の`@Test`を付けたサブルーチンを`erg test`コマンドでテストする。 `tests`のサブルーチンはブラックボックステスト(非公開関数をテストしない)、`*.test.er`のサブルーチンはホワイトボックステスト(非公開関数もテストする)を担当する。 -```erg +```python # tests/test1.er {add; ...} = import "foo" @@ -24,12 +24,12 @@ Ergでは`#`, `#[`以降がコメント行となるが、`##`, `#[[`でdoc comme さらにdoc comment中のソースコードはergと指定されていれば、erg testコマンドで自動テストされる。 以下はテストの例である。 -```erg +```python VM = ... ... #[[ execute commands. - ```erg + ```python # VM in standard configuration {vm1; ...} = import "tests/mock" diff --git a/doc/zh_CN/API/funcs.md b/doc/zh_CN/API/funcs.md index 3dee7041..0a97634e 100644 --- a/doc/zh_CN/API/funcs.md +++ b/doc/zh_CN/API/funcs.md @@ -27,7 +27,7 @@ 扔掉`x`。不使用返回值时使用。与 `del` 不同,它不会使变量 `x` 不可访问 -```erg +```python p! x = # q!应该返回一些不是None或()的值 # 如果不需要,请使用`discard` @@ -56,7 +56,7 @@ assert True # OK ### repeat|T|(x: T) -> RepeatIterator T -```erg +```python rep = repeat 1 # Repeater(1) for! rep, i => print! i @@ -65,7 +65,7 @@ for! rep, i => ### dup|T; N|(x: T, N: Nat) -> [T; N] -```erg +```python [a, b, c] = dup new(), 3 print! a # print! a == b # False @@ -73,7 +73,7 @@ print! a == b # False ### cycle|T|(it: Iterable T) -> CycleIterator T -```erg +```python cycle([0, 1]).take 4 # [0, 1, 0, 1] cycle("hello").take 3 # "hellohellohello" ``` @@ -85,7 +85,7 @@ cycle("hello").take 3 # "hellohellohello" 创建一个新类。 与`Inherit`不同,通过`Class`传递与基类型无关,并且方法会丢失 您将无法进行比较,但您可以进行模式匹配等操作 -```erg +```python C = Class {i = Int} NewInt = Class Int Months = Class 1..12 @@ -111,7 +111,7 @@ match jan: 返回参数类型。如果要获取运行时类,请使用`classof`。 如果您将其用于类型规范,则会出现警告。 -```erg +```python x: Typeof i = ... # TypeWarning: Typeof(i) == Int, please replace it ``` diff --git a/doc/zh_CN/API/special.md b/doc/zh_CN/API/special.md index 2a362bd0..f9775d6f 100644 --- a/doc/zh_CN/API/special.md +++ b/doc/zh_CN/API/special.md @@ -8,7 +8,7 @@ 将 body 分配给 pat 作为变量。如果变量已存在于同一范围内或与 pat 不匹配,则引发错误。 它还用于记录属性定义和默认参数。 -```erg +```python record = {i = 1; j = 2} f(x: Int, y = 2) = ... ``` @@ -16,7 +16,7 @@ f(x: Int, y = 2) = ... 当主体是类型或函数时,`=` 具有特殊行为。 左侧的变量名嵌入到右侧的对象中。 -```erg +```python print! Class() # > print! x: Int -> x + 1 # > C = Class() @@ -54,14 +54,14 @@ if True, do: 确定主题是否与 T 匹配。如果它们不匹配,则抛出编译错误。 -```erg +```python a: Int f x: Int, y: Int = x / y ``` 也用于 `:` 应用样式。 -```erg +```python f x: y z @@ -69,7 +69,7 @@ f x: 像`:`和`=`一样,运算的结果是不确定的。 -```erg +```python _ = x: Int # 语法错误: print!(x: Int) # 语法错误: ``` @@ -91,7 +91,7 @@ print!(x: Int) # 语法错误: 对于 obj,执行与模式匹配的 lambda。 -```erg +```python match [1, 2, 3]: (l: Int) -> log "this is type of Int" [[a], b] -> log a, b @@ -103,7 +103,7 @@ match [1, 2, 3]: 删除变量“x”。但是,无法删除内置对象。 -```erg +```python a = 1 del a # OK @@ -123,7 +123,7 @@ del True # SyntaxError: cannot delete a built-in object 创建一个由两对组成的类元组结构,称为 Choice 对象。 `l, r` 被懒惰地评估。也就是说,只有在调用 .get_then 或 .get_else 时才会计算表达式。 -```erg +```python choice = 1 else 2 assert choice.get_then() == 1 assert choice.get_else() == 2 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..305b0142 100644 --- a/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md +++ b/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md @@ -6,7 +6,7 @@ * values_at(self, selectors: [Nat; N]) -> [T; N] -```erg +```python assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] ``` @@ -15,7 +15,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] 如果元素为 0,则无论 pred 为 `True`,但会发出警告。 该规范本身已被多种语言采用,是逻辑一致性所必需的。 - ```erg + ```python assert [].all(_ -> False) ``` @@ -28,7 +28,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] * freq self -> [{T: Nat}] 返回对象出现的次数。 -```erg +```python assert ["a", "b", "c", "b", "c", "b"].freq() \ == [{"a", 1}, {"b": 3}, {"c": 2}] ``` diff --git a/doc/zh_CN/API/types/classes/Function(N).md b/doc/zh_CN/API/types/classes/Function(N).md index 0955f2ec..24195350 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 +```python assert f(g(x)) == f.then(g) x ``` diff --git a/doc/zh_CN/API/types/classes/IntRange.md b/doc/zh_CN/API/types/classes/IntRange.md index 997d8f42..e379badd 100644 --- a/doc/zh_CN/API/types/classes/IntRange.md +++ b/doc/zh_CN/API/types/classes/IntRange.md @@ -2,7 +2,7 @@ `L..R`のクラス。 -```erg +```python IntRange L, R: Int == L..R ``` @@ -12,7 +12,7 @@ IntRange L, R: Int == L..R 正常加法。 `Int` 和 `Nat` 的添加在此定义为假装它在每个类中定义 -```erg +```python 0..10 + 1..12 == 1..22 Int + 0..10 == _..|Int|_ + 0..10 == _..|Int|_ == Int Nat + Nat == 0.._ + 0.._ == 0.._ == Nat diff --git a/doc/zh_CN/API/types/classes/Interval.md b/doc/zh_CN/API/types/classes/Interval.md index 001d85d6..47aa17b3 100644 --- a/doc/zh_CN/API/types/classes/Interval.md +++ b/doc/zh_CN/API/types/classes/Interval.md @@ -2,14 +2,14 @@ 表示有序集合类型 (WellOrder) 的子类型的类型。Interval 类型具有派生类型,例如 PreOpen(x<..y)。 -```erg +```python Months = 1..12 Alphabet = "a".."z" Weekdays = Monday..Friday Winter = November..December or January..February ``` -```erg +```python 0..1 # 整数范围 0.0..1.0 # 真实(有理)范围 # 或 0/1..1/1 相同 diff --git a/doc/zh_CN/API/types/classes/Kind(N).md b/doc/zh_CN/API/types/classes/Kind(N).md index 4a72aec9..b3103d53 100644 --- a/doc/zh_CN/API/types/classes/Kind(N).md +++ b/doc/zh_CN/API/types/classes/Kind(N).md @@ -1,5 +1,5 @@ # Kind N: Nat -```erg +```python Kind N: Nat = (Type; N) -> Type ``` diff --git a/doc/zh_CN/API/types/classes/Nat.md b/doc/zh_CN/API/types/classes/Nat.md index afa30251..0e6d0d1f 100644 --- a/doc/zh_CN/API/types/classes/Nat.md +++ b/doc/zh_CN/API/types/classes/Nat.md @@ -4,7 +4,7 @@ ## def -```erg +```python Nat = 0.._ ``` @@ -12,7 +12,7 @@ Nat = 0.._ * times!(self, p: () => NoneType) -> NoneType -```erg +```python 100.times! () => print! "hello!" ``` diff --git a/doc/zh_CN/API/types/classes/Never.md b/doc/zh_CN/API/types/classes/Never.md index 2f0cdd15..fa6c413b 100644 --- a/doc/zh_CN/API/types/classes/Never.md +++ b/doc/zh_CN/API/types/classes/Never.md @@ -3,7 +3,7 @@ 它是所有类型的子类型。 它是一个`Class`,因为它拥有所有的方法,当然还有 `.new`。但是,它没有实例,并且Erg会在即将创建的那一刻停止。 还有一种叫做`Panic`的类型没有实例,但是`Never`用于正常终止或故意无限循环,`Panic`用于异常终止。 -```erg +```python # Never <: Panic f(): Panic = exit 0 # OK g(): Never = panic() # TypeError diff --git a/doc/zh_CN/API/types/classes/Option.md b/doc/zh_CN/API/types/classes/Option.md index 6eeb18b0..8018eb32 100644 --- a/doc/zh_CN/API/types/classes/Option.md +++ b/doc/zh_CN/API/types/classes/Option.md @@ -8,7 +8,7 @@ 提取它,期望内容是 `T` 类型。 如果是 `None`,则输出 `msg` 并恐慌 -```erg +```python x = "...".parse(Int).into(Option Int) x.unwrap() # UnwrappingError: unwrapped a None value x.unwrap("failed to convert from string to number") # UnwrappingError: failed to convert from string to number diff --git a/doc/zh_CN/API/types/classes/Record.md b/doc/zh_CN/API/types/classes/Record.md index 4ff1126e..7dc5f93f 100644 --- a/doc/zh_CN/API/types/classes/Record.md +++ b/doc/zh_CN/API/types/classes/Record.md @@ -3,7 +3,7 @@ 记录所属的类。例如,`{i = 1}` 是`Structural {i = Int}` 类型的元素,并且是`{i = Int}` 类的实例 请注意,其他类的实例是记录类型的元素,而不是记录类的实例 -```erg +```python assert not Structural({i = Int}) in Class assert {i = Int} in Class diff --git a/doc/zh_CN/API/types/classes/Result.md b/doc/zh_CN/API/types/classes/Result.md index de89e41c..67134e03 100644 --- a/doc/zh_CN/API/types/classes/Result.md +++ b/doc/zh_CN/API/types/classes/Result.md @@ -1,6 +1,6 @@ # Result T, E -```erg +```python Result T, E <: Error = Either T, E ``` diff --git a/doc/zh_CN/API/types/classes/Subroutine.md b/doc/zh_CN/API/types/classes/Subroutine.md index 2350098c..5738381b 100644 --- a/doc/zh_CN/API/types/classes/Subroutine.md +++ b/doc/zh_CN/API/types/classes/Subroutine.md @@ -8,7 +8,7 @@ Func和Proc的基本类型。 中断子程序并返回指定的值。 用于快速逃离嵌套 -```erg +```python f x = for 0..10, i -> if i == 5: diff --git a/doc/zh_CN/API/types/classes/Tensor.md b/doc/zh_CN/API/types/classes/Tensor.md index 131bb3c8..2fa51a80 100644 --- a/doc/zh_CN/API/types/classes/Tensor.md +++ b/doc/zh_CN/API/types/classes/Tensor.md @@ -3,13 +3,13 @@ 用于有效操作多维数组的类。 它还定义了诸如多维数组上的乘法之类的操作 Matrix、Vector 等都继承自该类型 -```erg +```python Tensor.arange(0..9) # Tensor [10] ``` * reshape(self, NewShape: [Nat; M]) -> Self NewShape -```erg +```python (1..9).into(Tensor).reshape [3, 3] ``` diff --git a/doc/zh_CN/API/types/classes/TransCell(T).md b/doc/zh_CN/API/types/classes/TransCell(T).md index 078be645..afb24e2c 100644 --- a/doc/zh_CN/API/types/classes/TransCell(T).md +++ b/doc/zh_CN/API/types/classes/TransCell(T).md @@ -3,7 +3,7 @@ 它是一个单元格,其内容可以针对每个模具进行更改。 由于它是T类型的子类型,因此它也表现为T类型 当它在初始化时输入T时很有用,并且在某个点之后总是输入U -```erg +```python a = TransCell!.new None a: TransCell! !NoneType a.set! 1 diff --git a/doc/zh_CN/API/types/classes/Tuple.md b/doc/zh_CN/API/types/classes/Tuple.md index b9b7667e..8ea7b645 100644 --- a/doc/zh_CN/API/types/classes/Tuple.md +++ b/doc/zh_CN/API/types/classes/Tuple.md @@ -8,7 +8,7 @@ 组合两个有序集合(数组或元组) - ```erg + ```python assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4) ``` @@ -17,7 +17,7 @@ 一种泛化 zip 的方法。 您可以指定一个二进制操作来组合 `()`、`[]`、`{}`、`{:}` 也可以指定为运算符,分别生成元组、数组、集合和字典 - ```erg + ```python assert ([1, 2, 3].zip([4, 5, 6]))[0] == (1, 4) assert ([1, 2, 3].zip_by((), [4, 5, 6]))[0] == (1, 4) assert ([1, 2, 3].zip_by([], [4, 5, 6]))[0] == [1, 4] diff --git a/doc/zh_CN/API/types/traits/Add(R,O).md b/doc/zh_CN/API/types/traits/Add(R,O).md index bf735100..f9ee06b3 100644 --- a/doc/zh_CN/API/types/traits/Add(R,O).md +++ b/doc/zh_CN/API/types/traits/Add(R,O).md @@ -1,6 +1,6 @@ # Add R -```erg +```python Add R = Trait { .AddO = Type .`_+_` = (Self, R) -> Self.AddO @@ -10,13 +10,13 @@ Add R = Trait { `Add`是一种定义加法的类型。加法有两种类型的`+`:方法和函数 `+`作为二元函数,即`_+_`,定义如下: -```erg +```python `_+_`(l: Add(R, O), r: R): O = l.`_+_` r ``` わざわざこの定義があるのは、`+`をメソッドではなく関数として取り扱えるようにである。 -```erg +```python assert [1, 2, 3].fold(0, `_+_`) == 6 call op, x, y = op(x, y) @@ -25,7 +25,7 @@ assert call(`_+_`, 1, 2) == 3 加算はこのように型付けされる。 -```erg +```python f: |O: Type; A <: Add(Int, O)| A -> O f x = x + 1 diff --git a/doc/zh_CN/API/types/traits/Div(R,O).md b/doc/zh_CN/API/types/traits/Div(R,O).md index b0b5adf0..020acba5 100644 --- a/doc/zh_CN/API/types/traits/Div(R,O).md +++ b/doc/zh_CN/API/types/traits/Div(R,O).md @@ -2,7 +2,7 @@ 如果除以零没有错误,请使用“SafeDiv” -```erg +```python Div R, O = Trait { .`/` = Self.(R) -> O or Panic } diff --git a/doc/zh_CN/API/types/traits/Num.md b/doc/zh_CN/API/types/traits/Num.md index 5745c5ce..377da536 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 +```python Num R = Add(R) and Sub(R) and Mul(R) and Eq Num = Num Self ``` 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..998faf89 100644 --- a/doc/zh_CN/API/types/traits/SafeDiv(R,O).md +++ b/doc/zh_CN/API/types/traits/SafeDiv(R,O).md @@ -1,6 +1,6 @@ # SafeDiv R, O -```erg +```python SafeDiv R, O = Subsume Div, { @Override .`/` = Self.(R) -> O diff --git a/doc/zh_CN/API/types/traits/Sample.md b/doc/zh_CN/API/types/traits/Sample.md index 93629a6a..5d2a6cdb 100644 --- a/doc/zh_CN/API/types/traits/Sample.md +++ b/doc/zh_CN/API/types/traits/Sample.md @@ -6,7 +6,7 @@ 所有主要的值类都实现了 `Sample`。它还在由“Sample”类组成的元组类型、记录类型、Or类型和筛选类型中实现 -```erg +```python assert Int.sample() == 42 assert Str.sample() == "example" # Int默认在64bit范围内采样 @@ -16,7 +16,7 @@ print! {x = Int; y = Int}.sample!() # {x = -32432892, y = 78458576891} 下面是一个`Sample`的实现示例 -```erg +```python EmailAddress = Class {header = Str; domain = Str}, Impl=Sample and Show @Impl Show EmailAddress. diff --git a/doc/zh_CN/API/types/traits/Unpack.md b/doc/zh_CN/API/types/traits/Unpack.md index 259beb3a..7c721151 100644 --- a/doc/zh_CN/API/types/traits/Unpack.md +++ b/doc/zh_CN/API/types/traits/Unpack.md @@ -2,7 +2,7 @@ 标记性状。实现时,元素可以像记录一样通过模式匹配来分解 -```erg +```python C = Class {i = Int}, Impl=Unpack C.new i = Self::new {i;} {i} = C.new(1) diff --git a/doc/zh_CN/compiler/errors.md b/doc/zh_CN/compiler/errors.md index 6e241f3c..1ad6e9c8 100644 --- a/doc/zh_CN/compiler/errors.md +++ b/doc/zh_CN/compiler/errors.md @@ -24,7 +24,7 @@ 当你有一个明显不可阻挡的循环时发生 -```erg +```python i: Int = i f(): Int = g() @@ -91,7 +91,7 @@ U = T 在定义之前使用变量时发生 更准确地说,它发生在以前使用过在范围内定义的变量时 -```erg +```python i = 0 f x = y = i + x @@ -102,7 +102,7 @@ f x = 在这段代码中,`y = i + x` 中的 `i` 是一个未定义的变量 但是,常量可以在定义之前在另一个函数中调用 -```erg +```python f() = g() g() = f() ``` @@ -113,7 +113,7 @@ g() = f() 它在语法上很好,但是当我们检测到冗余或不常见的代码(不必要的 `()` 等)时就会发生这种情况 -```erg +```python if (True): # SyntaxWarning: unnecessary parentheses ... ``` diff --git a/doc/zh_CN/compiler/hir.md b/doc/zh_CN/compiler/hir.md index 837b51a4..29e9ca14 100644 --- a/doc/zh_CN/compiler/hir.md +++ b/doc/zh_CN/compiler/hir.md @@ -5,7 +5,7 @@ HIR 是 Erg 编译器从 AST 生成的结构 AST与源代码一一对应(纯文本),但是HIR去掉了不必要的代码信息,添加了省略的类型信息,所以HIR可以转换为源代码很难恢复 让我们在下面的代码中查看 HIR 的示例 -```erg +```python v = ![] for! 0..10, i => v.push! i @@ -14,7 +14,7 @@ log v.sum() 从此代码生成的 AST 如下所示: -```erg +```python AST(Module[ VarDef{ sig: VarSignature{ @@ -71,7 +71,7 @@ AST(Module[ 从 AST 生成的 HIR 如下所示: -```erg +```python HIR(Module[ VarDef{ sig: VarSignature{ diff --git a/doc/zh_CN/compiler/parsing.md b/doc/zh_CN/compiler/parsing.md index 59d11bac..fbc7fc76 100644 --- a/doc/zh_CN/compiler/parsing.md +++ b/doc/zh_CN/compiler/parsing.md @@ -5,7 +5,7 @@ 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 +```python f +1 == f(+1) f + 1 == `+`(f, 1) f (1,) == f((1,)) @@ -20,7 +20,7 @@ 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 +```python # 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` is the right-hand side value, but i to the left of -> is the left-hand side value diff --git a/doc/zh_CN/dev_guide/faq_syntax.md b/doc/zh_CN/dev_guide/faq_syntax.md index 3bfa870b..5eab9ded 100644 --- a/doc/zh_CN/dev_guide/faq_syntax.md +++ b/doc/zh_CN/dev_guide/faq_syntax.md @@ -8,7 +8,7 @@ 因为在和中会发生语法冲突。 -```erg +```python # []版 id[T: Type] [t]: [T] = t y = id[Int] # 这是一个功能吗? @@ -27,7 +27,7 @@ y = id|Int| # OK Erg 设计为将类型本身也视为值。 -```erg +```python A = [Int; 3] assert A[2] == Int T = (Int, Str) @@ -49,7 +49,7 @@ assert S.i == Int 在 Erg 中,运算符使你可以在不太注意错误的情况下编写。 -```erg +```python read_file!() = f = open!("foo.txt")? # 如果失败则立即返回错误,所以 f 是文件类型 f.read_all!() @@ -78,7 +78,7 @@ Python 的库中有一些类设计为继承,如果完全取消继承,这些 默认情况下,指向结构托盘会使类型指定变得复杂,并且可能会混合程序员的非预期行为。 -```erg +```python # If T is a subtype of a structural trait... # f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T f|T| x, y: T = x + y - x diff --git a/doc/zh_CN/python/class_system.md b/doc/zh_CN/python/class_system.md index 89b6d2e9..fa6c7f10 100644 --- a/doc/zh_CN/python/class_system.md +++ b/doc/zh_CN/python/class_system.md @@ -51,7 +51,7 @@ TypeError: can only concatenate str (not "int") to str Erg statically checks for consistency with the parent class. The `Override` decorator must be given when overriding, and the type of the overriding function must be a subtype of the type of the function being overridden. -```erg +```python >>> C = Class() ... .f self = 1 ... .g self = self.f() + 1 @@ -81,7 +81,7 @@ f(c) f(1) # TypeError ``` -```erg +```python # f: |T, X <: {.m = Self.() -> T}| X -> T f(x) = x.m() diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md index 4d643c3b..651caf2f 100644 --- a/doc/zh_CN/syntax/00_basic.md +++ b/doc/zh_CN/syntax/00_basic.md @@ -11,7 +11,7 @@ This document describes the basic syntax of Erg. The [Standard API](./API/index. First, let's do "Hello World". -```erg +```python print!("Hello, World!") ``` @@ -19,7 +19,7 @@ This is almost identical to Python and other languages in the same family. The m In Erg, parentheses `()` can be omitted unless there is some confusion in interpretation. The omission of parentheses is similar to Ruby, but it is not possible to omit parentheses that can be interpreted in more than one way. -```erg +```python print! "Hello, World!" # OK print! "Hello,", "World!" # OK print!() # OK @@ -70,7 +70,7 @@ hello, world! The code after `#` is ignored as a comment. Use this to explain the intent of the code or to temporarily disable the code. -```erg +```python # Comment # `#` and after are ignored until a new line is inserted #[ @@ -85,7 +85,7 @@ A script is a series of expressions. An expression is something that can be calc Each expression is separated by a separator - either a new line or a semicolon `;`-. Erg scripts are basically evaluated from left to right, top to bottom. -```erg +```python n = 1 # assignment expression f(1, 2) # function-call expression 1 + 1 # operator-call expression @@ -95,7 +95,7 @@ f(1, 2); 1 + 1 As shown below, there is a syntax called instant block that takes the last expression evaluated in the block as the value of the variable. This differs from a function with no arguments, which does not add `()`. Note that instant blocks are evaluated only once on the fly. -```erg +```python i = x = 1 x + 1 @@ -104,7 +104,7 @@ assert i == 2 This cannot be accomplished with a semicolon (`;`). -```erg +```python i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses ``` @@ -112,7 +112,7 @@ i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses Erg, like Python, uses indentation to represent blocks. There are five operators (special forms) that trigger the start of a block: `=`, `->`, `=>`, `do`, and `do!` (In addition, `:` and `|`, although not operators, also produce indentation). The meanings of each are described later. -```erg +```python f x, y = x + y @@ -131,7 +131,7 @@ ans = match x: If a line is too long, it can be broken using `\`. -```erg +```python # this does not means `x + y + z` but means `x; +y; +z` x + y diff --git a/doc/zh_CN/syntax/01_literal.md b/doc/zh_CN/syntax/01_literal.md index f8336328..3411024d 100644 --- a/doc/zh_CN/syntax/01_literal.md +++ b/doc/zh_CN/syntax/01_literal.md @@ -4,19 +4,19 @@ ### Int Literal -```erg +```python 0, -0, 1, -1, 2, -2, 3, -3, ... ``` ### Ratio Literal -```erg +```python 0.00, -0.0, 0.1, 400.104, ... ``` If a `Ratio` literal has an integer or decimal part of `0`, you can omit the `0`. -```erg +```python assert 1.0 == 1. assert 0.5 == .5 ``` @@ -29,14 +29,14 @@ Subsequent documents may use `assert` to indicate that the results are equal. Any Unicode-representable string can be used. Unlike Python, quotation marks cannot be enclosed in `'`. If you want to use `"` in a string, use `\"`. -```erg +```python "", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "السَّلَامُ عَلَيْكُمْ", ... ``` `{}` allows you to embed expressions in strings. This is called string interpolation. If you want to output `{`, `}` itself, use `\{`, `\}`. -```erg +```python assert "1 + 1 is 2" == "{1} + {1} is {1+1}" s = "1+1" assert "\{1+1}\" == "\{{s}\}" @@ -47,11 +47,11 @@ assert "\{1+1}\" == "\{{s}\}" This is a literal representing exponential notation often used in academic calculations. It is an instance of type ``Ratio``. The notation is the same as in Python. -```erg +```python 1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ... ``` -```erg +```python assert 1e-10 == 0.0000000001 ``` @@ -61,37 +61,37 @@ Each of these literals has its own documentation describing them separately, so ### [Array Literal](./10_array.md) -```erg +```python [], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ... ``` ### [Dict Literal](./11_dict.md) -```erg +```python {:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ... ``` ### [Tuple Literal](./12_tuple.md) -```erg +```python (), (1, 2, 3), (1, "hello", True), ... ``` ### [Record Literal](./13_record.md) -```erg +```python {=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ... ``` ### [Set Literal](./14_set.md) -```erg +```python {}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ... ``` As a difference from `Array` literals, duplicate elements are removed in `Set`. -```erg +```python assert {1, 2, 1} == {1, 2} ``` @@ -99,19 +99,19 @@ assert {1, 2, 1} == {1, 2} ## Boolean Object -```erg +```python True, False ``` ### None Object -```erg +```python None ``` ## Range Object -```erg +```python assert 0..5 == {1, 2, 3, 4, 5} assert 0..10 in 5 assert 0..<10 notin 10 @@ -120,7 +120,7 @@ assert 0..9 == 0..<10 ## Float Object -```erg +```python assert 0.0f64 == 0 assert 0.0f32 == 0.0f64 ``` @@ -129,7 +129,7 @@ Float objects are constructed by multiplying a `Ratio` object by `f64`, which is ## Complex Object -```erg +```python 1+2im, 0.4-1.2im, 0im, im ``` @@ -139,7 +139,7 @@ A `Complex` object is simply an arithmetic combination of an imaginary unit obje In Erg, you can omit the `*` to indicate multiplication as long as there is no confusion in interpretation. However, the combined strength of the operators is set stronger than `*`. -```erg +```python # same as `assert (1*m) / (1*s) == 1*(m/s)` assert 1m / 1s == 1 (m/s) ``` diff --git a/doc/zh_CN/syntax/02_name.md b/doc/zh_CN/syntax/02_name.md index 8b87e4a2..63138c32 100644 --- a/doc/zh_CN/syntax/02_name.md +++ b/doc/zh_CN/syntax/02_name.md @@ -5,7 +5,7 @@ Variables are a type of algebra; algebra in Erg - sometimes simply referred to a A variable is defined as follows. The `n` part is called the variable name (or identifier), `=` is the assignment operator, and the `1` part is the assigned value. -```erg +```python n = 1 ``` @@ -15,13 +15,13 @@ We have just said that `1` is an object. We will discuss what an object is later If you want to specify the "type" of a variable, do the following. The type is roughly the set to which an object belongs, as will be explained later. Here we specify that `n` is a natural number (`Nat`) type. -```erg +```python n: Nat = 1 ``` Note that, unlike other languages, multiple assignments are not allowed. -```erg +```python # NG l1 = l2 = [1, 2, 3] # SyntaxError: multiple assignment not allowed # OK @@ -31,7 +31,7 @@ l2 = l1.clone() It is also not possible to reassign to a variable. The syntax that can be used instead, to hold mutable states, are described later. -```erg +```python i = 1 i = i + 1 # AssignError: cannot assign twice ``` @@ -40,7 +40,7 @@ You can define a variable with the same name in the inner scope, but you are onl Note that this is a different behavior than the Python "statement" scope. This kind of functionality is generally referred to as shadowing. However, unlike shadowing in other languages, you cannot shadow in the same scope. -```erg +```python x = 0 # x = 1 # AssignError: cannot assign twice if x.is_zero(), do: @@ -51,7 +51,7 @@ assert x == 0 The following may seem possible at first glance, but it is still not possible. This is a design decision, not a technical constraint. -```erg +```python x = 0 if x.is_zero(), do: x = x + 1 # NameError: cannot define variables refer to variables with the same name @@ -64,7 +64,7 @@ assert x == 0 Constants are also a type of algebra. If you start an identifier with a capital letter, it is treated as a constant. They are called constants because once defined, they do not change. The `N` part is called the constant name (or identifier). Otherwise, it is the same as a variable. -```erg +```python N = 0 if True, do: N = 1 # AssignError: constants cannot be shadowed @@ -77,13 +77,13 @@ For example, constants are used for mathematical constants, information about ex It is common practice to use all-caps (style in which all letters are capitalized) for identifiers of objects other than [types](./type/01_type_system.md). -```erg +```python PI = 3.141592653589793 URL = "https://example.com" CHOICES = ["a", "b", "c"] ``` -```erg +```python PI = 3.141592653589793 match! x: PI => print! "π" @@ -95,7 +95,7 @@ The above code prints `π` when `x` is `3.141592653589793`. If `x` is changed to Some objects cannot be bound as constants. Mutable objects, for example. Mutable objects are objects whose states can be changed, as described in detail later. This is because of the rule that only constant expressions can be assigned to constants. Constant expressions are also discussed later. -```erg +```python X = 1 # OK X = !1 # TypeError: cannot define Int! object as a constant ``` @@ -104,7 +104,7 @@ X = !1 # TypeError: cannot define Int! object as a constant You can delete an variable by using the `Del` function. All other variables that depend on the variable (that is, that refer directly to the value of the variable) are also removed. -```erg +```python x = 1 y = 2 Z = 3 @@ -119,7 +119,7 @@ f(2) # NameError: f is not defined (deleted in line 6) Note that `Del` can only delete variables defined in the user-defined module. Built-in constants such as `True` cannot be deleted. -```erg +```python Del True # TypeError: cannot delete built-in constants Del print! # TypeError: cannot delete built-in variables ``` @@ -128,7 +128,7 @@ Del print! # TypeError: cannot delete built-in variables Note that `x == a` is not necessarily true when `x = a`. An example is `Float.NaN`. This is the formal specification of floating-point numbers as defined by IEEE 754. -```erg +```python x = Float.NaN assert x ! = NaN assert x ! = x @@ -136,7 +136,7 @@ assert x ! = x There are other objects for which no equivalence relation is defined in the first place. -```erg +```python f = x -> x**2 + 2x + 1 g = x -> (x + 1)**2 f == g # TypeError: cannot compare function objects @@ -149,7 +149,7 @@ C == D # TypeError: cannot compare class objects Strictly speaking, `=` does not assign the right-hand side value directly to the left-hand side identifier. In the case of function and class objects, "modification" such as giving variable name information to the object is performed. However, this is not the case for structural types. -```erg +```python f x = x print! f # g x = x + 1 diff --git a/doc/zh_CN/syntax/03_declaration.md b/doc/zh_CN/syntax/03_declaration.md index b609984e..1548c120 100644 --- a/doc/zh_CN/syntax/03_declaration.md +++ b/doc/zh_CN/syntax/03_declaration.md @@ -4,7 +4,7 @@ Declaration is the syntax for specifying the type of variable to be used. Declarations can be made anywhere in the code, but declarations alone do not refer to the variables. They must be initialized. After the assignment, the declaration can be checked to ensure that the type is compatible with the object to which it is assigned. -```erg +```python i: Int # Can be declared at the same time as the assignment, like i: Int = 2 i = 2 @@ -17,7 +17,7 @@ i: {2} Declaration after assignment is similar to type checking by `assert`, but has the feature that it is checked at compile time. Type checking by `assert` at runtime can be checked for "may be type Foo", but type checking by `:` at compile time is strict: if the type is not determined to be "type Foo", it will not pass the check and an error will occur. -```erg +```python i = (-1..10).sample! assert i in Nat # this may pass i: Int # this will pass @@ -26,14 +26,14 @@ i: Nat # this will not pass (-1 is not an element of Nat) Functions can be declared in 2 different ways. -```erg +```python f: (x: Int, y: Int) -> Int f: (Int, Int) -> Int ``` If you declare the argument names explicitly, a type error will result if the names are different at definition time. If you want to give the argument names arbitrary names, you can declare them in the second way. In that case, only the method name and its type will be seen by type checking. -```erg +```python T = Trait { .f = (x: Int, y: Int): Int } diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md index be531d30..8e93f12b 100644 --- a/doc/zh_CN/syntax/04_function.md +++ b/doc/zh_CN/syntax/04_function.md @@ -2,7 +2,7 @@ A function is a block that takes an "argument", processes it, and returns it as a "return value". It is defined as follows. -```erg +```python add x, y = x + y # or add(x, y) = x + y @@ -13,7 +13,7 @@ In contrast, the objects passed to a function are called arguments. The function `add` is a function that takes `x` and `y` as parameters and returns the sum of them, `x + y`. The defined function can be called (applied/invoked) as follows. -```erg +```python add 1, 2 # or add(1, 2) @@ -23,16 +23,16 @@ add(1, 2) Functions are invoked like `f x, y, ...`, but if there are too many arguments for a single line, they can be applied using `:` (colon). -```erg +```python f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4 ``` -```erg +```python f some_long_name_variable_1 + some_long_name_variable_2: some_long_name_variable_3 * some_long_name_variable_4 ``` -```erg +```python f: some_long_name_variable_1 + some_long_name_variable_2 some_long_name_variable_3 * some_long_name_variable_4 @@ -40,7 +40,7 @@ f: All three codes above mean the same thing. This style is also useful when using `if` functions, for example. -```erg +```python result = if Bool.sample!(): do: log "True was chosen" @@ -57,19 +57,19 @@ After `:`, no code other than comments may be written, and must always be on a n If a function is defined with a large number of parameters, there is a danger of passing the arguments in the wrong order. In such cases, it is safe to call the function using keyword arguments. -```erg +```python f x, y, z, w, v, u: Int = ... ``` The functions defined above have many arguments and are arranged in a confusing order. You should not create such a function, but you may encounter such code when using code written by others. Therefore, we use keyword arguments. If you use keyword arguments, the values are passed from the name to the correct argument, even if they are in the wrong order. -```erg +```python f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3 ``` Note that keyword arguments and a new line immediately after the `:` are considered a colon-call style. -```erg +```python # means `f(x: y)` f x: y @@ -84,7 +84,7 @@ Default parameters are used when some parameters are mostly fixed and you want t Default parameters are specified by `:=`(walrus operator). If `base` is not specified, assign `math.E` to `base`. -```erg +```python math_log x: Ratio, base := math.E = ... assert math_log(100, 10) == 2 @@ -93,7 +93,7 @@ assert math_log(100) == math_log(100, math.E) Note that there is a distinction between specifying no argument and assigning `None`. -```erg +```python p! x := 0 = print! p!(2) # 2 p!() # 0 @@ -102,20 +102,20 @@ p!(None) # None Can also be used with type specification and patterns. -```erg +```python math_log x, base: Ratio := math.E = ... f [x, y] := [1, 2] = ... ``` However, within the default arguments, it is not possible to call the procedures (described later) or assign mutable objects. -```erg +```python f x := p! 1 = ... # NG ``` Also, the argument just defined cannot be used as the value passed to the default argument. -```erg +```python f x := 1, y := x = ... # NG ``` @@ -123,13 +123,13 @@ f x := 1, y := x = ... # NG The `log` function, which outputs a log (record) of its arguments, can take any number of arguments. -```erg +```python log "Hello", "World", "!" # Hello World ! ``` To define such a function, add `...` to a parameter. This way, the function receives arguments as a variable-length array. -```erg +```python f ...x = for x, i -> log i @@ -140,7 +140,7 @@ f 1, 2, 3, 4, 5 ## Function definition with multiple patterns -```erg +```python fib n: Nat = match n: 0 -> 0 @@ -150,7 +150,7 @@ fib n: Nat = Functions like the one above, where `match` appears directly under the definition, can be rewritten as follows. -```erg +```python fib 0 = 0 fib 1 = 1 fib(n: Nat): Nat = fib(n - 1) + fib(n - 2) @@ -160,7 +160,7 @@ Note that a function definition with multiple patterns is not so-called overload If instances of different classes are mixed, the last definition must specify that the function argument is of type `Or`. -```erg +```python f "aa" = ... f 1 = ... # `f x = ... ` is invalid @@ -169,7 +169,7 @@ f x: Int or Str = ... Also, like `match`, it must also be exhaustive. -```erg +```python fib 0 = 0 fib 1 = 1 # PatternError: pattern of fib's parameter is not exhaustive @@ -177,7 +177,7 @@ fib 1 = 1 However, it can be made exhaustive by explicitly specifying the type using the [refinement type](./type/12_refinement.md) described later. -```erg +```python fib: 0..1 -> 0..1 fib 0 = 0 fib 1 = 1 @@ -191,7 +191,7 @@ A recursive function is a function that includes itself in its definition. As a simple example, let us define a function `factorial` that performs a factorial calculation. Factorial is a computation that "multiplies all positive numbers less than or equal to". The factorial of 5 is `5*4*3*2*1 == 120`. -```erg +```python factorial 0 = 1 factorial 1 = 1 factorial(n: Nat): Nat = n * factorial(n - 1) @@ -205,7 +205,7 @@ Since the definition of `factorial` contains itself, `factorial` is a recursive As a reminder, if you do not add a type specification, it is inferred like this. -```erg +```python factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int factorial 0 = 1 factorial 1 = 1 @@ -214,7 +214,7 @@ factorial n = n * factorial(n - 1) However, even if you can reason about it, you should explicitly specify the type of the recursive function. In the example above, a code like ``factorial(-1)`` would work, but -```erg +```python factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ... ``` @@ -227,7 +227,7 @@ A function name begins with an uppercase letter to indicate a compile-time funct Compile-time functions are limited in what they can do. Only constant expressions can be used in compile-time functions, i.e., only some operators (such as quadrature, comparison, and type construction operations) and compile-time functions. Arguments to be passed must also be constant expressions. In return, the advantage is that the computation can be done at compile time. -```erg +```python Add(X, Y: Nat): Nat = X + Y assert Add(1, 2) == 3 @@ -241,7 +241,7 @@ Sin X = math.sin X # ConstantError: this function is not computable at compile t Compile-time functions are also used in polymorphic type definitions. -```erg +```python Option T: Type = T or NoneType Option: Type -> Type ``` @@ -250,7 +250,7 @@ Option: Type -> Type Erg does not define `==` for functions. This is because there is no structural equivalence algorithm for functions in general. -```erg +```python f = x: Int -> (x + 1)**2 g = x: Int -> x**2 + 2x + 1 @@ -269,7 +269,7 @@ assert (lambda x: x) ! = (lambda x: x) ## Appendix2: ()-completion -```erg +```python f x: Object = ... # will be completed to f(x: Object) = ... diff --git a/doc/zh_CN/syntax/05_builtin_funcs.md b/doc/zh_CN/syntax/05_builtin_funcs.md index f0b3075a..12aa1eeb 100644 --- a/doc/zh_CN/syntax/05_builtin_funcs.md +++ b/doc/zh_CN/syntax/05_builtin_funcs.md @@ -4,7 +4,7 @@ `if` is a function that changes processing depending on a condition. -```erg +```python result: Option Int = if! Bool.sample!(), do: log "True was chosen" 1 @@ -14,7 +14,7 @@ print! result # None (or 1) `.sample!()` returns a random set of values. If the return value is true, `print! "True"` is executed. You can also specify what to do if the condition is false; the second do block is called the else block. -```erg +```python result: Nat = if Bool.sample!(): do: log "True was chosen" @@ -27,7 +27,7 @@ print! result # 1 (or 0) If the process is a single line, you can omit indentation. -```erg +```python result = if Bool.sample!(): do 1 do 0 @@ -37,7 +37,7 @@ result = if Bool.sample!(): You can use `for` to write a repeating process. -```erg +```python match_s(ss: Iterator(Str), pat: Pattern): Option Str = for ss, s -> if pat.match(s).is_some(): diff --git a/doc/zh_CN/syntax/07_side_effect.md b/doc/zh_CN/syntax/07_side_effect.md index 342cae82..1037bb36 100644 --- a/doc/zh_CN/syntax/07_side_effect.md +++ b/doc/zh_CN/syntax/07_side_effect.md @@ -2,14 +2,14 @@ We have been neglecting to explain the meaning of the `!`, but now its meaning will finally be revealed. This `!` indicates that this object is a "procedure" with a "side-effect". A procedure is a function with a side-effect. -```erg +```python f x = print! x # EffectError: functions cannot be assigned objects with side effects # hint: change the name to 'f!' ``` The above code will result in a compile error. This is because you are using a procedure in a function. In such a case, you must define it as a procedure. -```erg +```python p! x = print! x ``` @@ -21,7 +21,7 @@ Procedures defined in this way also cannot be used within a function, so side-ef Functions and procedures each can be methods. Functional methods can only take immutable references to `self`, while procedural methods can take mutable references to `self`. The `self` is a special parameter, which in the context of a method refers to the calling object itself. The reference `self` cannot be assigned to any other variable. -```erg +```python C!. method ref self = x = self # OwnershipError: cannot move out 'self' @@ -30,7 +30,7 @@ C!. Procedural methods can also take [ownership](./18_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition. -```erg +```python n = 1 s = n.into(Str) # '1' n # ValueError: n was moved by .into (line 2) @@ -40,7 +40,7 @@ Only one procedural methods can have a mutable reference at any given time. In a Note, however, that it is possible to create (immutable/mutable) references from mutable references. This allows recursion and `print!` of `self` in procedural methods. -```erg +```python T -> T # OK (move) T -> Ref T # OK (move) T => Ref! T # OK (only once) @@ -63,14 +63,14 @@ There are procedures that for any given `x` will result in `p!(x) == p!(x)` (e.g An example of the former is `print!`, and an example of the latter is the following function. -```erg +```python nan _ = Float.NaN assert nan(1) ! = nan(1) ``` There are also objects, such as classes, for which equivalence determination itself is not possible. -```erg +```python T = Structural {i = Int} U = Structural {i = Int} assert T == U @@ -88,7 +88,7 @@ Back to the point: the precise definition of "side-effect" in Erg is As an example, consider the `print!` procedure. At first glance, `print!` does not seem to rewrite any variables. But if it were a function, it could rewrite outer variables, for example, with code like this: -```erg +```python camera = import "some_camera_module" ocr = import "some_ocr_module" @@ -107,7 +107,7 @@ The direct side-effect is caused by `cam.shot!()`, but obviously that informatio Nevertheless, there may be cases where you want to temporarily check a value in a function and do not want to add `!` in the related function just for that purpose. In such cases, the `log` function can be used. `log` prints the value after the entire code has been executed. In this way, side-effects are not propagated. -```erg +```python log "this will be printed after execution" print! "this will be printed immediately" # this will be printed immediately diff --git a/doc/zh_CN/syntax/08_procedure.md b/doc/zh_CN/syntax/08_procedure.md index 44363e46..a46e863a 100644 --- a/doc/zh_CN/syntax/08_procedure.md +++ b/doc/zh_CN/syntax/08_procedure.md @@ -3,7 +3,7 @@ Procedures are necessary when dealing with mutable objects, but having a mutable object as an argument does not necessarily make it a procedure. Here is a function takes a mutable object (not procedure). -```erg +```python peek_str s: Str! = log s ``` diff --git a/doc/zh_CN/syntax/09_builtin_procs.md b/doc/zh_CN/syntax/09_builtin_procs.md index 5a78d28e..eff9af73 100644 --- a/doc/zh_CN/syntax/09_builtin_procs.md +++ b/doc/zh_CN/syntax/09_builtin_procs.md @@ -6,7 +6,7 @@ Returns the unique identification number of the object. Although in pure Erg semantics no difference can be found between objects with the same structure, in practice objects have different locations in memory. `id!` returns a number representing this position. -```erg +```python ```

diff --git a/doc/zh_CN/syntax/10_array.md b/doc/zh_CN/syntax/10_array.md index a3c8c20c..fd42f8a3 100644 --- a/doc/zh_CN/syntax/10_array.md +++ b/doc/zh_CN/syntax/10_array.md @@ -3,7 +3,7 @@ Arrays are the most basic __collection (aggregate)__. A collection is an object that can hold multiple objects inside it. -```erg +```python a = [1, 2, 3] a: [Int; 3] # Type specification: number after semicolon is the number of elements # Can be omitted if the number of elements is not known @@ -16,13 +16,13 @@ assert mut_a == [2, 2, 3] As a rule, arrays cannot contain objects of different types. -```erg. +```python. [1, "a"] # TypeError: 1st element is Int, but 2nd element is Str ``` However, you can bypass the restriction by explicitly specifying the type like this. -```erg +```python [1, "a"]: [Int or Str]. ``` @@ -30,7 +30,7 @@ However, you can bypass the restriction by explicitly specifying the type like t An array can also have multiple values taken out at once. This is called slicing. -```erg +```python l = [1, 2, 3, 4] # Same as l[1:3] in Python assert l[1.. <3] == [2, 3] @@ -43,7 +43,7 @@ assert l[..].step(2) == [2, 4] The object obtained by slicing is an (immutable) copy to an array. -```erg +```python print! Typeof l[1..2] # [Int; 4] ``` diff --git a/doc/zh_CN/syntax/11_tuple.md b/doc/zh_CN/syntax/11_tuple.md index 75a942c3..403833b5 100644 --- a/doc/zh_CN/syntax/11_tuple.md +++ b/doc/zh_CN/syntax/11_tuple.md @@ -3,7 +3,7 @@ Tuples are similar to arrays, but can hold objects of different types. Such a collection is called an unequal collection. In contrast, homogeneous collections include arrays, sets, etc. -```erg +```python t = (1, True, "a") (i, b, s) = t assert(i == 1 and b == True and s == "a") @@ -12,7 +12,7 @@ assert(i == 1 and b == True and s == "a") The tuple `t` can retrieve the nth element in the form `t.n`; note that unlike Python, it is not `t[n]`. This is because accessing tuple elements is more like an attribute (the existence of the element is checked at compile time, and the type can change depending on `n`) than a method (an array's `[]` is a method). -```erg +```python assert t.0 == 1 assert t.1 == True assert t.2 == "a" @@ -20,14 +20,14 @@ assert t.2 == "a" Parentheses `()` are optional when not nested. -```erg +```python t = 1, True, "a" i, b, s = t ``` Tuples can hold objects of different types, so they cannot be iterated like arrays. -```erg +```python t: ({1}, {2}, {3}) = (1, 2, 3) (1, 2, 3).iter().map(x -> x + 1) # TypeError: type ({1}, {2}, {3}) has no method `.iter()` # If all types are the same, they can be represented by `(T; n)` like arrays, but this still does not allow iteration @@ -38,11 +38,11 @@ assert (Int; 3) == (Int, Int, Int) However, nonhomogeneous collections (such as tuples) can be converted to homogeneous collections (such as arrays) by upcasting, intersecting, and so on. This is called equalization. -```erg +```python (Int, Bool, Str) can be [T; 3] where T :> Int, T :> Bool, T :> Str ``` -```erg +```python t: (Int, Bool, Str) = (1, True, "a") # non-homogenous a: [Int or Bool or Str; 3] = [1, True, "a"] # homogenous _a: [Show; 3] = [1, True, "a"] # homogenous @@ -54,21 +54,21 @@ t.try_into([Show; 3])? .iter().map(x -> log x) # OK A tuple with zero elements is called a __unit__. A unit is a value, but also refers to its own type. -```erg +```python unit = () (): () ``` Unit is a superclass of all element 0 tuples. -```erg +```python () > (Int; 0) () > (Str; 0) ``` The use of this object is for procedures with no arguments and no return value, etc. Erg subroutines must have arguments and a return value. However, in some cases, such as a procedure, there may be no meaningful arguments or return value, only side effects. In such cases, we use units as "meaningless, formal values. -```erg +```python # ↓ Actually, this parenthesis is a unit p!() =. # `print!` does not return a meaningful value @@ -83,7 +83,7 @@ In Erg, you should use `()` when you are sure from the beginning that the operat Actually, all of Erg's `Callable` objects are one argument and one return value; a subroutine that takes N arguments was just receiving "one tuple with N elements" as an argument. -```erg +```python # f x = ... is implicitly assumed to be f(x) = ... is considered to be f x = x assert f(1) == 1 @@ -95,14 +95,14 @@ assert (2, 3) == g 1, 2, 3 This also explains the function type. -```erg +```python assert f in T: {(T,) -> T | T} assert g in {(Int, ... (Int; N)) -> (Int; N) | N: Nat} ``` To be precise, the function's input is not a tuple but a "Named tuple with default attributes". This is a special tuple that can only be used in function arguments, can be named like a record, and can have a default value. -```erg +```python f(x: Int, y=0) = x + y f: (Int, y=Int) -> Int diff --git a/doc/zh_CN/syntax/12_dict.md b/doc/zh_CN/syntax/12_dict.md index 2bbfbfd0..3c03c35f 100644 --- a/doc/zh_CN/syntax/12_dict.md +++ b/doc/zh_CN/syntax/12_dict.md @@ -2,14 +2,14 @@ Dict is a collection of key/value pairs. -```erg +```python ids = {"Alice": 145, "Bob": 214, "Charlie": 301} assert ids["Alice"] == 145 ``` The key does not have to be a string if it is a `Hash` object. -```erg +```python # deprecated to use a range object as a key (confused with slice) r = {1..3: "1~3", 4..6: "4~6", 7..9: "7~9"} assert r[1..3] == "1~3" @@ -20,20 +20,20 @@ assert l[[]] == "empty" Order does not matter for Dict. It also cannot have duplicate elements. In this respect, Dict is similar to Set. You could say that a Dict is a Set with values. -```erg +```python {"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214} ``` When generating a dict from a dict literal, it is checked for duplicate keys. Any duplicates will result in a compile error. -```erg +```python {"Alice": 145, "Alice": 1} # KeyError: Duplicate key "Alice" ``` Empty Dict is created with `{:}`. Note that `{}` denotes an empty set. -```erg +```python mut_dict = !{:} mut_dict.insert! "Alice", 145 mut_dict.insert! "Bob", 214 @@ -44,7 +44,7 @@ assert mut_dict["Alice"] == 145 There need not be a single key/value type. Such a dictionary is called a __heterogenous dict_. -```erg +```python d: {Str: Int, Int: Str} = {"a": 1, 1: "a"} assert d["a"] == 1 assert d[1] == "a" @@ -53,7 +53,7 @@ assert d[1] == "a" However, it is not possible to assign values of the same type to keys of different types, or values of different types to keys of the same type. In such cases, use the type Or instead. -```erg +```python invalid1 = {1: "a", "a": "b"} invalid2 = {1: "a", 2: 2} diff --git a/doc/zh_CN/syntax/13_record.md b/doc/zh_CN/syntax/13_record.md index 8fb4c524..c7f8694e 100644 --- a/doc/zh_CN/syntax/13_record.md +++ b/doc/zh_CN/syntax/13_record.md @@ -3,7 +3,7 @@ A record is a collection that combines the properties of a Dict accessed by key and a tuple whose access is inspected at compile time. If you know JavaScript, think of it as a (more enhanced) kind of object literal notation. -```erg +```python john = {.name = "John"; .age = 21} assert john.name == "John" @@ -20,7 +20,7 @@ So how should we use dictionaries and records? In general, we recommend using records. Records have the advantages of being checked at compile-time for the existence of elements and of being able to specify __visibility_. Specifying visibility is equivalent to specifying public/private in Java and other languages. For details, see [visibility](./15_visibility.md) for details. -```erg +```python a = {x = 1; .y = x + 1} a.x # AttributeError: x is private # Hint: declare as `.x`. @@ -31,7 +31,7 @@ The above example may seem strange to someone familiar with JavaScript, but simp You can also explicitly specify the type of an attribute. -```erg +```python anonymous = { .name: Option! Str = ! .age = 20 @@ -41,7 +41,7 @@ anonymous.name.set! "John" A record can also have the method. -```erg +```python o = { .i = !0 .inc! ref! self = self.i.inc!() @@ -55,7 +55,7 @@ assert o.i == 1 There is a notable syntax with respect to records. When all the attribute values of a record are classes (not structural types), the record itself behaves as a type with its own attributes as required attributes. Such a type is called a record type. See the section [Record] for more details. -```erg +```python # record john = {.name = "John"} # record type @@ -74,7 +74,7 @@ Named.name # Str Records can be deconstructed as follows. -```erg +```python record = {x = 1; y = 2} {x = a; y = b} = record assert a == 1 @@ -91,7 +91,7 @@ match point: `x = ...` can also be abbreviated to `x` when there is a variable with the same name as the attribute, for example, `x = x` or `x = .x` to `x`, and `.x = .x` or `.x = x` to `.x`. However, when there is only one attribute, it must be followed by `;` to distinguish it from a set. -```erg +```python x = 1 y = 2 xy = {x; y} @@ -108,7 +108,7 @@ assert tuple.1 == 1 This syntax can be used to deconstructed a record and assign it to a variable. -```erg +```python # same as `{x = x; y = y} = xy` {x; y} = xy assert x == 1 @@ -123,7 +123,7 @@ assert b == 2 An empty record is represented by `{=}`. An empty record is also its own class, like Unit. -```erg +```python empty_record = {=} empty_record: {=} # Object: Type = {=} @@ -137,7 +137,7 @@ As an enumerated type, `{}` is an empty type that contains nothing in its elemen Conversely, the record class `{=}` has no required instance attribute, so all objects are elements of it. An `Object` is an alias of this. An `Object` (a patch of `Object`) is an element of `. __sizeof__` and other very basic provided methods. -```erg +```python AnyPatch = Patch Structural {=} . __sizeof__ self = ... .clone self = ... @@ -153,7 +153,7 @@ Also, if you define a type (such as `Int and Str`) that results in a composition Erg has another syntax, instant block, which simply returns the last value evaluated. Attributes cannot be retained. -```erg +```python x = x = 1 y = x + 1 @@ -169,7 +169,7 @@ y = A bare record (a record generated by a record literal) must be defined directly in the instance if you try to implement a method on its own. This is inefficient, and as the number of attributes increases, error messages and the like become difficult to see and use. -```erg +```python john = { name = "John Smith" age = !20 @@ -183,7 +183,7 @@ john + 1 So, in such a case, you can inherit a record class. Such a class is called a data class. This is described in [class](./type/04_class.md). -```erg +```python Person = Inherit {name = Str; age = Nat} Person. greet! ref self = print! "Hello, my name is {self::name} and I am {self::age} years old." diff --git a/doc/zh_CN/syntax/16_iterator.md b/doc/zh_CN/syntax/16_iterator.md index 302d197b..d53deb4c 100644 --- a/doc/zh_CN/syntax/16_iterator.md +++ b/doc/zh_CN/syntax/16_iterator.md @@ -2,7 +2,7 @@ An iterator is an object used to retrieve elements of a container. -```erg +```python for! 0..9, i => print! i ``` @@ -12,7 +12,7 @@ Each number (=Int object) is assigned to `i` and the following operation (=`prin Now let's look at the type signature of the `for!` procedure. -```erg +```python for!: |T: Type, I <: Iterable T| (I, T => None) => None ``` @@ -20,7 +20,7 @@ The first argument seems to accept an object of type `Iterable`. `Iterable` is a type with `.Iterator` attribute, `.iter` method in the request method. -```erg +```python Iterable T = Trait { .Iterator = {Iterator} .iter = Self(T). () -> Self.Iterator T @@ -29,7 +29,7 @@ Iterable T = Trait { The type `{Iterator}` of the `.Iterator` attribute is so-called set-kind (kind is described [here](./type/advanced/kind.md)). -```erg +```python assert [1, 2, 3] in Iterable(Int) assert 1..3 in Iterable(Int) assert [1, 2, 3].Iterator == ArrayIterator diff --git a/doc/zh_CN/syntax/17_mutability.md b/doc/zh_CN/syntax/17_mutability.md index e88b87b1..47484bfa 100644 --- a/doc/zh_CN/syntax/17_mutability.md +++ b/doc/zh_CN/syntax/17_mutability.md @@ -3,7 +3,7 @@ As we have already seen, all Erg variables are immutable. However, Erg objects have the concept of mutability. Take the following code as an example. -```erg +```python a = [1, 2, 3] a = a + [4, 5, 6] print! a # [1, 2, 3, 4, 5, 6] @@ -13,7 +13,7 @@ The above code cannot actually be executed by Erg. This is because it is not rea This code can be executed. -```erg +```python b = ![1, 2, 3] b.concat! [4, 5, 6] print! b # [1, 2, 3, 4, 5, 6] @@ -22,7 +22,7 @@ print! b # [1, 2, 3, 4, 5, 6] The final result of `a, b` looks the same, but their meanings are very different. Although `a` is a variable that represents an array of `Nat`, the objects pointed to in the first and second lines are different. The name `a` is the same, but the contents are different. -```erg +```python a = [1, 2, 3] print! id! a # 0x000002A798DFE940 _a = a + [4, 5, 6] @@ -33,14 +33,14 @@ The `id!` procedure returns the address in memory where the object resides. `b` is a `Nat` "dynamic" array. The content of the object changes, but the variables point to the same thing. -```erg +```python b = ![1, 2, 3] print! id! b # 0x000002A798DFE220 b.concat! [4, 5, 6] print! id! b # 0x000002A798DFE220 ``` -```erg +```python i = !0 if! True. do! do! i.inc!() # or i.add!(1) @@ -51,7 +51,7 @@ print! i # 1 `!` is a special operator called the __mutation operator__. It makes immutable objects mutable. The behavior of objects marked with `!` can be customized. -```erg +```python Point = Class {.x = Int; .y = Int} # In this case .x is made mutable and .y remains immutable @@ -69,7 +69,7 @@ print! p.x # 1 Unlike variables, constants point to the same thing in all scopes. Constants are declared with the `=` operator. -```erg +```python PI = 3.141592653589 match! x: PI => print! "this is pi" diff --git a/doc/zh_CN/syntax/22_subroutine.md b/doc/zh_CN/syntax/22_subroutine.md index 0128c059..c5f70cff 100644 --- a/doc/zh_CN/syntax/22_subroutine.md +++ b/doc/zh_CN/syntax/22_subroutine.md @@ -2,14 +2,14 @@ ## Func -```erg +```python some_func(x: T, y: U) -> V some_func: (T, U) -> V ``` ## Proc -```erg +```python some_proc!(x: T, y: U) => V some_proc!: (T, U) => V ``` @@ -18,7 +18,7 @@ some_proc!: (T, U) => V The method type cannot be specified externally with ``Self``. -```erg +```python .some_method(self, x: T, y: U) => () # Self.(T, U) => () takes ownership of self .some_method: Ref(Self). (T, U) => () @@ -28,7 +28,7 @@ The method type cannot be specified externally with ``Self``. In the following, assume that the type `T!` takes the type argument `N: Nat`. To specify it externally, use a type variable. -```erg +```python T!: Nat -> Type # ~> indicates the state of the type argument before and after application (in this case, self must be a variable reference) T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => () @@ -39,7 +39,7 @@ For methods that do not have `ref!`, i.e., are deprived of ownership after appli If ownership is taken, it is as follows. -```erg +```python # If you don't use N, you can omit it with _. # .some_method!: |N, X: Nat| T!(N).({X}) => T!(N+X) .some_method!|N, X: Nat|(self(N), X: Nat) => T!(N+X) @@ -51,7 +51,7 @@ It can be defined as a normal function by enclosing it with ``. Neuter alphabetic operators such as `and` and `or` can be defined as neuter operators by enclosing them with ``. -```erg +```python and(x, y, z) = x and y and z `_+_`(x: Foo, y: Foo) = x.a + y.a `-_`(x: Foo) = Foo.new(-x.a) diff --git a/doc/zh_CN/syntax/24_module.md b/doc/zh_CN/syntax/24_module.md index 2a7c92d9..98027038 100644 --- a/doc/zh_CN/syntax/24_module.md +++ b/doc/zh_CN/syntax/24_module.md @@ -2,7 +2,7 @@ Erg allows you to think of the file itself as a single record. This is called a module. -```erg: foo.er +```python: foo.er # foo.er .i = 1 ``` @@ -12,7 +12,7 @@ Erg allows you to think of the file itself as a single record. This is called a foo = {.i = 1} ``` -```erg: bar.er +```python: bar.er #bar.er foo = import "foo" print! foo # diff --git a/doc/zh_CN/syntax/32_integration_with_Python.md b/doc/zh_CN/syntax/32_integration_with_Python.md index 1948466b..945379a2 100644 --- a/doc/zh_CN/syntax/32_integration_with_Python.md +++ b/doc/zh_CN/syntax/32_integration_with_Python.md @@ -5,7 +5,7 @@ When the Erg script is compiled, a .pyc file is generated, which can simply be imported as a Python module. However, variables set to private on the Erg side cannot be accessed from Python. -```erg +```python # foo.er .public = "this is a public variable" private = "this is a private variable" @@ -30,7 +30,7 @@ All objects imported from Python are by default of type `Object`. Since no compa All APIs in the Python standard library are type specified by the Erg development team. -```erg +```python time = pyimport "time" time.sleep! 1 ``` @@ -50,7 +50,7 @@ def baz(): ... ``` -```erg +```python # foo.d.er foo = pyimport "foo" .X = declare foo.'X', Int @@ -58,14 +58,14 @@ foo = pyimport "foo" .baz! = declare foo.'baz', () => Int ``` -```erg +```python foo = pyimport "foo" assert foo.bar(1) in Int ``` This ensures type safety by performing type checking at runtime. The ``declare`` function works roughly as follows. -```erg +```python declare|S: Subroutine| sub!: S, T = # Actually, => can be cast to a function without block side effects x => diff --git a/doc/zh_CN/syntax/33_package_system.md b/doc/zh_CN/syntax/33_package_system.md index dded29be..23e5aff5 100644 --- a/doc/zh_CN/syntax/33_package_system.md +++ b/doc/zh_CN/syntax/33_package_system.md @@ -25,7 +25,7 @@ You can import `foo` and `bar` modules in `app.er`. The `bar` directory can be r A `foo` module is a module consisting of files, and a `bar` module is a module consisting of directories. The `bar` module also contains `baz` and `qux` modules. This module is simply an attribute of the `bar` module, and can be accessed from `app.er` as follows. -```erg +```python # app.er foo = import "foo" bar = import "bar" @@ -47,7 +47,7 @@ For example, a module for testing. A file ending with `.test.er` is a (white box └─ foo.test.er ./src -```erg +```python # app.er foo = import "foo" @@ -66,14 +66,14 @@ Also, files ending in ``.private.er`` are private modules and can only be access └─ qux.er ``` -```erg +```python # foo.er bar = import "bar" bar.qux bar.baz # AttributeError: module 'baz' is private ``` -```erg +```python # qux.er baz = import "baz" ``` diff --git a/doc/zh_CN/syntax/34_generator.md b/doc/zh_CN/syntax/34_generator.md index 1aef8649..12eba58e 100644 --- a/doc/zh_CN/syntax/34_generator.md +++ b/doc/zh_CN/syntax/34_generator.md @@ -2,7 +2,7 @@ Generators are special procedures that use the `yield!` procedure in a block. -```erg +```python g!() = yield! 1 yield! 2 @@ -12,7 +12,7 @@ g!() = `yield!` is a procedure defined in a block of subroutines that calls `self!.yield!`. Like `return`, it returns the value passed to it as a return value, but it has the feature of saving the current execution state of the block and executing it from the beginning when it is called again. A generator is both a procedure and an iterator; a Python generator is a function that creates an iterator, while Erg iterates directly. Procedures themselves are generally not mutable objects (no `!`), but a generator is a mutable object because its own contents can change with each execution. -```erg +```python # Generator! g!: Generator!((), Int) assert g!() == 1 @@ -22,7 +22,7 @@ assert g!() == 3 A Python-style generator can be defined as follows. -```erg +```python make_g() = () => yield! 1 yield! 2 diff --git a/doc/zh_CN/syntax/type/01_type_system.md b/doc/zh_CN/syntax/type/01_type_system.md index d45ede30..3f1ee80a 100644 --- a/doc/zh_CN/syntax/type/01_type_system.md +++ b/doc/zh_CN/syntax/type/01_type_system.md @@ -6,7 +6,7 @@ The following is a brief description of Erg's type system. Details are explained One of the unique features of Erg is that there is not much difference in syntax between (normal) variable, function (subroutine), and type (Kind) definitions. All are defined according to the syntax of normal variable and function definitions. -```erg +```python f i: Int = i + 1 f # f(1) # 2 @@ -64,7 +64,7 @@ Erg's array (Array) is what Python calls a list. `[Int; 3]` is an array class th > __Note__: `(Type; N)` is both a type and a value, so it can be used like this. > -> ```erg. +> ```python. > Types = (Int, Str, Bool) > > for! Types, T => @@ -73,7 +73,7 @@ Erg's array (Array) is what Python calls a list. `[Int; 3]` is an array class th > a: Types = (1, "aaa", True) > ``` -```erg +```python pop|T, N|(l: [T; N]): ([T; N-1], T) = [...l, last] = l (l, last) @@ -86,7 +86,7 @@ lpop|T, N|(l: [T; N]): (T, [T; N-1]) = A type ends with `!` can be rewritten internal structure. For example, the `[T; !N]` class is a dynamic array. To create an object of type `T!` from an object of type `T`, use the unary operator `!`. -```erg +```python i: Int! = !1 i.update! i -> i + 1 assert i == 2 @@ -101,7 +101,7 @@ assert mut_arr == [1, 2, 3, 4]. Types are defined as follows. -```erg +```python Point2D = {.x = Int; .y = Int} ``` @@ -115,7 +115,7 @@ As mentioned earlier, a "type" in Erg roughly means a set of objects. The following is a definition of the `Add` type, which requires `+` (the middle operator). `R, O` are the so-called type parameters, which can be a true type (class) such as `Int` or `Str`. In other languages, type parameters are given a special notation (generics, templates, etc.), but in Erg they can be defined just like normal parameters. Type parameters can also be used for types other than type objects. For example, the array type `[Int; 3]` is a syntax sugar for `Array Int, 3`. If the type implementations overlap, the user must explicitly choose one. -```erg +```python Add R = Trait { .AddO = Type . `_+_` = Self.(R) -> Self.AddO @@ -124,7 +124,7 @@ Add R = Trait { .`_+_` is an abbreviation for Add.`_+_`. The prefix operator .`+_` is a method of type `Num`. -```erg +```python Num = Add and Sub and Mul and Eq NumImpl = Patch Num NumImpl. @@ -134,7 +134,7 @@ NumImpl. Polymorphic types can be treated like functions. They can be monomorphic by specifying them as `Mul Int, Str`, etc. (in many cases, they are inferred with real arguments without specifying them). -```erg +```python 1 + 1 `_+_` 1, 1 Nat.`_+_` 1, 1 @@ -146,7 +146,7 @@ The top four lines return the same result (to be exact, the bottom one returns ` This is because `Int <: Ratio`, so `1` is downcast to `Ratio`. But this is not cast. -```erg +```python i = 1 if i: # TypeError: i: Int cannot be cast to Bool, use Int.is_zero() instead. log "a" @@ -159,7 +159,7 @@ This is because `Bool <: Int` (`True == 1`, `False == 0`). Casts to subtypes gen Erg uses static duck typing, so there is little need to explicitly specify the type. -```erg +```python f x, y = x + y ``` @@ -168,7 +168,7 @@ If `{0}, {-1}`, it is monomorphic to `Int` since it does not match `Nat`. If the `{0}` and `{1}` are enumerated types that are partial types such as `Int` and `Nat`. Enumerated types, for example, can be given names and request/implementation methods. In namespaces that have access to that type, objects that satisfy the request can use the implementation method. -```erg +```python Binary = Patch {0, 1} Binary. # self contains an instance. In this example, either 0 or 1. @@ -185,7 +185,7 @@ Binary. Thereafter, the code `0.to_bool()` is possible (although `0 as Bool == False` is defined built-in). Here is an example of a type that can actually rewrite `self` as shown in the code. -```erg +```python Binary! = Patch {0, 1}! Binary! switch! ref! self = match! self: @@ -199,7 +199,7 @@ print! b # => 0 ## Structure type (anonymous type) -```erg +```python Binary = {0, 1} ``` @@ -212,14 +212,14 @@ Such types are called structural types. When we want to emphasize its use as the The following cannot be specified. For example, you cannot specify `Int` and `Int` and `Int` and `Int` and `Int` and `Int`. For example, `Int` and `Str` are both `Add`, but `Int` and `Str` cannot be added. -```erg +```python add l: Add, r: Add = l + r # TypeError: there is no implementation of `_+_`: |T, U <: Add| (T, U) -> ``` Also, the types `A` and `B` below are not considered the same type. However, the type `O` is considered to match. -```erg +```python ... |R1; R2; O; A <: Add(R1, O); B <: Add(R2, O)| ``` diff --git a/doc/zh_CN/syntax/type/02_basic.md b/doc/zh_CN/syntax/type/02_basic.md index 3a270717..d555b8ce 100644 --- a/doc/zh_CN/syntax/type/02_basic.md +++ b/doc/zh_CN/syntax/type/02_basic.md @@ -4,7 +4,7 @@ In Erg, the type of a variable can be specified after `:` as follows. This can be done at the same time as an assignment. -```erg +```python i: Int # Declare the variable i to be of type Int i: Int = 1 j = 1 # type specification can be omitted @@ -12,7 +12,7 @@ j = 1 # type specification can be omitted You can also specify a type for ordinary expressions. -```erg +```python i = 1: Int f([1, "a"]: [Int or Str]) ``` @@ -20,7 +20,7 @@ f([1, "a"]: [Int or Str]) For simple variable assignments, most type specifications can be omitted. Type specifications are more useful when defining subroutines and types. -```erg +```python # Type specification for parameters f x, y: Array Int = ... T X, Y: Array Int = ... @@ -28,20 +28,20 @@ T X, Y: Array Int = ... Note that in the above case, `x, y` are both `Array Int`. -```erg +```python # The value of a capital variable must be a constant expression f X: Int = X ``` Alternatively, if you don't need complete information about the type argument, you can omit it with `_`. -```erg +```python g v: [T; _] = ... ``` Note, however, `_` at a type specification implies `Object`. -```erg +```python f x: _, y: Int = x + y # TypeError: + is not implemented between Object and Int ``` @@ -52,7 +52,7 @@ The left side of `<:` can only specify a class. Use `Subtypeof` or similar opera This is also often used when defining subroutines or types, rather than simply specifying variables. -```erg +```python # Subtype specification of an argument f X <: T = ... @@ -66,7 +66,7 @@ Iterable T = Trait { You can also use a subtype specification when defining a class to statically check whether the class is a subtype of the specified type. -```erg +```python # Class C is a subtype of Show C = Class Object, Impl := Show C.show self = ... # Show's required attributes. @@ -74,7 +74,7 @@ C.show self = ... # Show's required attributes. You can also specify a subtype only in specific cases. -```erg +```python K T: Eq K Int <: Show and Eq K T = Class Object @@ -87,7 +87,7 @@ K(Int). Subtype specification is recommended when implementing structural types. This is because, due to the nature of structural subtyping, typo or type specification errors will not cause errors when implementing required attributes. -```erg +```python C = Class Object C.shoe self = ... # Show is not implemented due to Typo (it is considered just a unique method). ``` @@ -96,7 +96,7 @@ C.shoe self = ... # Show is not implemented due to Typo (it is considered just a Attributes can be defined for traits and classes only in modules. -```erg +```python C = Class() C.pub_attr = "this is public" C::private_attr = "this is private" @@ -107,7 +107,7 @@ assert c.pub_attr == "this is public" The syntax for defining a batch definition is called a batch definition, in which a newline is added after `C.` or `C::` and the definitions are grouped together below the indentation. -```erg +```python C = Class() C.pub1 = ... C.pub2 = ... @@ -127,7 +127,7 @@ C:: Types can be aliased. This allows long types, such as record types, to be shortened. -```erg +```python Id = Int Point3D = {x = Int; y = Int; z = Int} IorS = Int or Str @@ -140,7 +140,7 @@ However, only one alias of the same type is allowed per module, and multiple ali This means that types with different purposes should be defined as separate types. The purpose is also to prevent adding aliases on top of types that already have aliases. -```erg +```python Id = Int UserId = Int # TypeWarning: duplicate aliases: Id and UserId diff --git a/doc/zh_CN/syntax/type/03_trait.md b/doc/zh_CN/syntax/type/03_trait.md index 9fcf79b0..ea1fb991 100644 --- a/doc/zh_CN/syntax/type/03_trait.md +++ b/doc/zh_CN/syntax/type/03_trait.md @@ -3,7 +3,7 @@ Trait is a nominal type that adds a type attribute requirement to record types. It is similar to the Abstract Base Class (ABC) in Python, but with the distinction of being able to perform algebraic operations. -```erg +```python Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int} ``` @@ -12,7 +12,7 @@ Trait does not distinguish between attributes and methods. Note that traits can only be declared, not implemented (implementation is achieved by a feature called patching, which will be discussed later). Traits can be checked for implementation in a class by specifying a partial type. -```erg +```python Point2D <: Norm Point2D = Class {.x = Int; .y = Int} Point2D.norm self = self.x**2 + self.y**2 @@ -20,14 +20,14 @@ Point2D.norm self = self.x**2 + self.y**2 Error if the required attributes are not implemented. -```erg +```python Point2D <: Norm # TypeError: Point2D is not a subtype of Norm Point2D = Class {.x = Int; .y = Int} ``` Traits, like structural types, can apply operations such as composition, substitution, and elimination (e.g. `T and U`). The resulting trait is called an instant trait. -```erg +```python T = Trait {.x = Int} U = Trait {.y = Int} V = Trait {.x = Int; y: Int} @@ -40,7 +40,7 @@ assert Structural(W) == Structural(T.replace {.x = Ratio}) Trait is also a type, so it can be used for normal type specification. -```erg +```python points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)] assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25]. ``` @@ -51,7 +51,7 @@ The expansion operator `...` allows you to define a trait that contains a certai In the example below, `BinAddSub` subsumes `BinAdd` and `BinSub`. This corresponds to Inheritance in a class, but unlike Inheritance, multiple base types can be combined using `and`. Traits that are partially excluded by `not` are also allowed. -```erg +```python Add R = Trait { .AddO = Type . `_+_` = Self.(R) -> Self.AddO @@ -69,7 +69,7 @@ BinAddSub = Subsume Add(Self) and Sub(Self) Traits can be structured. -```erg +```python SAdd = Structural Trait { . `_+_` = Self.(Self) -> Self } @@ -87,7 +87,7 @@ assert add(C.new(1), C.new(2)) == C.new(3) Nominal traits cannot be used simply by implementing a request method, but must be explicitly declared to have been implemented. In the following example, `add` cannot be used with an argument of type `C` because there is no explicit declaration of implementation. It must be `C = Class {i = Int}, Impl := Add`. -```erg +```python Add = Trait { .`_+_` = Self.(Self) -> Self } @@ -109,7 +109,7 @@ Structural traits do not need to be declared for this implementation, but instea Traits can take parameters. This is the same as for polymorphic types. -```erg +```python Mapper T: Type = Trait { .mapIter = {Iterator} .map = Self(T). (T -> U) -> Self.MapIter U @@ -127,7 +127,7 @@ assert [1, 2, 3].iter().map(x -> "{x}").collect(Array) == ["1", "2", "3"]. Derived traits can override the type definitions of the base trait. In this case, the type of the overriding method must be a subtype of the base method type. -```erg +```python # `Self.(R) -> O` is a subtype of ``Self.(R) -> O or Panic Div R, O: Type = Trait { . `/` = Self.(R) -> O or Panic @@ -142,7 +142,7 @@ SafeDiv R, O = Subsume Div, { The actual definitions of `Add`, `Sub`, and `Mul` look like this. -```erg +```python Add R = Trait { .Output = Type . `_+_` = Self.(R) -> .Output @@ -159,7 +159,7 @@ Mul R = Trait { `.Output` is duplicated. If you want to implement these multiple traits at the same time, specify the following. -```erg +```python P = Class {.x = Int; .y = Int} # P|Self <: Add(P)| can be abbreviated to P|<: Add(P)| P|Self <: Add(P)|. @@ -172,7 +172,7 @@ P|Self <: Mul(Int)|. Duplicate APIs implemented in this way are almost always type inferred when used, but can also be resolved by explicitly specifying the type with `||`. -```erg +```python print! P.Output # TypeError: ambiguous type print! P|<: Mul(Int)|.Output # ``` diff --git a/doc/zh_CN/syntax/type/04_class.md b/doc/zh_CN/syntax/type/04_class.md index f582937a..b345aa65 100644 --- a/doc/zh_CN/syntax/type/04_class.md +++ b/doc/zh_CN/syntax/type/04_class.md @@ -3,7 +3,7 @@ A class in Erg is roughly a type that can create its own elements (instances). Here is an example of a simple class. -```erg +```python Person = Class {.name = Str; .age = Nat} # If `.new` is not defined, then Erg will create `Person.new = Person::__new__` Person. @@ -22,7 +22,7 @@ In the class above, the `.new` method is defined so that field names, etc. can b Note that the following definition without line breaks will result in a syntax error. -```erg +```python Person.new name, age = ... # SyntaxError: cannot define attributes directly on an object ``` @@ -39,7 +39,7 @@ class Person: age: int ``` -```erg +```python # In Erg, this notation implies the declaration of a class attribute (not an instance attribute) Person = Class() Person. @@ -47,7 +47,7 @@ Person. age: Int ``` -```erg +```python # Erg code for the Python code above Person = Class { .name = Str @@ -61,7 +61,7 @@ In addition, dividing the attributes in this way clarifies roles such as "this a The example below illustrates this. The attribute `species` is common to all instances, so it is more natural to use it as a class attribute. However, the attribute `name` should be an instance attribute because each instance should have it individually. -```erg +```python Person = Class {name = Str} Person:: species = "human" @@ -85,7 +85,7 @@ alice.greet() # Hello, My name is Alice. Incidentally, if an instance attribute and a type attribute have the same name and the same type, a compile error occurs. This is to avoid confusion. -```erg +```python C = Class {.i = Int} C.i = 1 # AttributeError: `.i` is already defined in instance fields ``` @@ -102,7 +102,7 @@ Erg does not allow you to add class methods, but you can use [patch](./07_patch. You can also inherit from existing classes ([Inheritable](./../27_decorator.md/#inheritable) class). You can create an inherited class by using `Inherit`. The type on the left-hand side is called the derived class, and the argument type of `Inherit` on the right-hand side is called the base class (inherited class). -```erg +```python MyStr = Inherit Str # other: You can use MyStr if you set ``other: Str''. MyStr. @@ -117,7 +117,7 @@ Unlike Python, the defined Erg classes are `final` (non-inheritable) by default. To make a class inheritable, an `Inheritable` decorator must be attached to the class. Str` is one of the inheritable classes. -```erg +```python MyStr = Inherit Str # OK MyStr2 = Inherit MyStr # NG @@ -131,7 +131,7 @@ MyStr3 = Inherit InheritableMyStr # OK Classes have a different equivalence checking mechanism than types. Types are equivalence tested based on their structure. -```erg +```python Person = {.name = Str; .age = Nat} Human = {.name = Str; .age = Nat} @@ -140,7 +140,7 @@ assert Person == Human class has no equivalence relation defined. -```erg +```python Person = Class {.name = Str; .age = Nat} Human = Class {.name = Str; .age = Nat} @@ -151,7 +151,7 @@ Person == Human # TypeError: cannot compare classes We said that a class is a type that can generate its own elements, but that is not a strict description. In fact, a record type + patch can do the same thing. -```erg +```python Person = {.name = Str; .age = Nat} PersonImpl = Patch Person PersonImpl. @@ -174,7 +174,7 @@ Type checking for classes is simply a matter of checking the object's `. __class Erg enables NSTs in classes; the advantages of NSTs include robustness. When writing large programs, it is often the case that the structure of an object is coincidentally matched. -```erg +```python Dog = {.name = Str; .age = Nat} DogImpl = Patch Dog DogImpl. @@ -192,7 +192,7 @@ john.bark() # "Yelp!" The structure of `Dog` and `Person` is exactly the same, but it is obviously nonsense to allow animals to greet and humans to bark. The former is impossible, so it is safer to make it inapplicable. In such cases, it is better to use classes. -```erg +```python Dog = Class {.name = Str; .age = Nat} Dog.bark = log "Yelp!" ... @@ -207,7 +207,7 @@ Another feature is that the type attributes added by the patch are virtual and a That is, `T.x`, `T.bar` are objects that can be accessed (compile-time bound) by types compatible with `{i = Int}`, and are not defined in `{i = Int}` or `C`. In contrast, class attributes are held by the class itself. Therefore, they cannot be accessed by classes that are not in an inheritance relationship, even if they have the same structure. -```erg +```python C = Class {i = Int} C. foo self = ... @@ -233,7 +233,7 @@ There are two types of classes: regular classes, which are record classes throug The data class inherits the functionality of the record class and has features such as decomposition assignment, `==` and `hash` implemented by default, etc. On the other hand, the data class has its own equivalence relation and format display. On the other hand, if you want to define your own equivalence relations or formatting displays, you should use the normal class. -```erg +```python C = Class {i = Int} c = C.new {i = 1} d = C.new {i = 2} @@ -251,7 +251,7 @@ assert e ! = f To facilitate defining classes of type `Or`, an `Enum` is provided. -```erg +```python X = Class() Y = Class() XorY = Enum X, Y @@ -260,7 +260,7 @@ XorY = Enum X, Y Each type can be accessed as `XorY.X`, `XorY.Y` and the constructor can be obtained as `XorY.cons(X)`. `.cons` is a method that takes a class and returns its constructor. -```erg +```python x1 = XorY.new X.new() x2 = XorY.cons(X)() assert x1 == x2 @@ -270,7 +270,7 @@ assert x1 == x2 A class is a subtype of a requirement type. methods (including patch methods) of the requirement type can be used in the class. -```erg +```python T = Trait {.foo = Foo} C = Class(... , impl: T) C. diff --git a/doc/zh_CN/syntax/type/05_inheritance.md b/doc/zh_CN/syntax/type/05_inheritance.md index bb8c78f1..92607492 100644 --- a/doc/zh_CN/syntax/type/05_inheritance.md +++ b/doc/zh_CN/syntax/type/05_inheritance.md @@ -3,7 +3,7 @@ Inheritance allows you to define a new class that adds functionality or specialization to an existing class. Inheritance is similar to inclusion in a trait. The inherited class becomes a subtype of the original class. -```erg +```python NewInt = Inherit Int NewInt. plus1 self = self + 1 @@ -16,7 +16,7 @@ If you want the newly defined class to be inheritable, you must give it the `Inh You can specify an optional argument `additional` to allow the class to have additional instance attributes, but only if the class is a value class. However, you cannot add instance attributes if the class is a value class. -```erg +```python @Inheritable Person = Class {name = Str} Student = Inherit Person, additional: {id = Int} @@ -34,7 +34,7 @@ Erg is exceptionally designed not to allow inheritance of type ``Never``. Erg is [Or type](./13_algebraic.md) can also be inherited. In this case, you can remove any of the choices (multiple choices are possible with `or`) by specifying the optional argument `Excluding`. No additional choices can be added. The class to which you add an option is not a subtype of the original class. -```erg +```python Number = Class Int or Float or Complex Number.abs(self): Float = match self: @@ -48,7 +48,7 @@ RealNumber = Inherit Number, Excluding: Complex Similarly, [refinement type](./12_refinement.md) can also be specified. -```erg +```python Months = Class 0..12 MonthsNot31Days = Inherit Months, Excluding: {1, 3, 5, 7, 8, 10, 12} @@ -73,7 +73,7 @@ Next, consider the second condition. This is for type consistency. Since the der Finally, consider the third condition. This condition is unique to Erg and not often found in other object-oriented languages, again for safety. Let's look at what could go wrong if this were not the case. -```erg +```python # Bad example @Inheritable Base! = Class {x = Int!} @@ -94,7 +94,7 @@ In the inherited class `Inherited!`, the `.g!` method is overridden to transfer Erg has built this rule into the specification. -```erg +```python # OK. @Inheritable Base! = Class {x = Int!} @@ -123,7 +123,7 @@ Although it is not possible to replace traits at inheritance time, there are exa For example, `Int`, a subtype of `Real` (which implements `Add()`), appears to reimplement `Add()`. -```erg +```python Int = Class ... , Impl := Add() and ... ``` @@ -134,13 +134,13 @@ They are two different traits (`Add` is a [covariate](./advanced/variance.md), s Erg does not allow intersection, diff, and complement between normal classes. -```erg +```python Int and Str # TypeError: cannot unite classes ``` This rule prevents inheritance from multiple classes, i.e., multiple inheritance. -```erg +```python IntAndStr = Inherit Int and Str # SyntaxError: multiple inheritance of classes is not allowed ``` @@ -161,7 +161,7 @@ The first is an update operation on the inherited source class attribute. It can Overriding is different from rewriting because it is an operation to override with a more specialized method. Overrides must also be replaced by compatible types. -```erg +```python @Inheritable Base! = Class {.pub = !Int; pri = !Int} Base! @@ -180,7 +180,7 @@ Inherited! The second is an update operation on the (variable) instance attribute of the inherited source. This is also prohibited. Instance attributes of the base class may only be updated from methods provided by the base class. Regardless of the visibility of the attribute, it cannot be updated directly. However, they can be read. -```erg +```python @Inheritable Base! = Class {.pub = !Int; pri = !Int} Base! @@ -209,7 +209,7 @@ So, conversely, where should inheritance be used? One indicator is when "semanti Erg allows the type system to automatically do part of the subtype determination (e.g., Nat, where Int is greater than or equal to 0). However, for example, it is difficult to create a "string type representing a valid e-mail address" relying solely on Erg's type system. You should probably perform validation on a normal string. Then, we would like to add some kind of "warrant" to the string object that has passed validation. That is the equivalent of downcasting to an inherited class. Downcasting a `Str object` to `ValidMailAddressStr` is a one-to-one correspondence with validating that the string is in the correct email address format. -```erg +```python ValidMailAddressStr = Inherit Str ValidMailAddressStr. init s: Str = @@ -229,7 +229,7 @@ But obviously it is wrong to apply a `Dog` type object. So we will use the `Pers This way, only `Person` objects, classes that inherit from them, and `Student` objects will be accepted as arguments. This is more conservative and avoids unnecessarily assuming too much responsibility. -```erg +```python Named = {name = Str; ...} Dog = Class {name = Str; breed = Str} Person = Class {name = Str} diff --git a/doc/zh_CN/syntax/type/06_nst_vs_sst.md b/doc/zh_CN/syntax/type/06_nst_vs_sst.md index 8cc422cc..2738cf7f 100644 --- a/doc/zh_CN/syntax/type/06_nst_vs_sst.md +++ b/doc/zh_CN/syntax/type/06_nst_vs_sst.md @@ -1,6 +1,6 @@ # Nominal Subtyping vs. Structural Subtyping -```erg +```python Months = 0..12 # NST diff --git a/doc/zh_CN/syntax/type/07_patch.md b/doc/zh_CN/syntax/type/07_patch.md index 79795524..80c0b8eb 100644 --- a/doc/zh_CN/syntax/type/07_patch.md +++ b/doc/zh_CN/syntax/type/07_patch.md @@ -4,7 +4,7 @@ Erg does not allow modification of existing types and classes. This means, it is not possible to define additional methods in a class, nor to perform specialization (a language feature that monomorphizes a polymorphically declared type and defines a dedicated method, as in C++). However, there are many situations where you may want to add feature to an existing type or class, and there is a function called "patching" that allows you to do this. -```erg +```python StrReverse = Patch Str StrReverse. reverse self = self.iter().rev().collect(Str) @@ -18,7 +18,7 @@ In fact, built-in method `.reverse` is not a method of `Str`, but a method added However, patch methods have lower precedence than methods of the nominal type (class/trait) and cannot override methods of existing types. -```erg +```python StrangeInt = Patch Int StrangeInt. `_+_` = Int.`_-_` # AssignError: . `_+_` is already defined in Int @@ -28,7 +28,7 @@ If you want to override, you must inherit from the class. However, it is basically recommended not to override and to define a method with a different name. Overriding is not very easy to do because of some safety restrictions. -```erg +```python StrangeInt = Inherit Int StrangeInt. # Overriding methods must be given Override decorators. @@ -41,7 +41,7 @@ StrangeInt. Patches can be defined for a single type, and can be grouped together. -```erg +```python # foo.er StrReverse = Patch(Str) @@ -61,7 +61,7 @@ StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKeba StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase ``` -```erg +```python {StrBoosterPack; ...} = import "foo" assert "abc".reverse() == "cba" @@ -72,7 +72,7 @@ assert "to kebab case".to_kebab_case() == "to-kebab-case" If multiple patches are defined, some of them may result in duplicate implementations. -```erg +```python # foo.er StrReverse = Patch(Str) @@ -88,13 +88,13 @@ StrReverseMk2. In such a case, you can make it unique by using the __related function__ form instead of the method form. -```erg +```python assert StrReverseMk2.reverse("hello") == "olleh" ``` You can also make it unique by selectively importing. -```erg +```python {StrReverseMk2; ...} = import "foo" assert "hello".reverse() == "olleh" @@ -106,7 +106,7 @@ Patches can also relate types to each other. The `StrReverse` patch relates `Str Such a patch is called a __glue patch__. Because `Str` is a built-in type, a glue patch is necessary for users to retrofit traits. -```erg +```python Reverse = Trait { .reverse = Self.() -> Self } @@ -121,7 +121,7 @@ Only one glue patch can be defined per type/trait pair. This is because if multiple glue patches were "visible" at the same time, it would not be possible to uniquely determine which implementation to choose. However, you can swap patches when moving to another scope (module). -```erg +```python NumericStr = Inherit Str NumericStr. ... @@ -152,7 +152,7 @@ impl Reverse for String { You could say that Rust's traits are features of Erg's traits and patches. This makes Rust's traits sound more convenient, but that is not necessarily the case. -```erg +```python # Erg Reverse = Trait { .reverse = Self.() -> Self @@ -167,7 +167,7 @@ StrReverse. Because the `impl` block is objectized as a patch in Erg, selective inclusion is possible when importing from other modules. As a side-effect, it also allows implementation of external traits to external structures. Also, syntaxes such as `dyn trait` and `impl trait` are no longer required by the structure type. -```erg +```python # Erg reversible: [Reverse; 2] = [[1, 2, 3], "hello"] @@ -189,7 +189,7 @@ A patch can be defined not only for one specific type, but also for "function ty In this case, the term to which the degree of freedom is to be given is given as an argument (in the case below, `T: Type`). A patch defined in this way is called an all-symmetric patch. As you can see, an all-symmetric patch is precisely a function that returns a patch, but it can also be considered a patch in its own right. -```erg +```python FnType T: Type = Patch(T -> T) FnType(T). type = T @@ -204,7 +204,7 @@ However, this has a lower priority than nominal patches and class methods. Careful design should be used when defining structural patches, as some properties are lost by extension, such as the following. -```erg +```python # This should not be `Structural` Norm = Structural Patch {x = Int; y = Int} Norm. diff --git a/doc/zh_CN/syntax/type/10_interval.md b/doc/zh_CN/syntax/type/10_interval.md index 4c71ed4f..3d48f0b1 100644 --- a/doc/zh_CN/syntax/type/10_interval.md +++ b/doc/zh_CN/syntax/type/10_interval.md @@ -2,7 +2,7 @@ The most basic use of `Range` objects is as iterator. -```erg +```python for! 0..9, i => print! i ``` @@ -11,7 +11,7 @@ Note that unlike Python, it includes a end number. However, this is not only use for the `Range` objects. It can also be used the type. Such a type is called the Interval type. -```erg +```python i: 0..10 = 2 ``` @@ -20,7 +20,7 @@ The `Nat` type is equivalent to `0.. ExtraStatus, and elements of Status can use methods of ExtraStatus. Status = Trait {"Ok", "Error"} # ... @@ -65,7 +65,7 @@ Methods can also be added by patching. Use the `or` operator to explicitly indicate inclusion or to add a choice to an existing Enum type. -```erg +```python ExtraStatus = Status or {"Unknown"} ``` @@ -75,7 +75,7 @@ By default, a class whose requirement type is an homogeneous enumerated type can If you do not wish to do so, you can make it a wrapper class. -```erg +```python Abc = Class {"A", "B", "C"} Abc.new("A").is_uppercase() diff --git a/doc/zh_CN/syntax/type/12_refinement.md b/doc/zh_CN/syntax/type/12_refinement.md index 2aac3db8..f8df698d 100644 --- a/doc/zh_CN/syntax/type/12_refinement.md +++ b/doc/zh_CN/syntax/type/12_refinement.md @@ -5,7 +5,7 @@ Refinement type is a type constrained by a predicate expression. Enumeration typ The standard form of a refinement type is `{Elem: Type | (Pred)*}`. This means that the type is a type whose elements are `Elem` satisfying `Pred`. The type that can be used for the sifting type is [Const type](./advanced/const.md) only. -```erg +```python Nat = 0.. _ Odd = {N: Int | N % 2 == 1} Char = StrWithLen 1 @@ -22,7 +22,7 @@ It is called a refinement type because it is a type whose elements are part of a The `Pred` is called a (left-hand side) predicate expression. Like assignment expressions, it does not return a meaningful value, and only a pattern can be placed on the left-hand side. That is, expressions such as `X**2 - 5X + 6 == 0` cannot be used as refinement-type predicate expressions. In this respect, it differs from a right-hand-side predicate expression. -```erg +```python {X: Int | X**2 - 5X + 6 == 0} # SyntaxError: the predicate form is invalid. Only names can be on the left-hand side ``` @@ -34,14 +34,14 @@ However, the Erg compiler has very little knowledge of algebra, so it cannot sol It's nice that you defined `Odd`, but as it is, it doesn't look like it can be used much outside of literals. To promote an odd number in a normal `Int` object to `Odd`, i.e., to downcast an `Int` to `Odd`, you need to pass the constructor of `Odd`. For refinement types, the normal constructor `.new` may panic, and there is an auxiliary constructor called `.try_new` that returns a `Result` type. -```erg +```python i = Odd.new (0..10).sample!() i: Odd # or Panic ``` It can also be used as a type specification in `match`. -```erg +```python # i: 0..10 i = (0..10).sample! match i: @@ -58,7 +58,7 @@ However, Erg cannot currently make sub-decisions such as `Even` because it was n The enumerative/interval types introduced before are syntax sugar of the refinement type. `{a, b, ...}` is `{I: Typeof(a) | I == a or I == b or ... }`, and `a..b` is desugarized to `{I: Typeof(a) | I >= a and I <= b}`. -```erg +```python {1, 2} == {I: Int | I == 1 or I == 2} 1..10 == {I: Int | I >= 1 and I <= 10} 1... <10 == {I: Int | I >= 1 and I < 10} @@ -68,7 +68,7 @@ The enumerative/interval types introduced before are syntax sugar of the refinem Just as `_: {X}` can be rewritten as `X` (constant pattern), `_: {X: T | Pred}` can be rewritten as `X: T | Pred`. -```erg +```python # method `.m` is defined for arrays of length 3 or greater Array(T, N | N >= 3) .m(&self) = ... diff --git a/doc/zh_CN/syntax/type/13_algebraic.md b/doc/zh_CN/syntax/type/13_algebraic.md index f910147a..e214c71d 100644 --- a/doc/zh_CN/syntax/type/13_algebraic.md +++ b/doc/zh_CN/syntax/type/13_algebraic.md @@ -10,7 +10,7 @@ Union types can give multiple possibilities for types. As the name suggests, the A typical Union is the `Option` type. The `Option` type is a `T or NoneType` patch type, primarily representing values that may fail. -```erg +```python IntOrStr = Int or Str assert dict.get("some key") in (Int or NoneType) @@ -22,7 +22,7 @@ Option T = T or NoneType Intersection types are got by combining types with the `and` operation. -```erg +```python Num = Add and Sub and Mul and Eq ``` @@ -33,7 +33,7 @@ As mentioned above, normal classes cannot be combined with the `and` operation. Diff types are got by `not` operation. It is better to use `and not` as a closer notation to English text, but it is recommended to use just `not` because it fits better alongside `and` and `or`. -```erg +```python CompleteNum = Add and Sub and Mul and Div and Eq and Ord Num = CompleteNum not Div not Ord @@ -47,7 +47,7 @@ Complement types is got by the `not` operation, which is a unary operation. The Intersection with type `not T` is equivalent to Diff, and Diff with type `not T` is equivalent to Intersection. However, this way of writing is not recommended. -```erg +```python # the simplest definition of the non-zero number type NonZero = Not {0} # deprecated styles @@ -61,7 +61,7 @@ There are two algebraic types: apparent algebraic types that can be simplified a The "apparent algebraic types" include `or` and `and` of Enum, Interval, and the Record types. These are not true algebraic types because they are simplified, and using them as type specifiers will result in a Warning; to eliminate the Warning, you must either simplify them or define their types. -```erg +```python assert {1, 2, 3} or {2, 3} == {1, 2, 3} assert {1, 2, 3} and {2, 3} == {2, 3} assert -2..-1 or 1..2 == {-2, -1, 1, 2} @@ -77,7 +77,7 @@ q: Point2D = {x = 1; y = 2; z = 3} True algebraic types include the types `Or` and `And`. Classes such as `or` between classes are of type `Or`. -```erg +```python assert Int or Str == Or(Int, Str) assert Int and Marker == And(Int, Marker) ``` diff --git a/doc/zh_CN/syntax/type/15_quantified.md b/doc/zh_CN/syntax/type/15_quantified.md index 368aaaf5..9c76157a 100644 --- a/doc/zh_CN/syntax/type/15_quantified.md +++ b/doc/zh_CN/syntax/type/15_quantified.md @@ -3,14 +3,14 @@ A type variable is a variable used, for example, to specify the type of subroutine arguments, and its type is arbitrary (not monomorphic). First, as motivation for introducing type variables, consider the `id` function, which returns input as is. -```erg +```python id x: Int = x ``` The `id` function that returns the input as is is defined for the type `Int`, but this function can obviously be defined for any type. Let's use `Object` for the largest class. -```erg +```python id x: Object = x i = id 1 @@ -21,7 +21,7 @@ b = id True Sure, it now accepts arbitrary types, but there is one problem: the return type is expanded to `Object`. The return type is expanded to `Object`. I would like to see the return type `Int` if the input is of type `Int`, and `Str` if it is of type `Str`. -```erg +```python print! id 1 # id(1) + 1 # TypeError: cannot add `Object` and `Int ``` @@ -29,7 +29,7 @@ id(1) + 1 # TypeError: cannot add `Object` and `Int To ensure that the type of the input is the same as the type of the return value, use a __type variable__. Type variables are declared in `||`(type variable list). -```erg +```python id|T: Type| x: T = x assert id(1) == 1 assert id("foo") == "foo" @@ -39,7 +39,7 @@ assert id(True) == True This is called the __universal quantification (universalization)__ of the function. There are minor differences, but it corresponds to the function called generics in other languages. A universalized function is called a __polymorphic function__. Defining a polymorphic function is like defining a function of the same form for all types (Erg prohibits overloading, so the code below cannot really be written). -```erg +```python id|T: Type| x: T = x # pseudo code id x: Int = x @@ -56,7 +56,7 @@ You can also omit `|T, N| foo: [T; N]` if it can be inferred to be other than a You can also provide constraints if the type is too large for an arbitrary type. Constraints also have advantages, for example, a subtype specification allows certain methods to be used. -```erg +```python # T <: Add # => T is a subclass of Add # => can do addition @@ -68,7 +68,7 @@ In this case, `T` is satisfied by `Int`, `Ratio`, etc. So, the addition of `Int` You can also type it like this. -```erg +```python f| Y, Z: Type X <: Add Y, O1 @@ -80,7 +80,7 @@ f| If the annotation list is long, you may want to pre-declare it. -```erg +```python f: |Y, Z: Type, X <: Add(Y, O1), O1 <: Add(Z, O2), O2 <: Add(X, O3)| (X, Y, Z) -> O3 f|X, Y, Z| x: X, y: Y, z: Z = x + y + z + x @@ -90,7 +90,7 @@ Unlike many languages with generics, all declared type variables must be used ei This is a requirement from Erg's language design that all type variables are inferrable from real arguments. So information that cannot be inferred, such as the return type, is passed from real arguments; Erg allows types to be passed from real arguments. -```erg +```python Iterator T = Trait { # Passing return types from arguments. # .collect: |K: Type -> Type| Self(T). ({K}) -> K(T) @@ -104,7 +104,7 @@ it.collect(Array) # [2, 3, 4]. Type variables can only be declared during `||`. However, once declared, they can be used anywhere until they exit scope. -```erg +```python f|X|(x: X): () = y: X = x.clone() log X.__name__ @@ -117,14 +117,14 @@ f 1 You can also explicitly monophasize at the time of use as follows -```erg +```python f: Int -> Int = id|Int| ``` In that case, the specified type takes precedence over the type of the actual argument (failure to match will result in a type error that the type of the actual argument is wrong). That is, if the actual object passed can be converted to the specified type, it will be converted; otherwise, a compile error will result. -```erg +```python assert id(1) == 1 assert id|Int|(1) in Int assert id|Ratio|(1) in Ratio @@ -135,14 +135,14 @@ id|Int|("str") # TypeError: id|Int| is type `Int -> Int` but got Str When this syntax is batting against comprehensions, you need to enclose it in `()`. -```erg +```python # {id|Int| x | x <- 1..10} would be interpreted as {id | ...} will be interpreted as. {(id|Int| x) | x <- 1..10} ``` A type variable cannot be declared with the same name as a type that already exists. This is because all type variables are constants. -```erg +```python I: Type # ↓ invalid type variable, already exists f|I: Type| ... = ... @@ -152,7 +152,7 @@ f|I: Type| ... = ... Type arguments on the left-hand side are treated as bound variables by default. -```erg +```python K(T: Type, N: Nat) = ... K(T, N). foo(x) = ... @@ -160,7 +160,7 @@ K(T, N). Using another type variable name will result in a warning. -```erg +```python K(T: Type, N: Nat) = ... K(U, M). # Warning: K's type variable names are 'T' and 'N' foo(x) = ... @@ -168,7 +168,7 @@ K(U, M). # Warning: K's type variable names are 'T' and 'N' Constants are the same in all namespaces since their definition, so of course they cannot be used for type variable names. -```erg +```python N = 1 K(N: Nat) = ... # NameError: N is already defined @@ -183,7 +183,7 @@ L(M). You cannot have multiple definitions for each type argument, but you can define methods with the same name because there is no relationship between dependent types that are not assigned type arguments (non-primitive-kind) and dependent types that are assigned (primitive-kind). -```erg +```python K(I: Int) = ... K. # K is not a true type (atomic Kind), so we cannot define a method @@ -197,7 +197,7 @@ K(0). The `id` function defined in the previous section is a function that can be of any type. So what is the type of the `id` function itself? -```erg +```python print! classof(id) # |T: Type| T -> T ``` @@ -207,7 +207,7 @@ There is a restriction on the closed universal quantified type: only subroutine Like anonymous functions, polymorphic types have arbitrary type variable names, but they all have the same value. -```erg +```python assert (|T: Type| T -> T) == (|U: Type| U -> U) ``` @@ -222,14 +222,14 @@ In contrast, a type in which type variables are defined and used on the right-ha An open universal type is a supertype of all isomorphic "true" types. In contrast, a closed universal type is a subtype of all isomorphic true types. -```erg +```python (|T: Type| T -> T) < (Int -> Int) < (T -> T) ``` You may remember that closed ones are smaller/open ones are larger. But why is this so? For a better understanding, let's consider an instance of each. -```erg +```python # id: |T: Type| T -> T id|T|(x: T): T = x @@ -265,7 +265,7 @@ The important point is that there are no type arguments in the closed, polymorph In Erg, the type itself is also a value, so types that take arguments, such as function types, will probably be dependent types. In other words, polymorphic function types are both a quantified type and a dependent type. -```erg +```python PolyFn = Patch(|T| T -> T) PolyFn. type self = T # NameError: cannot find 'T' diff --git a/doc/zh_CN/syntax/type/16_subtyping.md b/doc/zh_CN/syntax/type/16_subtyping.md index e5ed7cf9..ca71245c 100644 --- a/doc/zh_CN/syntax/type/16_subtyping.md +++ b/doc/zh_CN/syntax/type/16_subtyping.md @@ -2,7 +2,7 @@ In Erg, class inclusion can be determined with the comparison operators `<`, `>`. -```erg +```python Nat < Int Int < Object 1... _ < Nat @@ -13,7 +13,7 @@ Int < Object Note that this has a different meaning than the `<:` operator. It declares that the class on the left-hand side is a subtype of the type on the right-hand side, and is meaningful only at compile-time. -```erg +```python C <: T # T: StructuralType f|D <: E| ... @@ -26,7 +26,7 @@ You can also specify `Self <: Add` for a polymorphic subtype specification, for Structural types are types for structural typing and are considered to be the same object if they have the same structure. -```erg +```python T = Structural {i = Int} U = Structural {i = Int} @@ -38,7 +38,7 @@ assert t in U In contrast, classes are types for notational typing and cannot be compared structurally to types and instances. -```erg +```python C = Class {i = Int} D = Class {i = Int} @@ -54,7 +54,7 @@ Arguments and return values of subroutines take only a single class. In other words, you cannot directly specify a structural type or a trait as the type of a function. It must be specified as "a single class that is a subtype of that type" using the partial type specification. -```erg +```python # OK f1 x, y: Int = x + y # NG @@ -68,7 +68,7 @@ Type inference in subroutines also follows this rule. When a variable in a subro ## Class upcasting -```erg +```python i: Int i as (Int or Str) i as (1..10) diff --git a/doc/zh_CN/syntax/type/17_type_casting.md b/doc/zh_CN/syntax/type/17_type_casting.md index 65ef9207..f1465b5c 100644 --- a/doc/zh_CN/syntax/type/17_type_casting.md +++ b/doc/zh_CN/syntax/type/17_type_casting.md @@ -8,7 +8,7 @@ A simple example is `1 + 2.0`: the `+`(Int, Ratio), or Int(<: Add(Ratio, Ratio)) ~~The Erg extended bytecode adds type information to BINARY_ADD, in which case the type information is Ratio-Ratio. In this case, the BINARY_ADD instruction does the casting of Int, so no special instruction specifying the cast is inserted. So, for example, even if you override a method in a child class, if you specify the parent as the type, type coercion is performed and the method is executed in the parent's method (name modification is performed at compile time to refer to the parent's method). The compiler only performs type coercion validation and name modification. The runtime does not cast objects (currently. Cast instructions may be implemented for execution optimization). ~~ -```erg +```python @Inheritable Parent = Class() Parent. @@ -31,7 +31,7 @@ child # "Hello from Parent" This behavior does not create an incompatibility with Python. In the first place, Python does not specify the type of a variable, so that all variables are typed as type variables, so to speak. Since type variables choose the smallest type they can fit, the same behavior as in Python is achieved if you do not specify a type in Erg. -```erg +```python @Inheritable Parent = Class() Parent. @@ -52,7 +52,7 @@ child # "Hello from Child" You can also use `.from` and `.into`, which are automatically implemented for types that are inherited from each other. -```erg +```python assert 1 == 1.0 assert Ratio.from(1) == 1.0 assert 1.into() == 1.0 @@ -62,7 +62,7 @@ assert 1.into() == 1.0 Since downcasting is generally unsafe and the conversion method is non-trivial, we instead implement ``TryFrom.try_from``. -```erg +```python IntTryFromFloat = Patch Int IntTryFromFloat. try_from r: Float = diff --git a/doc/zh_CN/syntax/type/advanced/erasure.md b/doc/zh_CN/syntax/type/advanced/erasure.md index 94f9e01a..ff485c46 100644 --- a/doc/zh_CN/syntax/type/advanced/erasure.md +++ b/doc/zh_CN/syntax/type/advanced/erasure.md @@ -6,7 +6,7 @@ The most common example of a type that has been type-erased is `[T, _]`. Arrays However, a type that has been type-erased becomes a supertype of a type that has not been (e.g. `[T; N] <: [T; _]`), so it can accept more objects. Objects of type `[T; N]` can of course use methods of type `[T; _]`, but the `N` information is erased after use. If the length does not change, then it is possible to use `[T; N]` in the signature. If the length remains the same, it must be indicated by a signature. -```erg +```python # Functions that are guaranteed to not change the length of the array (e.g., sort) f: [T; N] -> [T; N] # functions that do not (f: [T; N]) # functions that do not (e.g. filter) @@ -16,14 +16,14 @@ g: [T; n] -> [T; _] If you use `_` in the type specification itself, the type is upcast to `Object`. For non-type type arguments (Int, Bool, etc.), the parameter with `_` will be undefined. -```erg +```python i: _ # i: Object [_; _] == [Object; _] == Array ``` Type erasure is not the same as omitting a type specification. Once the type argument information has been erased, it will not be returned unless you assert it again. -```erg +```python implicit = (1..5).iter().map(i -> i * 2).to_arr() explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat)) ``` @@ -36,7 +36,7 @@ let partial = (1..6).iter().map(|i| i * 2).collect::>(); Erg does not allow partial omission of types, but uses higher-order kind polymorphism instead. -```erg +```python # collect is a higher-order Kind method that takes Kind hk = (1..5).iter().map(i -> i * 2).collect(Array) hk: Array(Int) diff --git a/doc/zh_CN/syntax/type/advanced/existential.md b/doc/zh_CN/syntax/type/advanced/existential.md index 5cc1ef99..34c385fa 100644 --- a/doc/zh_CN/syntax/type/advanced/existential.md +++ b/doc/zh_CN/syntax/type/advanced/existential.md @@ -3,7 +3,7 @@ If there is a for-all type corresponding to ∀, it is natural to assume that there is an existential type corresponding to ∃. Existential types are not difficult. You already know the existential type, just not consciously aware of it as such. -```erg +```python T: Trait f x: T = ... ``` @@ -11,7 +11,7 @@ f x: T = ... The trait `T` above is used as the existential type. In contrast, `T` in the lower case is only a trait, and `X` is an for-all type. -```erg +```python f|X <: T| x: X = ... ``` @@ -19,7 +19,7 @@ In fact, the existential type is replaced by an for-all type. So why is there su First of all, as we saw above, existential types do not involve type variables, which simplifies type specification. Also, since the type variable can be removed, it is possible to construct a type that would have rank 2 or higher if it were an all-presumptive type. -```erg +```python show_map f: (|T| T -> T), arr: [Show; _] = arr.map x -> y = f x @@ -30,7 +30,7 @@ show_map f: (|T| T -> T), arr: [Show; _] = However, as you can see, the existential type forgets or expands the original type, so if you do not want to expand the return type, you must use the for-all type. Conversely, types that are only taken as arguments and are not relevant to the return value may be written as existential types. -```erg +```python # id(1): I want it to be Int id|T|(x: T): T = x # |S <: Show|(s: S) -> () is redundant diff --git a/doc/zh_CN/syntax/type/advanced/mut_struct.md b/doc/zh_CN/syntax/type/advanced/mut_struct.md index 9fdd8479..b23de3c9 100644 --- a/doc/zh_CN/syntax/type/advanced/mut_struct.md +++ b/doc/zh_CN/syntax/type/advanced/mut_struct.md @@ -2,7 +2,7 @@ The ``T!`` type is described as a box type that can be replaced by any ``T`` type object. -```erg +```python Particle!State: {"base", "excited"}! = Class(... Impl := Phantom State) Particle! # This method moves the State from "base" to "excited". @@ -19,7 +19,7 @@ In other words, the length cannot be changed. To change the length, the structur This is achieved by Mutable structure (mutable) types. -```erg +```python v = [Str; !0].new() v.push! "Hello" v: [Str; !1]. @@ -30,7 +30,7 @@ Incidentally, the `[T; !N]` type is the sugar-coated syntax of the `ArrayWithLen Mutable structure types can of course be user-defined. Note, however, that there are some differences from invariant structure types in terms of the construction method. -```erg +```python Nil T = Class(Impl := Phantom T) List T, !0 = Inherit Nil T List T, N: Nat! = Class {head = T; rest = List(T, !N-1)} diff --git a/doc/zh_CN/syntax/type/advanced/newtype.md b/doc/zh_CN/syntax/type/advanced/newtype.md index bf08c2a0..96d65399 100644 --- a/doc/zh_CN/syntax/type/advanced/newtype.md +++ b/doc/zh_CN/syntax/type/advanced/newtype.md @@ -4,7 +4,7 @@ Here is the Erg version of the newtype pattern commonly used in Rust. Erg allows type aliases to be defined as follows, but they only refer to the same type. -```erg +```python UserId = Int ``` @@ -14,7 +14,7 @@ Also, for example, when designing a database system, suppose there are several t The newtype pattern is a good design pattern for such cases. -```erg +```python UserId = Class {id = Nat} UserId. new id: Nat = diff --git a/doc/zh_CN/syntax/type/advanced/overloading.md b/doc/zh_CN/syntax/type/advanced/overloading.md index 6f621555..99740240 100644 --- a/doc/zh_CN/syntax/type/advanced/overloading.md +++ b/doc/zh_CN/syntax/type/advanced/overloading.md @@ -3,7 +3,7 @@ Erg does not support __ad hoc polymorphism__. That is, multiple definitions of functions and Kinds (overloading) are not possible. However, you can reproduce the overloading behavior by using a combination of a trait and a patch. You can use traits instead of trait classes, but then all types that implement `.add1` will be covered. -```erg +```python Add1 = Trait { .add1: Self.() -> Self } @@ -24,7 +24,7 @@ Such a polymorphism by accepting all subtypes of a type is called __subtyping po If the process is exactly the same for each type, it can be written as below. The above is used when the behavior changes from class to class (but the return type is the same). A polymorphism that uses type arguments is called __parametric polymorphism__. Parametric polymorphism is often used in conjunction with subtyping, as shown below, in which case it is a combination of parametric and subtyping polymorphism. -```erg +```python add1|T <: Int or Str| x: T = x + 1 assert add1(1) == 2 assert add1(1.0) == 2.0 @@ -32,7 +32,7 @@ assert add1(1.0) == 2.0 Also, overloading of types with different numbers of arguments can be reproduced with default arguments. -```erg +```python C = Class {.x = Int; .y = Int} C. new(x, y := 0) = Self::__new__ {.x; .y} @@ -47,7 +47,7 @@ In conclusion, Erg prohibits overloading and adopts subtyping plus parametric po First, overloaded functions are distributed in their definitions. This makes it difficult to report the cause of an error when it occurs. Also, importing a subroutine may change the behavior of already defined subroutines. -```erg +```python {id; ...} = import "foo" ... id x: Int = x @@ -60,7 +60,7 @@ id "str" # TypeError: id is not implemented for Str Second, it is incompatible with default arguments. When a function with default arguments is overloaded, there is a problem with which one takes precedence. -```erg +```python f x: Int = ... f(x: Int, y := 0) = ... @@ -70,7 +70,7 @@ f(1) # which is chosen? Furthermore, it is incompatible with the declaration. The declaration `f: Num -> Num` cannot specify which definition it refers to. This is because `Int -> Ratio` and `Ratio -> Int` are not inclusive. -```erg +```python f: Num -> Num f(x: Int): Ratio = ... f(x: Ratio): Int = ... @@ -79,7 +79,7 @@ f(x: Ratio): Int = ... And the grammar is inconsistent: Erg prohibits variable reassignment, but the overloaded grammar looks like reassignment. Nor can it be replaced by an anonymous function. -```erg +```python # same as `f = x -> body` f x = body diff --git a/doc/zh_CN/syntax/type/advanced/phantom.md b/doc/zh_CN/syntax/type/advanced/phantom.md index 9abfeade..b36d8b5e 100644 --- a/doc/zh_CN/syntax/type/advanced/phantom.md +++ b/doc/zh_CN/syntax/type/advanced/phantom.md @@ -3,7 +3,7 @@ Phantom types are marker traits that exist only to provide annotations to the compiler. As a usage of phantom types, let's look at the structure of a list. -```erg +```python Nil = Class() List T, 0 = Inherit Nil List T, N: Nat = Class {head = T; rest = List(T, N-1)} @@ -11,7 +11,7 @@ List T, N: Nat = Class {head = T; rest = List(T, N-1)} This code results in an error. -```erg +```python 3 | List T, 0 = Inherit Nil ^^^ TypeConstructionError: since Nil does not have a parameter T, it is not possible to construct List(T, 0) with Nil @@ -21,7 +21,7 @@ hint: use 'Phantom' trait to consume T This error is a complaint that `T` cannot be type inferred when `List(_, 0).new Nil.new()` is used. In such a case, whatever the `T` type is, it must be consumed on the right-hand side. A type of size zero, such as a tuple of length zero, is convenient because it has no runtime overhead. -```erg +```python Nil T = Class((T; 0)) List T, 0 = Inherit Nil T List T, N: Nat = Class {head = T; rest = List(T, N-1)} @@ -31,7 +31,7 @@ This code passes compilation. But it's a little tricky to understand the intent, In such a case, a phantom type is just what you need. A phantom type is a generalized type of size 0. -```erg +```python Nil T = Class(Impl := Phantom T) List T, 0 = Inherit Nil T List T, N: Nat = Class {head = T; rest = List(T, N-1)} @@ -45,7 +45,7 @@ assert nil.__size__ == 0 Also, `Phantom` can consume arbitrary type arguments in addition to its type. In the following example, `Phantom` holds a type argument called `State`, which is a subtype object of `Str`. Again, `State` is a fake type variable that does not appear in the object's entity. -```erg +```python VM! State: {"stopped", "running"}! = Class(... State) VM!("stopped"). start ref! self("stopped" ~> "running") = diff --git a/doc/zh_CN/syntax/type/advanced/projection.md b/doc/zh_CN/syntax/type/advanced/projection.md index e9ce3ae4..57668930 100644 --- a/doc/zh_CN/syntax/type/advanced/projection.md +++ b/doc/zh_CN/syntax/type/advanced/projection.md @@ -2,7 +2,7 @@ A projection type represents a type such as ``Self.AddO`` in the following code. -```erg +```python Add R = Trait { . `_+_` = Self, R -> Self.AddO .AddO = Type @@ -16,7 +16,7 @@ AddForInt. The type ``Add(R)`` can be said to be a type that defines addition with some object. Since the method should be a type attribute, the `+` type declaration should be written below the indentation. The mise-en-scène of the `Add` type is the declaration `.AddO = Type`, and the entity of the `.AddO` type, which is a projective type, is held by a type that is a subtype of `Add`. For example, `Int.AddO = Int`, `Odd.AddO = Even`. -```erg +```python assert Int < Add assert Int.AddO == Int assert Odd < Add diff --git a/doc/zh_CN/syntax/type/advanced/quantified_dependent.md b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md index 28afb5ed..623f206f 100644 --- a/doc/zh_CN/syntax/type/advanced/quantified_dependent.md +++ b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md @@ -2,7 +2,7 @@ Erg has quantified and dependent types. Then naturally, it is possible to create a type that combines the two. That is the quantified dependent type. -```erg +```python NonNullStr = |N: Nat| StrWithLen N | N ! = 0 # same as {S | N: Nat; S: StrWithLen N; N ! = 0} NonEmptyArray = |N: Nat| [_; N | N > 0] # same as {A | N: Nat; A: Array(_, N); N > 0} ``` @@ -11,7 +11,7 @@ The standard form of quantified dependent types are `K(A, ... | Pred)`. ``K`` is Quantified dependent types as left-hand side values can only define methods in the same module as the original type. -```erg +```python K A: Nat = Class ... K(A). ... @@ -21,7 +21,7 @@ K(A | A >= 1). Quantified dependent types as right-hand side values require that the type variable to be used be declared in the type variable list (`||`). -```erg +```python # T is a concrete type a: |N: Nat| [T; N | N > 1] ``` diff --git a/doc/zh_CN/syntax/type/advanced/shared.md b/doc/zh_CN/syntax/type/advanced/shared.md index ccc907ae..69b7cb7e 100644 --- a/doc/zh_CN/syntax/type/advanced/shared.md +++ b/doc/zh_CN/syntax/type/advanced/shared.md @@ -21,7 +21,7 @@ The relation `VIPMember[] <: NormalMember[]` is fine for immutable objects. Howe In Erg, such code is played back due to the ownership system. -```erg +```python NormalMember = Class() VIPMember = Class() @@ -35,7 +35,7 @@ log vip_area # OwnershipError: `vip_room` was moved to `normal_room` However, it can be inconvenient for an object to be owned by only one place. For this reason, Erg has a type `SharedCell!T!`, which represents a shared state. -```erg +```python $p1 = SharedCell!.new(!1) $p2 = $p1.mirror!() $p3 = SharedCell!.new(!1) @@ -57,7 +57,7 @@ The `SharedCell! T!` type is also a subtype of `T!` and can call methods of type An important fact is that `SharedCell! T!` is non-variant, i.e., no inclusions are defined for different type arguments. -```erg +```python $vip_area = SharedCell!.new([].into [VIPMember; !_]) $normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError: expected SharedCell!([NormalMember; !_]), but got SharedCell!([VIPMember; !_]) # hint: SharedCell!(T) is non-variant, which means it cannot have a supertype or a subtype. @@ -65,7 +65,7 @@ $normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError: However, the following code have not problem. In the last line, it's the `VIPMember` argument that has been typed converted. -```erg +```python $normal_area = SharedCell!.new([].into [NormalMember; !_]) $normal_area.push!(NormalMember.new()) # OK $normal_area.push!(VIPMember.new()) # OK diff --git a/doc/zh_CN/tips.md b/doc/zh_CN/tips.md index b90de192..1baf322d 100644 --- a/doc/zh_CN/tips.md +++ b/doc/zh_CN/tips.md @@ -7,7 +7,7 @@ However, external libraries may not support multiple languages. ## Want to change only certain attributes of a record -```erg +```python record: {.name = Str; .age = Nat; .height = CentiMeter} {height; rest; ...} = record mut_record = {.height = !height; ...rest} @@ -17,7 +17,7 @@ mut_record = {.height = !height; ...rest} Shadowing in the same scope is not possible with Erg. However, you can redefine them if the scope changes (This is a syntax called instance block). -````erg +````python ## Get a T!-type object and finally assign it to a variable as type T x: T = x: T! = foo() @@ -29,7 +29,7 @@ x: T = You can create a wrapper class. This is a so-called composition pattern. -```erg +```python FinalWrapper = Class {inner = FinalClass} FinalWrapper. method self = @@ -43,7 +43,7 @@ You can define a traditional enumerated type (algebraic data type) commonly foun If you implement `Singleton`, classes and instances are identical. Also, if you use `Enum`, the type of choice is automatically defined as a redirect attribute. -```erg +```python Ok = Class Impl := Singleton Err = Class Impl := Singleton ErrWithInfo = Inherit {info = Str} @@ -55,7 +55,7 @@ match! stat: Status.ErrWithInfo::{info} -> ... ``` -```erg +```python Status = Enum Ok, Err, ErrWithInfo # is equivalent to Status = Class Ok or Err or ErrWithInfo @@ -69,7 +69,7 @@ Status. method 1: -```erg +```python arr = [...] for! arr.iter().enumerate(start: 1), i => ... @@ -77,7 +77,7 @@ for! arr.iter().enumerate(start: 1), i => method 2: -```erg +```python arr = [...] for! arr.iter().zip(1...) , i => ... @@ -88,12 +88,12 @@ for! arr.iter().zip(1...) , i => The private API in `foo.er` is specially accessible in the module `foo.test.er`. The `foo.test.er` module cannot be imported, so it remains hidden. -```erg +```python # foo.er private x = ... ``` -```erg +```python # foo.test.er foo = import "foo" @@ -108,7 +108,7 @@ foo = import "foo" You can make the attribute private and define a getter. -```erg +```python C = Class {v = Int!} C:: inc_v!(ref! self) = self::v.inc!() @@ -122,7 +122,7 @@ C. You can receive arguments by record. -```erg +```python Point = {x = Int; y = Int} norm: Point -> Int From cd602f0b004fb52a85cb8512f9c93e9942315fd3 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 12:10:03 +0800 Subject: [PATCH 08/42] translate save --- doc/zh_CN/API/operators.md | 2 +- doc/zh_CN/API/procs.md | 2 +- doc/zh_CN/API/special.md | 2 +- doc/zh_CN/API/types.md | 2 +- .../API/types/classes/ArrayWithLen(T,N).md | 4 +-- .../types/classes/ArrayWithMutLength!(T,N).md | 2 +- doc/zh_CN/API/types/classes/Complex.md | 8 ++--- doc/zh_CN/API/types/classes/Dict!.md | 2 +- doc/zh_CN/API/types/classes/Either.md | 2 +- doc/zh_CN/API/types/classes/Float.md | 6 ++-- doc/zh_CN/API/types/classes/Function(N).md | 2 +- doc/zh_CN/API/types/classes/Int.md | 4 +-- doc/zh_CN/API/types/classes/IntRange.md | 2 +- doc/zh_CN/API/types/classes/Matrix.md | 2 +- doc/zh_CN/API/types/classes/Module.md | 2 +- doc/zh_CN/API/types/classes/Nat.md | 4 +-- doc/zh_CN/API/types/classes/Neg.md | 2 +- doc/zh_CN/API/types/classes/NonZero.md | 2 +- doc/zh_CN/API/types/classes/Object.md | 2 +- doc/zh_CN/API/types/classes/Operator.md | 2 +- doc/zh_CN/API/types/classes/Option.md | 2 +- doc/zh_CN/API/types/classes/Pos.md | 2 +- doc/zh_CN/API/types/classes/Str.md | 2 +- doc/zh_CN/API/types/classes/Subroutine.md | 2 +- doc/zh_CN/API/types/classes/Tuple.md | 2 +- doc/zh_CN/API/types/patches/BinOp.md | 2 +- doc/zh_CN/API/types/patches/UnaryOp.md | 2 +- doc/zh_CN/API/types/traits/Add(R,O).md | 4 +-- doc/zh_CN/API/types/traits/Into.md | 2 +- doc/zh_CN/API/types/traits/Num.md | 6 ++-- doc/zh_CN/compiler/hir.md | 2 +- doc/zh_CN/compiler/inference.md | 2 +- doc/zh_CN/compiler/overview.md | 2 +- doc/zh_CN/compiler/trait_method_resolving.md | 12 +++---- doc/zh_CN/compiler/type_var_normalization.md | 2 +- doc/zh_CN/dev_guide/rust_code_guideline.md | 4 +-- doc/zh_CN/dev_guide/terms.md | 8 ++--- doc/zh_CN/python/class_system.md | 4 +-- doc/zh_CN/syntax/04_function.md | 2 +- doc/zh_CN/syntax/07_side_effect.md | 10 +++--- doc/zh_CN/syntax/13_record.md | 2 +- doc/zh_CN/syntax/16_iterator.md | 2 +- doc/zh_CN/syntax/19_visibility.md | 12 +++---- doc/zh_CN/syntax/20_naming_rule.md | 2 +- doc/zh_CN/syntax/22_subroutine.md | 2 +- doc/zh_CN/syntax/24_module.md | 2 +- doc/zh_CN/syntax/25_object_system.md | 6 ++-- doc/zh_CN/syntax/31_pipeline.md | 2 +- doc/zh_CN/syntax/container_ownership.md | 2 +- doc/zh_CN/syntax/indexes.md | 2 +- doc/zh_CN/syntax/quick_tour.md | 2 +- doc/zh_CN/syntax/type/01_type_system.md | 4 +-- doc/zh_CN/syntax/type/03_trait.md | 2 +- doc/zh_CN/syntax/type/04_class.md | 6 ++-- doc/zh_CN/syntax/type/05_inheritance.md | 8 ++--- doc/zh_CN/syntax/type/06_nst_vs_sst.md | 2 +- doc/zh_CN/syntax/type/07_patch.md | 34 +++++++++---------- doc/zh_CN/syntax/type/11_enum.md | 8 ++--- doc/zh_CN/syntax/type/14_dependent.md | 2 +- doc/zh_CN/syntax/type/15_quantified.md | 10 +++--- doc/zh_CN/syntax/type/18_mut.md | 2 +- doc/zh_CN/syntax/type/advanced/erasure.md | 2 +- doc/zh_CN/syntax/type/advanced/kind.md | 6 ++-- doc/zh_CN/syntax/type/advanced/newtype.md | 4 +-- doc/zh_CN/syntax/type/advanced/phantom.md | 2 +- .../type/advanced/quantified_dependent.md | 2 +- doc/zh_CN/syntax/type/advanced/shared.md | 2 +- doc/zh_CN/syntax/type/advanced/variance.md | 6 ++-- 68 files changed, 134 insertions(+), 134 deletions(-) diff --git a/doc/zh_CN/API/operators.md b/doc/zh_CN/API/operators.md index 5c767571..82c43c93 100644 --- a/doc/zh_CN/API/operators.md +++ b/doc/zh_CN/API/operators.md @@ -1,4 +1,4 @@ -# 操作员 +# 操作员 ## 中缀运算符 diff --git a/doc/zh_CN/API/procs.md b/doc/zh_CN/API/procs.md index dfbdcff9..914c8846 100644 --- a/doc/zh_CN/API/procs.md +++ b/doc/zh_CN/API/procs.md @@ -8,7 +8,7 @@ 使用换行符返回 x。 -##调试&排除; +## 调试&排除; ``` erg 调试!(x,类型=信息)-> NoneType diff --git a/doc/zh_CN/API/special.md b/doc/zh_CN/API/special.md index f9775d6f..8f90dd40 100644 --- a/doc/zh_CN/API/special.md +++ b/doc/zh_CN/API/special.md @@ -34,7 +34,7 @@ print! L # `=` 运算符的返回值为“未定义”。 函数中的多个赋值和 `=` 会导致语法错误。 -``` 呃 +``` erg i = j = 1 # SyntaxError: 不允许多次赋值 print!(x=1) # SyntaxError: cannot use `=` in function arguments # 提示:您的意思是关键字参数(`x: 1`)吗? diff --git a/doc/zh_CN/API/types.md b/doc/zh_CN/API/types.md index 7d564d92..7737ec9f 100644 --- a/doc/zh_CN/API/types.md +++ b/doc/zh_CN/API/types.md @@ -41,7 +41,7 @@ Trait 类相当于 Python 中的 ABC(抽象基类,接口) ### 类型 -* `__supers__`:超类型(`__mro__` 是一个数组,但这个是一个 Set) +* `__父类__`:超类型(`__mro__` 是一个数组,但这个是一个 Set) * `__basicsize__`: * `__dictoffset__`:Evm 不支持 * `__flags__`: 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 305b0142..074bbe5d 100644 --- a/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md +++ b/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md @@ -2,7 +2,7 @@ `[T; N]`是语法糖。还有一个[`Array` 类型](./Array.md)省略了长度。 -## methods +## 方法 * values_at(self, selectors: [Nat; N]) -> [T; N] @@ -23,7 +23,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] assert all(False for _ in []) ``` -## methods of ArrayWithLen T, N | T <: Eq +## ArrayWithLen T, N | T <: Eq 的方法 * freq self -> [{T: Nat}] 返回对象出现的次数。 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..842084ca 100644 --- a/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md +++ b/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md @@ -2,7 +2,7 @@ 一个可变长度数组,其长度在编译时已知。还有语法糖`ArrayWithMutLength(T, !N) == [T; !N]` -## methods +## 方法 * push! ref! self(N ~> N+1, ...), elem: T diff --git a/doc/zh_CN/API/types/classes/Complex.md b/doc/zh_CN/API/types/classes/Complex.md index 521b5b56..e9e8b49a 100644 --- a/doc/zh_CN/API/types/classes/Complex.md +++ b/doc/zh_CN/API/types/classes/Complex.md @@ -1,12 +1,12 @@ # Complex -表示复数的类型。 在 Erg 中表示数字的类型,例如 Float、Int 和 Nat,通常在顶部有这种类型 +表示复数的类型。在 Erg 中表示数字的类型,例如 Float、Int和Nat,通常派生于Complex -## supers +## 父类 -Num and Norm +Num 和 Norm -## methods +## 方法 * abs * conjugate diff --git a/doc/zh_CN/API/types/classes/Dict!.md b/doc/zh_CN/API/types/classes/Dict!.md index 0c5fa58e..49d244a7 100644 --- a/doc/zh_CN/API/types/classes/Dict!.md +++ b/doc/zh_CN/API/types/classes/Dict!.md @@ -2,6 +2,6 @@ 表示字典(哈希Map)的类型。 有一个语法糖叫做`{K: V}` -## methods +## 方法 * invert!(self) -> Self! V, K diff --git a/doc/zh_CN/API/types/classes/Either.md b/doc/zh_CN/API/types/classes/Either.md index 900cc4d3..43a45deb 100644 --- a/doc/zh_CN/API/types/classes/Either.md +++ b/doc/zh_CN/API/types/classes/Either.md @@ -2,7 +2,7 @@ 表示L或R的类型。 您可以将其视为Or类型的二元形式 -## methods +## 方法 * orl * orr diff --git a/doc/zh_CN/API/types/classes/Float.md b/doc/zh_CN/API/types/classes/Float.md index 02fe7aa8..a71be823 100644 --- a/doc/zh_CN/API/types/classes/Float.md +++ b/doc/zh_CN/API/types/classes/Float.md @@ -4,11 +4,11 @@ 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 +Complex 和 Ord -## methods +## 方法 * sgn(self) -> {-1, 0, 1} 返回标志 diff --git a/doc/zh_CN/API/types/classes/Function(N).md b/doc/zh_CN/API/types/classes/Function(N).md index 24195350..4317a8ea 100644 --- a/doc/zh_CN/API/types/classes/Function(N).md +++ b/doc/zh_CN/API/types/classes/Function(N).md @@ -1,6 +1,6 @@ # Function N: Nat -## methods of Function 1 +## Function 1 的方法 * then(self, g: Self) -> Self diff --git a/doc/zh_CN/API/types/classes/Int.md b/doc/zh_CN/API/types/classes/Int.md index 98846f2d..3bd560e8 100644 --- a/doc/zh_CN/API/types/classes/Int.md +++ b/doc/zh_CN/API/types/classes/Int.md @@ -5,6 +5,6 @@ 建议使用 Nat、NZInt、Interval 类型等。 Int是一种来自 Python 的类型,只有`Object`作为其超类型。 -## supers +## 父类 -## methods +## 方法 diff --git a/doc/zh_CN/API/types/classes/IntRange.md b/doc/zh_CN/API/types/classes/IntRange.md index e379badd..e84bb7b1 100644 --- a/doc/zh_CN/API/types/classes/IntRange.md +++ b/doc/zh_CN/API/types/classes/IntRange.md @@ -6,7 +6,7 @@ IntRange L, R: Int == L..R ``` -## methods +## 方法 * .`_+_`: Self(L1, R1), Self(L2, R2) -> Self(L1+L2, R1+R2) diff --git a/doc/zh_CN/API/types/classes/Matrix.md b/doc/zh_CN/API/types/classes/Matrix.md index 902029b2..bbb43b4f 100644 --- a/doc/zh_CN/API/types/classes/Matrix.md +++ b/doc/zh_CN/API/types/classes/Matrix.md @@ -2,6 +2,6 @@ 表示矩阵的类型。 它继承自 Tensor[M, N] -## def +## 定义 Inherit Tensor T, [M, N] diff --git a/doc/zh_CN/API/types/classes/Module.md b/doc/zh_CN/API/types/classes/Module.md index 03b89e9f..547f7253 100644 --- a/doc/zh_CN/API/types/classes/Module.md +++ b/doc/zh_CN/API/types/classes/Module.md @@ -1,3 +1,3 @@ # Module -## methods +## 方法 diff --git a/doc/zh_CN/API/types/classes/Nat.md b/doc/zh_CN/API/types/classes/Nat.md index 0e6d0d1f..05911648 100644 --- a/doc/zh_CN/API/types/classes/Nat.md +++ b/doc/zh_CN/API/types/classes/Nat.md @@ -2,13 +2,13 @@ 表示自然数的类型。 用于数组索引和范围类型 -## def +## 定义 ```python Nat = 0.._ ``` -## methods +## 方法 * times!(self, p: () => NoneType) -> NoneType diff --git a/doc/zh_CN/API/types/classes/Neg.md b/doc/zh_CN/API/types/classes/Neg.md index 7005a062..7298453f 100644 --- a/doc/zh_CN/API/types/classes/Neg.md +++ b/doc/zh_CN/API/types/classes/Neg.md @@ -3,6 +3,6 @@ 表示负整数的类型。 Pos和Neg和{0} == Int 它还具有一些值得注意的属性,例如不被零除和 Neg * Neg == Pos -## def +## 定义 Inf<..-1 diff --git a/doc/zh_CN/API/types/classes/NonZero.md b/doc/zh_CN/API/types/classes/NonZero.md index 9a7d53b7..b73422a0 100644 --- a/doc/zh_CN/API/types/classes/NonZero.md +++ b/doc/zh_CN/API/types/classes/NonZero.md @@ -24,7 +24,7 @@ classDiagram Div <|.. Int: Impl ``` -## methods +## 方法 @Impl SafeDiv R, O .`/`: Self.(R) -> O diff --git a/doc/zh_CN/API/types/classes/Object.md b/doc/zh_CN/API/types/classes/Object.md index 963f58f1..79a6e635 100644 --- a/doc/zh_CN/API/types/classes/Object.md +++ b/doc/zh_CN/API/types/classes/Object.md @@ -2,6 +2,6 @@ 它是所有类型的超类型 -## methods +## 方法 * __sizeof__: Nat diff --git a/doc/zh_CN/API/types/classes/Operator.md b/doc/zh_CN/API/types/classes/Operator.md index 0b26bbe9..581e7ac5 100644 --- a/doc/zh_CN/API/types/classes/Operator.md +++ b/doc/zh_CN/API/types/classes/Operator.md @@ -2,6 +2,6 @@ 是运算符的类型 -## def +## 定义 Inherit Func [...T], O diff --git a/doc/zh_CN/API/types/classes/Option.md b/doc/zh_CN/API/types/classes/Option.md index 8018eb32..bbcefdf9 100644 --- a/doc/zh_CN/API/types/classes/Option.md +++ b/doc/zh_CN/API/types/classes/Option.md @@ -2,7 +2,7 @@ 表示“可能失败”的类型。 -## methods +## 方法 * unwrap(self, msg = "unwrapped a None value") -> T or Panic diff --git a/doc/zh_CN/API/types/classes/Pos.md b/doc/zh_CN/API/types/classes/Pos.md index 44831482..d28285f9 100644 --- a/doc/zh_CN/API/types/classes/Pos.md +++ b/doc/zh_CN/API/types/classes/Pos.md @@ -3,6 +3,6 @@ Pos是一种表示正数(大于或等于1的整数)的类型。 由于不包括0,因此具有消除被零除的可能性等优点。 -## Def +## 定义 `Pos = 1.._` diff --git a/doc/zh_CN/API/types/classes/Str.md b/doc/zh_CN/API/types/classes/Str.md index 9b4f21b8..d87eff6d 100644 --- a/doc/zh_CN/API/types/classes/Str.md +++ b/doc/zh_CN/API/types/classes/Str.md @@ -2,7 +2,7 @@ (不变长度)表示字符串的类型。 简单的 `Str` 类型是删除了字符数的 `StrWithLen N` 类型(`Str = StrWithLen _`) -## methods +## 方法 * isnumeric diff --git a/doc/zh_CN/API/types/classes/Subroutine.md b/doc/zh_CN/API/types/classes/Subroutine.md index 5738381b..60bd76de 100644 --- a/doc/zh_CN/API/types/classes/Subroutine.md +++ b/doc/zh_CN/API/types/classes/Subroutine.md @@ -2,7 +2,7 @@ Func和Proc的基本类型。 -## methods +## 方法 * return diff --git a/doc/zh_CN/API/types/classes/Tuple.md b/doc/zh_CN/API/types/classes/Tuple.md index 8ea7b645..49551099 100644 --- a/doc/zh_CN/API/types/classes/Tuple.md +++ b/doc/zh_CN/API/types/classes/Tuple.md @@ -2,7 +2,7 @@ 包含多种类型对象的集合 -## methods +## 方法 * zip self, other diff --git a/doc/zh_CN/API/types/patches/BinOp.md b/doc/zh_CN/API/types/patches/BinOp.md index b10cd654..8494aa4f 100644 --- a/doc/zh_CN/API/types/patches/BinOp.md +++ b/doc/zh_CN/API/types/patches/BinOp.md @@ -2,6 +2,6 @@ 二元运算符的类型 -## Patches +## 修补程序 Operator [L, R], O diff --git a/doc/zh_CN/API/types/patches/UnaryOp.md b/doc/zh_CN/API/types/patches/UnaryOp.md index e06e07af..6b56481a 100644 --- a/doc/zh_CN/API/types/patches/UnaryOp.md +++ b/doc/zh_CN/API/types/patches/UnaryOp.md @@ -2,6 +2,6 @@ 一元运算符的类型 -## def +## 定义 Operator [T], O diff --git a/doc/zh_CN/API/types/traits/Add(R,O).md b/doc/zh_CN/API/types/traits/Add(R,O).md index f9ee06b3..4d8b6220 100644 --- a/doc/zh_CN/API/types/traits/Add(R,O).md +++ b/doc/zh_CN/API/types/traits/Add(R,O).md @@ -14,7 +14,7 @@ Add R = Trait { `_+_`(l: Add(R, O), r: R): O = l.`_+_` r ``` -わざわざこの定義があるのは、`+`をメソッドではなく関数として取り扱えるようにである。 +这个定义的目的是让 `+` 可以被视为一个函数而不是一个方法 ```python assert [1, 2, 3].fold(0, `_+_`) == 6 @@ -23,7 +23,7 @@ call op, x, y = op(x, y) assert call(`_+_`, 1, 2) == 3 ``` -加算はこのように型付けされる。 +加法是这样输入的 ```python f: |O: Type; A <: Add(Int, O)| A -> O diff --git a/doc/zh_CN/API/types/traits/Into.md b/doc/zh_CN/API/types/traits/Into.md index 53c8e9a8..de92a824 100644 --- a/doc/zh_CN/API/types/traits/Into.md +++ b/doc/zh_CN/API/types/traits/Into.md @@ -4,7 +4,7 @@ 即使Self和T之间没有继承关系,也是在关系可以相互转换的时候定义的。 与继承不同,没有隐式转换。您必须始终调用 `.into` 方法。 -## methods +## 方法 * into(self, T) -> T diff --git a/doc/zh_CN/API/types/traits/Num.md b/doc/zh_CN/API/types/traits/Num.md index 377da536..d5e3b2d8 100644 --- a/doc/zh_CN/API/types/traits/Num.md +++ b/doc/zh_CN/API/types/traits/Num.md @@ -1,16 +1,16 @@ # Num -## definition +## 定义初始化 ```python 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_CN/compiler/hir.md b/doc/zh_CN/compiler/hir.md index 29e9ca14..69f2b3f0 100644 --- a/doc/zh_CN/compiler/hir.md +++ b/doc/zh_CN/compiler/hir.md @@ -1,4 +1,4 @@ -# 高レベル中間表現(HIR, High-level Intermediate Representation) +# 高级中间表示(HIR, High-level Intermediate Representation) HIR 是 Erg 编译器从 AST 生成的结构 此结构包含源代码中每个表达式的完整类型信息,并且在语法上已脱糖 diff --git a/doc/zh_CN/compiler/inference.md b/doc/zh_CN/compiler/inference.md index 4f513eb2..628e1309 100644 --- a/doc/zh_CN/compiler/inference.md +++ b/doc/zh_CN/compiler/inference.md @@ -28,7 +28,7 @@ Erg's type inference largely uses the Hindley-Milner type inference algorithm (a 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 +7. Propagate changes for mutable dependent 方法 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) diff --git a/doc/zh_CN/compiler/overview.md b/doc/zh_CN/compiler/overview.md index 8cd43ef0..bdbdd075 100644 --- a/doc/zh_CN/compiler/overview.md +++ b/doc/zh_CN/compiler/overview.md @@ -1,6 +1,6 @@ # overview of `erg` -We will introduce the function of each layer and the particularly important functions and methods. +We will introduce the function of each layer and the particularly important functions and 方法. ## 1. Lexical Analysis diff --git a/doc/zh_CN/compiler/trait_method_resolving.md b/doc/zh_CN/compiler/trait_method_resolving.md index f0d8b1a6..2e44e180 100644 --- a/doc/zh_CN/compiler/trait_method_resolving.md +++ b/doc/zh_CN/compiler/trait_method_resolving.md @@ -1,4 +1,4 @@ -# Resolving patch methods +# Resolving patch 方法 `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? @@ -22,9 +22,9 @@ As for `Complex`, even though it is a class that does not have an inheritance re ~ 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. +But we really only have to think about types with 方法, i.e. types with names. -The Erg compiler has a hashmap of patch types with all provided methods and their implementations. +The Erg compiler has a hashmap of patch types with all provided 方法 and their implementations. This table is updated each time a new type is defined. ``` erg @@ -49,12 +49,12 @@ In this case, `Nat` is `0.._ == {I: Int | I >= 0}`, so `{1}` is compatible with ## Determine record type 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. +Others that are 修补程序 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. +That is, subtype 方法 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. @@ -62,7 +62,7 @@ To eliminate the error, you need to specify the patch explicitly. o.method(x) -> P.method(o, x) ``` -## method resolution for universal patches +## method resolution for universal 修补程序 Define a patch like this: diff --git a/doc/zh_CN/compiler/type_var_normalization.md b/doc/zh_CN/compiler/type_var_normalization.md index 3c4fccfc..391e814c 100644 --- a/doc/zh_CN/compiler/type_var_normalization.md +++ b/doc/zh_CN/compiler/type_var_normalization.md @@ -3,7 +3,7 @@ * 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. +Equality judgment naturally has its limits, but the judgments that are possible at present and their 方法 are as follows. * Addition/multiplication symmetry: diff --git a/doc/zh_CN/dev_guide/rust_code_guideline.md b/doc/zh_CN/dev_guide/rust_code_guideline.md index fa26af68..17be981f 100644 --- a/doc/zh_CN/dev_guide/rust_code_guideline.md +++ b/doc/zh_CN/dev_guide/rust_code_guideline.md @@ -3,7 +3,7 @@ ## 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. +* Unused or internal variables/方法 (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 @@ -19,5 +19,5 @@ ## Code that makes decisions based on context -* Define unused helper methods. +* Define unused helper 方法. * 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 d3bbc42f..01ba474a 100644 --- a/doc/zh_CN/dev_guide/terms.md +++ b/doc/zh_CN/dev_guide/terms.md @@ -316,7 +316,7 @@ An object that applies an operation to its operands. or a symbol denoting that o ### Override -Overriding superclass methods in subclasses. +Overriding superclass 方法 in subclasses. In Erg you have to add `Override` decorator when overriding. ### [No overloading](../syntax/type/overloading.md) @@ -420,7 +420,7 @@ In Erg, modules are the responsibility of module objects, and types are the type ### [inheritance](../syntax/type/07_inheritance.md) -To define a class that is a superset of another class. +To define a class that is a 父类et 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. @@ -471,7 +471,7 @@ Polymorphism with subtyping. Subtyping corresponds to set containment in types. ### Subroutine -An object that modularizes processing. A generic term for functions, procedures, and methods in Erg. +An object that modularizes processing. A generic term for functions, procedures, and 方法 in Erg. ### [reference](../syntax/18_memory_management.md#borrowed) @@ -783,7 +783,7 @@ In Erg, an object should never change its contents. ### [move] -### methods +### 方法 ### Metacharacters diff --git a/doc/zh_CN/python/class_system.md b/doc/zh_CN/python/class_system.md index fa6c7f10..270fa188 100644 --- a/doc/zh_CN/python/class_system.md +++ b/doc/zh_CN/python/class_system.md @@ -1,8 +1,8 @@ # Python class system (compare with Erg) -## Methods +## 方法 -Methods may be forward referenced, but this is not a special technique used. +方法 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.) diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md index 8e93f12b..36292785 100644 --- a/doc/zh_CN/syntax/04_function.md +++ b/doc/zh_CN/syntax/04_function.md @@ -78,7 +78,7 @@ f x: y ``` -## Default parameters +## 定义ault parameters Default parameters are used when some parameters are mostly fixed and you want to be able to omit them. diff --git a/doc/zh_CN/syntax/07_side_effect.md b/doc/zh_CN/syntax/07_side_effect.md index 1037bb36..579898c1 100644 --- a/doc/zh_CN/syntax/07_side_effect.md +++ b/doc/zh_CN/syntax/07_side_effect.md @@ -16,9 +16,9 @@ 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`. +Functions and procedures each can be 方法. Functional 方法 can only take immutable references to `self`, while procedural 方法 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. ```python @@ -28,7 +28,7 @@ C!. x ``` -Procedural methods can also take [ownership](./18_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition. +Procedural 方法 can also take [ownership](./18_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition. ```python n = 1 @@ -36,9 +36,9 @@ 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`. +Only one procedural 方法 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. +Note, however, that it is possible to create (immutable/mutable) references from mutable references. This allows recursion and `print!` of `self` in procedural 方法. ```python T -> T # OK (move) diff --git a/doc/zh_CN/syntax/13_record.md b/doc/zh_CN/syntax/13_record.md index c7f8694e..48a325dc 100644 --- a/doc/zh_CN/syntax/13_record.md +++ b/doc/zh_CN/syntax/13_record.md @@ -135,7 +135,7 @@ empty_record: Structural {=} 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. +An `Object` (a patch of `Object`) is an element of `. __sizeof__` and other very basic provided 方法. ```python AnyPatch = Patch Structural {=} diff --git a/doc/zh_CN/syntax/16_iterator.md b/doc/zh_CN/syntax/16_iterator.md index d53deb4c..2cd6802c 100644 --- a/doc/zh_CN/syntax/16_iterator.md +++ b/doc/zh_CN/syntax/16_iterator.md @@ -41,7 +41,7 @@ log (1..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. +And the `IteratorImpl` patch is the core of the iteration functionality. `Iterator` requires only one `.next` method, `IteratorImpl` provides dozens of 方法 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 diff --git a/doc/zh_CN/syntax/19_visibility.md b/doc/zh_CN/syntax/19_visibility.md index e5ef1e80..315ab8e4 100644 --- a/doc/zh_CN/syntax/19_visibility.md +++ b/doc/zh_CN/syntax/19_visibility.md @@ -87,7 +87,7 @@ C. ## Visibility in external modules -A class defined in one module can actually define methods from an external module. +A class defined in one module can actually define 方法 from an external module. ``` erg # foo.er @@ -109,9 +109,9 @@ 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. +However, both of those 方法 are only available within that module. +Private 方法 defined externally are visible to 方法 of the `Foo` class only within the defining module. +Public 方法 are exposed outside the class, but not outside the module. ``` erg # baz.er @@ -121,8 +121,8 @@ foo = Foo.new() foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defined in module 'bar') ``` -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. +Also, 方法 cannot be defined in the type to be re-exported. +This is to avoid confusion about 方法 being found or not found depending on the module they are imported from. ``` erg #bar.er diff --git a/doc/zh_CN/syntax/20_naming_rule.md b/doc/zh_CN/syntax/20_naming_rule.md index dee0d1cf..e5543f7e 100644 --- a/doc/zh_CN/syntax/20_naming_rule.md +++ b/doc/zh_CN/syntax/20_naming_rule.md @@ -9,7 +9,7 @@ match i: None -> log "None" ``` -Objects with side effects always end with `!`. Procedures and procedural methods, and mutable types. +Objects with side effects always end with `!`. Procedures and procedural 方法, and mutable types. However, the `Proc` type itself is not mutable. ``` erg diff --git a/doc/zh_CN/syntax/22_subroutine.md b/doc/zh_CN/syntax/22_subroutine.md index c5f70cff..0cfbb3a4 100644 --- a/doc/zh_CN/syntax/22_subroutine.md +++ b/doc/zh_CN/syntax/22_subroutine.md @@ -35,7 +35,7 @@ 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. +For 方法 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. diff --git a/doc/zh_CN/syntax/24_module.md b/doc/zh_CN/syntax/24_module.md index 98027038..f2309cf0 100644 --- a/doc/zh_CN/syntax/24_module.md +++ b/doc/zh_CN/syntax/24_module.md @@ -8,7 +8,7 @@ Erg allows you to think of the file itself as a single record. This is called a ``` ``` erg -# Defining the foo module is almost the same as defining this record +# 定义ining the foo module is almost the same as defining this record foo = {.i = 1} ``` diff --git a/doc/zh_CN/syntax/25_object_system.md b/doc/zh_CN/syntax/25_object_system.md index c02573ea..40f0ae5f 100644 --- a/doc/zh_CN/syntax/25_object_system.md +++ b/doc/zh_CN/syntax/25_object_system.md @@ -13,7 +13,7 @@ All data that can be assigned to a variable. The attributes of the `Object` clas ## Record An object generated by a record literal (`{attr = value; ...}`). -This object has basic methods such as `.clone` and `.__sizeof__`. +This object has basic 方法 such as `.clone` and `.__sizeof__`. ``` erg obj = {.x = 1} @@ -42,7 +42,7 @@ 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`. +Indicates an object that is an instance of a function or procedure (including 方法). The class representing a subroutine is `Subroutine`. An object that implements `.__call__` is more commonly called a `Callable`. ## Callable @@ -57,7 +57,7 @@ Furthermore, a type that defines a method that changes the state of an object is ## Class -A type that has `.__new__`, `.__init__` methods, etc. Implement class-based object orientation. +A type that has `.__new__`, `.__init__` 方法, etc. Implement class-based object orientation. ## Function diff --git a/doc/zh_CN/syntax/31_pipeline.md b/doc/zh_CN/syntax/31_pipeline.md index 652f756d..4093994e 100644 --- a/doc/zh_CN/syntax/31_pipeline.md +++ b/doc/zh_CN/syntax/31_pipeline.md @@ -8,7 +8,7 @@ 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)`. +The pipeline operator can also be used on 方法. For 方法, `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 diff --git a/doc/zh_CN/syntax/container_ownership.md b/doc/zh_CN/syntax/container_ownership.md index 3067bb35..af0bc06a 100644 --- a/doc/zh_CN/syntax/container_ownership.md +++ b/doc/zh_CN/syntax/container_ownership.md @@ -1,6 +1,6 @@ # Subscript (index access) -`[]` is different from normal methods. +`[]` is different from normal 方法. ``` erg a = [!1, !2] diff --git a/doc/zh_CN/syntax/indexes.md b/doc/zh_CN/syntax/indexes.md index 9a530a07..37c89de9 100644 --- a/doc/zh_CN/syntax/indexes.md +++ b/doc/zh_CN/syntax/indexes.md @@ -416,7 +416,7 @@ See [here](../dev_guide/terms.md) for terminology. * [anonymous function](./21_lambda.md) * mutable → [mutable] * [Move] -* methods +* 方法 * Metacharacter * [module](./24_module.md) * [String] → [Str] diff --git a/doc/zh_CN/syntax/quick_tour.md b/doc/zh_CN/syntax/quick_tour.md index 0c5e6cf7..f3511598 100644 --- a/doc/zh_CN/syntax/quick_tour.md +++ b/doc/zh_CN/syntax/quick_tour.md @@ -231,7 +231,7 @@ Erg does not support multiple/multilevel inheritance. ## Traits -They are similar to Rust traits, but in a more literal sense, allowing composition and decoupling, and treating attributes and methods as equals. +They are similar to Rust traits, but in a more literal sense, allowing composition and decoupling, and treating attributes and 方法 as equals. Also, it does not involve implementation. ``` erg diff --git a/doc/zh_CN/syntax/type/01_type_system.md b/doc/zh_CN/syntax/type/01_type_system.md index 3f1ee80a..a7b7be64 100644 --- a/doc/zh_CN/syntax/type/01_type_system.md +++ b/doc/zh_CN/syntax/type/01_type_system.md @@ -26,7 +26,7 @@ o2 = D.new {.public = 2} # InitializationError: class 'D' requires attribute 'pr ## Classification 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). +The top-level type is `{=}`, which implements `__repr__`, `__hash__`, `clone`, etc. (not required 方法, 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). @@ -166,7 +166,7 @@ f x, y = x + y 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. +Enumerated types, for example, can be given names and request/implementation 方法. In namespaces that have access to that type, objects that satisfy the request can use the implementation method. ```python Binary = Patch {0, 1} diff --git a/doc/zh_CN/syntax/type/03_trait.md b/doc/zh_CN/syntax/type/03_trait.md index ea1fb991..9df474e0 100644 --- a/doc/zh_CN/syntax/type/03_trait.md +++ b/doc/zh_CN/syntax/type/03_trait.md @@ -7,7 +7,7 @@ It is similar to the Abstract Base Class (ABC) in Python, but with the distincti Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int} ``` -Trait does not distinguish between attributes and methods. +Trait does not distinguish between attributes and 方法. 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. diff --git a/doc/zh_CN/syntax/type/04_class.md b/doc/zh_CN/syntax/type/04_class.md index b345aa65..2728fcdd 100644 --- a/doc/zh_CN/syntax/type/04_class.md +++ b/doc/zh_CN/syntax/type/04_class.md @@ -96,8 +96,8 @@ 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. +Objects can use patch 方法 as well as class 方法. +Erg does not allow you to add class 方法, 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). @@ -268,7 +268,7 @@ 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. +A class is a subtype of a requirement type. 方法 (including patch 方法) of the requirement type can be used in the class. ```python T = Trait {.foo = Foo} diff --git a/doc/zh_CN/syntax/type/05_inheritance.md b/doc/zh_CN/syntax/type/05_inheritance.md index 92607492..85744b2a 100644 --- a/doc/zh_CN/syntax/type/05_inheritance.md +++ b/doc/zh_CN/syntax/type/05_inheritance.md @@ -58,11 +58,11 @@ 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". +The class is the same as the patch in that new 方法 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. +And if you override a method that is referenced by another method, you must also override all referenced 方法. 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. @@ -177,7 +177,7 @@ Inherited! # 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. +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 方法 provided by the base class. Regardless of the visibility of the attribute, it cannot be updated directly. However, they can be read. ```python @@ -198,7 +198,7 @@ Inherited! self.pub.update! p -> p + 2 ``` -After all, Erg inheritance can only add new attributes and override base class methods. +After all, Erg inheritance can only add new attributes and override base class 方法. ## Usage of Inheritance 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 2738cf7f..7bfe0f93 100644 --- a/doc/zh_CN/syntax/type/06_nst_vs_sst.md +++ b/doc/zh_CN/syntax/type/06_nst_vs_sst.md @@ -29,7 +29,7 @@ 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. +# If both exist, class 方法 take priority. assert MonthsClass.new(2).name() == "february" ``` diff --git a/doc/zh_CN/syntax/type/07_patch.md b/doc/zh_CN/syntax/type/07_patch.md index 80c0b8eb..630fb8a9 100644 --- a/doc/zh_CN/syntax/type/07_patch.md +++ b/doc/zh_CN/syntax/type/07_patch.md @@ -1,7 +1,7 @@ # Patch 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++). +This means, it is not possible to define additional 方法 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. ```python @@ -13,10 +13,10 @@ 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`). +This way, objects of the type being patched (`Str`) can use the 方法 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. +However, patch 方法 have lower precedence than 方法 of the nominal type (class/trait) and cannot override 方法 of existing types. ```python StrangeInt = Patch Int @@ -31,15 +31,15 @@ Overriding is not very easy to do because of some safety restrictions. ```python StrangeInt = Inherit Int StrangeInt. - # Overriding methods must be given Override decorators. - # In addition, you need to override all Int methods that depend on Int.`_+_`. + # Overriding 方法 must be given Override decorators. + # In addition, you need to override all Int 方法 that depend on Int.`_+_`. @Override - `_+_` = Super.`_-_` # OverrideError: Int.`_+_` is referenced by ... ````` , so these methods must also be overridden + `_+_` = Super.`_-_` # OverrideError: Int.`_+_` is referenced by ... ````` , so these 方法 must also be overridden ``` -## Selecting Patches +## Selecting 修补程序 -Patches can be defined for a single type, and can be grouped together. +修补程序 can be defined for a single type, and can be grouped together. ```python # foo.er @@ -70,7 +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. +If multiple 修补程序 are defined, some of them may result in duplicate implementations. ```python # foo.er @@ -102,7 +102,7 @@ assert "hello".reverse() == "olleh" ## Glue Patch -Patches can also relate types to each other. The `StrReverse` patch relates `Str` and `Reverse`. +修补程序 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. @@ -118,8 +118,8 @@ StrReverse. ``` 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). +This is because if multiple glue 修补程序 were "visible" at the same time, it would not be possible to uniquely determine which implementation to choose. +However, you can swap 修补程序 when moving to another scope (module). ```python NumericStr = Inherit Str @@ -135,7 +135,7 @@ NumStrRev. ## Appendix: Relationship to Rust's Trait -Erg patches are the equivalent of Rust's (retrofitted) `impl` blocks. +Erg 修补程序 are the equivalent of Rust's (retrofitted) `impl` blocks. ```rust // Rust @@ -150,7 +150,7 @@ impl Reverse for String { } ``` -You could say that Rust's traits are features of Erg's traits and patches. This makes Rust's traits sound more convenient, but that is not necessarily the case. +You could say that Rust's traits are features of Erg's traits and 修补程序. This makes Rust's traits sound more convenient, but that is not necessarily the case. ```python # Erg @@ -199,10 +199,10 @@ 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. +In addition, 修补程序 can be defined for any type that satisfies a certain structure. +However, this has a lower priority than nominal 修补程序 and class 方法. -Careful design should be used when defining structural patches, as some properties are lost by extension, such as the following. +Careful design should be used when defining structural 修补程序, as some properties are lost by extension, such as the following. ```python # This should not be `Structural` diff --git a/doc/zh_CN/syntax/type/11_enum.md b/doc/zh_CN/syntax/type/11_enum.md index ef18d8b6..66ceb5f3 100644 --- a/doc/zh_CN/syntax/type/11_enum.md +++ b/doc/zh_CN/syntax/type/11_enum.md @@ -1,7 +1,7 @@ # Enumerative Type Enum types generated by Set. -Enum types can be used as-is with type specifications, but further methods can be defined by classifying them into classes or defining patches. +Enum types can be used as-is with type specifications, but further 方法 can be defined by classifying them into classes or defining 修补程序. A partially typed system with an enumerated type is called an enumerated partially typed. @@ -44,7 +44,7 @@ The difference with Rust is that it uses a structural subtype(SST). enum Status { Ok, Error } enum ExtraStatus { Ok, Error, Unknown } -// Methods can be implemented +// 方法 can be implemented impl Status { // ... } @@ -54,14 +54,14 @@ impl ExtraStatus { ``` ```python -# Status > ExtraStatus, and elements of Status can use methods of ExtraStatus. +# Status > ExtraStatus, and elements of Status can use 方法 of ExtraStatus. Status = Trait {"Ok", "Error"} # ... ExtraStatus = Trait {"Ok", "Error", "Unknown"} # ... ``` -Methods can also be added by patching. +方法 can also be added by patching. Use the `or` operator to explicitly indicate inclusion or to add a choice to an existing Enum type. diff --git a/doc/zh_CN/syntax/type/14_dependent.md b/doc/zh_CN/syntax/type/14_dependent.md index c7ec3eb6..bf5ac404 100644 --- a/doc/zh_CN/syntax/type/14_dependent.md +++ b/doc/zh_CN/syntax/type/14_dependent.md @@ -24,7 +24,7 @@ assert array(3) == [3, 3, 3] When defining a dependent type, all type arguments must be constants. -Dependent types themselves exist in existing languages, but Erg has the feature of defining procedural methods on dependent types. +Dependent types themselves exist in existing languages, but Erg has the feature of defining procedural 方法 on dependent types. ``` erg x=1 diff --git a/doc/zh_CN/syntax/type/15_quantified.md b/doc/zh_CN/syntax/type/15_quantified.md index 9c76157a..87c8b0ab 100644 --- a/doc/zh_CN/syntax/type/15_quantified.md +++ b/doc/zh_CN/syntax/type/15_quantified.md @@ -54,7 +54,7 @@ Also, the type variable `T` can be inferred to be of type `Type` since it is use 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. +Constraints also have advantages, for example, a subtype specification allows certain 方法 to be used. ```python # T <: Add @@ -173,15 +173,15 @@ N = 1 K(N: Nat) = ... # NameError: N is already defined L(M: Nat) = ... -# Defined only if M == N == 1 +# 定义ined only if M == N == 1 L(N). foo(self, x) = ... -# defined for any M: Nat +# 定义ined 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). +You cannot have multiple definitions for each type argument, but you can define 方法 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). ```python K(I: Int) = ... @@ -261,7 +261,7 @@ Therefore, it is indeed `(|T| T -> T) < (Int -> Int) < (T -> T)`. 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. -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`. +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 方法, 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. diff --git a/doc/zh_CN/syntax/type/18_mut.md b/doc/zh_CN/syntax/type/18_mut.md index 63ab9719..8ea1f9db 100644 --- a/doc/zh_CN/syntax/type/18_mut.md +++ b/doc/zh_CN/syntax/type/18_mut.md @@ -15,7 +15,7 @@ Person!. 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. +Mutable types can define procedural 方法 that rewrite instances, but having procedural 方法 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`. diff --git a/doc/zh_CN/syntax/type/advanced/erasure.md b/doc/zh_CN/syntax/type/advanced/erasure.md index ff485c46..d9d418d2 100644 --- a/doc/zh_CN/syntax/type/advanced/erasure.md +++ b/doc/zh_CN/syntax/type/advanced/erasure.md @@ -4,7 +4,7 @@ Type erasure is the process of setting a type argument to `_` and deliberately d 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. +Objects of type `[T; N]` can of course use 方法 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. ```python # Functions that are guaranteed to not change the length of the array (e.g., sort) diff --git a/doc/zh_CN/syntax/type/advanced/kind.md b/doc/zh_CN/syntax/type/advanced/kind.md index 64cd1f35..6e6b41c2 100644 --- a/doc/zh_CN/syntax/type/advanced/kind.md +++ b/doc/zh_CN/syntax/type/advanced/kind.md @@ -15,7 +15,7 @@ assert Option in Type -> Type ``` So code like the following will result in an error: -In Erg, methods can only be defined in atomic kinds, and the name `self` cannot be used anywhere other than the first argument of a method. +In Erg, 方法 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 @@ -132,9 +132,9 @@ Fn2(T, U). ``` 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. +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 修补程序 above are possible options. -In this case, patches are selected according to the following priority criteria. +In this case, 修补程序 are selected according to the following priority criteria. * 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`. diff --git a/doc/zh_CN/syntax/type/advanced/newtype.md b/doc/zh_CN/syntax/type/advanced/newtype.md index 96d65399..067a04d6 100644 --- a/doc/zh_CN/syntax/type/advanced/newtype.md +++ b/doc/zh_CN/syntax/type/advanced/newtype.md @@ -27,5 +27,5 @@ i + UserId.new(10000001) # TypeError: + is not implemented between `UserId` and ``` 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. +The `UserId` loses all the 方法 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 方法 is desirable, so choose the appropriate method depending on the situation. diff --git a/doc/zh_CN/syntax/type/advanced/phantom.md b/doc/zh_CN/syntax/type/advanced/phantom.md index b36d8b5e..6caca4a7 100644 --- a/doc/zh_CN/syntax/type/advanced/phantom.md +++ b/doc/zh_CN/syntax/type/advanced/phantom.md @@ -53,5 +53,5 @@ VM!("stopped"). self::set_phantom!("running")) ``` -The `state` is updated via the `update_phantom!` or `set_phantom!` methods. +The `state` is updated via the `update_phantom!` or `set_phantom!` 方法. 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/quantified_dependent.md b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md index 623f206f..ab5bc0f2 100644 --- a/doc/zh_CN/syntax/type/advanced/quantified_dependent.md +++ b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md @@ -9,7 +9,7 @@ NonEmptyArray = |N: Nat| [_; N | N > 0] # same as {A | N: Nat; A: Array(_, N); N 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. +Quantified dependent types as left-hand side values can only define 方法 in the same module as the original type. ```python K A: Nat = Class ... diff --git a/doc/zh_CN/syntax/type/advanced/shared.md b/doc/zh_CN/syntax/type/advanced/shared.md index 69b7cb7e..74a904bd 100644 --- a/doc/zh_CN/syntax/type/advanced/shared.md +++ b/doc/zh_CN/syntax/type/advanced/shared.md @@ -53,7 +53,7 @@ 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`. +The `SharedCell! T!` type is also a subtype of `T!` and can call 方法 of type `T!`. The only 方法 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. diff --git a/doc/zh_CN/syntax/type/advanced/variance.md b/doc/zh_CN/syntax/type/advanced/variance.md index 6a7bec59..0c1d8f32 100644 --- a/doc/zh_CN/syntax/type/advanced/variance.md +++ b/doc/zh_CN/syntax/type/advanced/variance.md @@ -3,11 +3,11 @@ 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`. +For example, `Option Int < Option Object`. Therefore, 方法 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: +Now, the `Array!(T)` type has 方法 called `.push!` and `.pop!`, which mean adding and removing elements, respectively. Here is the type: Array.push!: Self(T).(T) => NoneType Array.pop!: Self(T).() => T @@ -101,7 +101,7 @@ List(T). ``` 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. +Note, however, that the Erg compiler doesn't understand the semantics of 方法. The compiler simply infers and derives type relationships mechanically according to how variables and type variables are used. As written in the comments, the type `U` put in the `head` of `List T` is a subclass of `T` (`T: Int`, such as `Nat`). That is, it is inferred as `U <: T`. This constraint changes the argument type of `.push{U}` upcast `(List(T), U) -> List(T) to (List(T), T) -> List(T)`( e.g. disallow `List(Int).push{Object}`). Note, however, that the `U <: T` constraint does not alter the type containment of the function. The fact that `(List(Int), Object) -> List(Int) to (List(Int), Int) -> List(Int)` does not change, just in `.push` method It means that the cast cannot be performed. Similarly, a cast from `List T` to `List U` is possible subject to the constraint `U :> T`, so the variation specification is inferred. This constraint changes the return type of `.upcast(U)` to upcast `List(T) -> List(T) to List(T) -> List(T)` (e.g. `List(Object) .upcast(Int)`) is prohibited. From 7151f44d91b86f01558e9a041129d2d517f15520 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 12:32:14 +0800 Subject: [PATCH 09/42] compiler zh_CN translate --- doc/zh_CN/compiler/TODO_hint.md | 6 +- doc/zh_CN/compiler/TODO_recov_suggest.md | 20 +- doc/zh_CN/compiler/TODO_warn.md | 6 +- doc/zh_CN/compiler/inference.md | 248 +++++++++---------- doc/zh_CN/compiler/overview.md | 36 +-- doc/zh_CN/compiler/parsing.md | 26 +- doc/zh_CN/compiler/refinement_subtyping.md | 78 +++--- doc/zh_CN/compiler/trait_method_resolving.md | 66 ++--- doc/zh_CN/compiler/transpile.md | 38 +-- doc/zh_CN/compiler/type_var_normalization.md | 32 +-- 10 files changed, 277 insertions(+), 279 deletions(-) diff --git a/doc/zh_CN/compiler/TODO_hint.md b/doc/zh_CN/compiler/TODO_hint.md index 3844f83f..70ff02be 100644 --- a/doc/zh_CN/compiler/TODO_hint.md +++ b/doc/zh_CN/compiler/TODO_hint.md @@ -1,4 +1,4 @@ -# 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`" +* `x 未定义`(x 已被`Del` 删除)=> `提示:在第 X 行删除` +*补丁方法重复:“提示:指定补丁(如`T.foo(1)`)或使用`Del`删除任何`.foo`” \ No newline at end of file diff --git a/doc/zh_CN/compiler/TODO_recov_suggest.md b/doc/zh_CN/compiler/TODO_recov_suggest.md index a11955fa..b324f0e1 100644 --- a/doc/zh_CN/compiler/TODO_recov_suggest.md +++ b/doc/zh_CN/compiler/TODO_recov_suggest.md @@ -1,11 +1,11 @@ -# 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`? +* `1 or 2`, `1 and 2` => `{1, 2}`? +* `U = Inherit T` => 非类类型不能被继承,或者`U = Class T`? +* `Int and Str` => 不允许多重继承,或者`Int or Str`? +* `: [1, 2]` => `: {1, 2}`? +* `: [Int, 2]` => `: [Int; 2]`? +* `[Int; Str]` => `(Int, Str)`(Tuple) 还是 `[Int: Str]`(Dict)? +* `{x: Int}` => `{x = Int}`? +* `{x = Int}!` => `{x = Int!}`? +* `ref! immut_expr` => `ref! !immut_expr`? \ No newline at end of file diff --git a/doc/zh_CN/compiler/TODO_warn.md b/doc/zh_CN/compiler/TODO_warn.md index 0ba2ebf2..8785ea6c 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) +* `t = {(record type)}` => `T = {(record type)}`?(只有定义为常量的类型才能用于类型说明) * `{I: Int | ...}!` => `{I: Int! | ...}` -* `return x`(`x != ()`) in for/while block => `f::return` (outer block)? +* for/while 块中的`return x`(`x != ()`) => `f::return`(外部块)? \ No newline at end of file diff --git a/doc/zh_CN/compiler/inference.md b/doc/zh_CN/compiler/inference.md index 628e1309..936bfd56 100644 --- a/doc/zh_CN/compiler/inference.md +++ b/doc/zh_CN/compiler/inference.md @@ -1,8 +1,8 @@ -# type inference algorithm +# 类型推断算法 -> __Warning__: This section is being edited and may contain some errors. +> __Warning__:此部分正在编辑中,可能包含一些错误 -The notation used below is shown. +显示了下面使用的符号 ``` erg Free type variables (type, unbound): ?T, ?U, ... @@ -12,7 +12,7 @@ Type assignment rule (S): { ?T --> T, ... } Type argument evaluation environment (E): { e -> e', ... } ``` -Let's take the following code as an example. +我们以下面的代码为例: ``` erg v = ![] @@ -20,51 +20,51 @@ v.push! 1 print! v ``` -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. +Erg 的类型推断主要使用 Hindley-Milner 类型推断算法(尽管已经进行了各种扩展)。具体而言,类型推断是通过以下过程执行的。术语将在后面解释。 -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 方法 -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) +1. 推断右值的类型(搜索) +2. 实例化结果类型 +3. 如果是调用,执行类型替换(substitute) +4. 解决已经单态化的特征 +5. 如果有类型变量值,求值/归约(eval) +6. 删除链接类型变量(deref) +7. 传播可变依赖方法的变化 +8. 如果有左值并且是Callable,则泛化参数类型(generalize) +9. 如果有左值,对(返回值)类型进行泛化(generalize) +10. 如果是赋值,则在符号表(`Context`)中注册类型信息(更新) -The specific operations are as follows. +具体操作如下。 -line 1. Def{sig: v, block: ![]} - get block type: - get UnaryOp type: - getArray type: `['T; 0]` - instantiate: `[?T; 0]` - (substitute, eval are omitted) - update: `Γ: {v: [?T; 0]!}` - expr returns `NoneType`: OK +第 1 行。 Def{sig: v, block: ![]} + 获取块类型: + 获取 UnaryOp 类型: + getArray 类型:`['T; 0]` + 实例化:`[?T; 0]` + (替代,评估被省略) + 更新:`Γ: {v: [?T; 0]!}` + 表达式 返回`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 +第 2 行 CallMethod {obj: v, name: push!, args: [1]} + 获取 obj 类型:`Array!(?T, 0)` + 搜索:`Γ Array!(?T, 0).push!({1})` + 得到:`= Array!('T ~> 'T, 'N ~> 'N+1).push!('T) => NoneType` + 实例化:`Array!(?T, ?N).push!(?T) => NoneType` + 替代(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!(Nat) => NoneType` + 评估: `Array!(Nat, 0 ~> 1).push!({1}) => NoneType` + 更新:`Γ:{v:[Nat; 1]!}` + 表达式 返回`NoneType`:OK -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 +第 3 行。调用 {obj: print!, args: [v]} + 获取参数类型:`[[Nat; 1]!]` + 获取 obj 类型: + 搜索:`Γ print!([Nat; 1]!)` + 得到:`= print!(...Object) => NoneType` + 表达式 返回`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>`. +类型变量最初在 [ty.rs](../../src/common/ty.rs) 的 `Type` 中表示如下。它现在以不同的方式实现,但本质上是相同的想法,所以我将以更天真的方式考虑这种实现。 +`RcCell` 是 `Rc>` 的包装类型。 ```rust pub enum Type { @@ -74,78 +74,78 @@ 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) ). +类型变量可以通过将实体类型保存在外部字典中来实现,并且类型变量本身只有它的键。但是,据说使用 `RcCell` 的实现通常更有效(需要验证,[来源](https://mobile.twitter.com/bd_gfngfn/status/1296719625086877696?s=21))。 -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__. +类型变量首先被初始化为 `Type::Var(RcCell::new(None))`。 +当分析代码并确定类型时,会重写此类型变量。 +如果内容直到最后都保持为 None ,它将是一个无法确定为具体类型的类型变量(当场)。例如,具有 `id x = x` 的 `x` 类型。 +我将这种状态下的类型变量称为 __Unbound 类型变量__(我不知道确切的术语)。另一方面,我们将分配了某种具体类型的变量称为 __Linked 类型变量__。 -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`. +两者都是自由类型变量(该术语显然以“自由变量”命名)。这些是编译器用于推理的类型变量。它之所以有这样一个特殊的名字,是因为它不同于程序员指定类型的类型变量,例如 `id: 'T -> '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. +未绑定类型变量表示为`?T`、`?U`。在类型论的上下文中,经常使用 α 和 β,但这一种是用来简化输入的。 +请注意,这是出于一般讨论目的而采用的表示法,实际上并未使用字符串标识符实现。 -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. +进入类型环境时,未绑定的类型变量 `Type::Var` 被替换为 `Type::MonoQuantVar`。这称为 __quantified 类型变量__。这类似于程序员指定的类型变量,例如“T”。内容只是一个字符串,并没有像自由类型变量那样链接到具体类型的工具。 -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. +用量化类型变量替换未绑定类型变量的操作称为__generalization__(或泛化)。如果将其保留为未绑定类型变量,则类型将通过一次调用固定(例如,调用 `id True` 后,`id 1` 的返回类型将是 `Bool`),所以它必须是概括的。 +以这种方式,在类型环境中注册了包含量化类型变量的通用定义。 -## generalizations, type schemes, reifications +## 概括、类型方案、具体化 -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. +让我们将未绑定类型变量 `?T` 泛化为 `gen` 的操作表示。令生成的广义类型变量为 `|T: Type| T`。 +在类型论中,量化类型,例如多相关类型 `α->α`,通过在它们前面加上 `∀α.` 来区分(像 ∀ 这样的符号称为(通用)量词。)。 +这样的表示(例如`∀α.α->α`)称为类型方案。 Erg 中的类型方案表示为 `|T: Type| T -> T`。 +类型方案通常不被认为是一流的类型。以这种方式配置类型系统可以防止类型推断起作用。但是,在尔格中,在一定条件下可以算是一流的类型。有关详细信息,请参阅 [rank2 类型](../syntax/type/advanced/rank2type.md)。 -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`. +现在,当在使用它的类型推断(例如,`id 1`,`id True`)中使用获得的类型方案(例如`'T -> 'T(id's type scheme)`)时,必须释放generalize。这种逆变换称为 __instantiation__。我们将调用操作`inst`。 ``` erg gen ?T = 'T inst 'T = ?T (?T ∉ Γ) ``` -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. +重要的是,这两个操作都替换了所有出现的类型变量。 例如,如果你实例化 `'T -> 'T`,你会得到 `?T -> ?T`。 +实例化需要替换 dict,但为了泛化,只需将 `?T` 与 `'T` 链接以替换它。 -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. +之后,给出参数的类型以获取目标类型。 此操作称为类型替换,将用 `subst` 表示。 +此外,如果表达式是调用,则获取返回类型的操作表示为 `subst_call_ret`。 第一个参数是参数类型列表,第二个参数是要分配的类型。 -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`. +类型替换规则 `{?T --> X}` 意味着将 `?T` 和 `X` 重写为相同类型。 此操作称为 __Unification__。 `X` 也可以是类型变量。 +[单独部分](./unification.md) 中描述了详细的统一算法。 我们将统一操作表示为“统一”。 ``` erg unify(?T, Int) == Ok(()) # ?T == (Int) -# S is the type assignment rule, T is the applicable type +# S为类型分配规则,T为适用类型 subst(S: {?T --> X}, T: ?T -> ?T) == X -> X # Type assignment rules are {?T --> X, ?U --> T} subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y ``` -## semi-unification +## 半统一(semi-unification) -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__)。 这是更新类型变量约束以满足子类型关系的操作。 +在某些情况下,类型变量可能是统一的,也可能不是统一的,因此称为“半”统一。 -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 -# If the formal parameter type is T +# 如果形参类型是T f(x: T): T = ... a: U -# must be U <: T, otherwise type error +# 必须为 U <: T,否则类型错误 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 x -> @@ -153,8 +153,8 @@ x -> y ``` -First, Erg allocates type variables as follows: -The type of y is also unknown, but is left unassigned for now. +首先,Erg 分配类型变量如下: +y 的类型也是未知的,但暂时未分配。 ``` erg x(: ?T) -> @@ -162,8 +162,8 @@ x(: ?T) -> y ``` -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. +首先要确定的是右值 x 的类型。 右值是一种“用途”,因此我们将其具体化。 +但是 x 的类型 `?T` 已经被实例化了,因为它是一个自由变量。 Yo`?T` 成为右值的类型。 ``` erg x(: ?T) -> @@ -171,7 +171,7 @@ x(: ?T) -> y ``` -Generalize when registering as the type of lvalue y. However, as we will see later, this generalization is imperfect and produces erroneous results. +注册为左值 y 的类型时进行泛化。 然而,正如我们稍后将看到的,这种概括是不完善的,并且会产生错误的结果。 ``` erg x(: ?T) -> @@ -185,7 +185,7 @@ x(: ?T) -> y ``` -The type of y is now a quantified type variable `'T`. In the next line, `y` is used immediately. Concrete. +y 的类型现在是一个量化类型变量“T”。 在下一行中,立即使用 `y`。 具体的。 ``` erg x: ?T -> @@ -193,7 +193,7 @@ x: ?T -> 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 x: ?T -> @@ -201,20 +201,20 @@ x: ?T -> 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. +并查看生成的整个表达式的类型。 `?T -> ?U`。 +但显然这个表达式应该是`?T -> ?T`,所以我们知道推理有问题。 +发生这种情况是因为我们没有“级别管理”类型变量。 -So we introduce the level of type variables with the following notation. Levels are expressed as natural numbers. +所以我们用下面的符号来介绍类型变量的层次。 级别表示为自然数。 ``` erg -# normal type variable +# 普通类型变量 ?T<1>, ?T<2>, ... -# type variable with subtype constraint +# 具有子类型约束的类型变量 ?T<1>(<:U) or ?T(<:U)<1>, ... ``` -Let's try again. +让我们再尝试一次: ``` erg x -> @@ -222,8 +222,8 @@ x -> y ``` -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. +首先,按如下方式分配一个 leveled 类型变量: toplevel 级别为 1。随着范围的加深,级别增加。 +函数参数属于内部范围,因此它们比函数本身高一级。 ``` erg # level 1 @@ -233,7 +233,7 @@ x (: ?T<2>) -> y ``` -First, instantiate the rvalue `x`. Same as before, nothing changed. +首先,实例化右值`x`。和以前一样,没有任何改变。 ``` erg x (: ?T<2>) -> @@ -241,9 +241,9 @@ x (: ?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. +这是关键。 这是分配给左值`y`的类型时的概括。 +早些时候,这里的结果很奇怪,所以我们将改变泛化算法。 +如果类型变量的级别小于或等于当前范围的级别,则泛化使其保持不变。 ``` erg gen ?T = if n <= current_level, then= ?T, else= 'T @@ -260,12 +260,12 @@ That is, the lvalue `y` has type `?T<2>`. ``` erg x (: ?T<2>) -> - # ↓ not generalized + # ↓ 不包括 y(: ?T<2>) = x 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. +y 的类型现在是一个未绑定的类型变量 `?T<2>`。 具体如下几行:但是 `y` 的类型没有被概括,所以什么也没有发生 ``` erg x (: ?T<2>) -> @@ -279,9 +279,9 @@ x (: ?T<2>) -> y (: ?T<2>) ``` -We successfully got the correct type `?T<2> -> ?T<2>`. +我们成功获得了正确的类型`?T<2> -> ?T<2>`。 -Let's see another example. This is the more general case, with function/operator application and forward references. +让我们看另一个例子。 这是更一般的情况,具有函数/运算符应用程序和前向引用。 ``` erg fx, y = id(x) + y @@ -290,11 +290,11 @@ id x = x 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. +在 `f` 的推断过程中,会引用后面定义的函数常量 `id`。 +在这种情况下,在 `f` 之前插入一个假设的 `id` 声明,并为其分配一个自由类型变量。 +注意此时类型变量的级别是`current_level`。 这是为了避免在其他函数中泛化。 ``` erg id: ?T<1> -> ?U<1> @@ -302,11 +302,11 @@ 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 # BAD @@ -316,9 +316,9 @@ f x (: ?V<2>), y (: ?W<2>) = id(x) (: ?U<1>) + y (: ?W<2>) ``` -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. +这使得无法确定在何处实例化类型变量。 +对于 Type 类型变量,执行正常统一而不是半统一。 +也就是说,统一到下层。 ``` erg # OK @@ -363,7 +363,7 @@ 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 # ?T<1 -> 2> @@ -371,7 +371,7 @@ When defining, raise the level so that it can be generalized. 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>`). +如果已经分配了返回类型,则与结果类型统一(`?U<2> --> ?T<2>`)。 ``` erg # ?U<2> --> ?T<2> @@ -381,9 +381,9 @@ 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. +如果类型变量已经被实例化为一个简单的类型变量, +依赖于它的类型变量也将是一个 Type 类型变量。 +广义类型变量对于每个函数都是独立的。 ``` erg f(x, y) (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = @@ -403,7 +403,7 @@ f(10, 1) (: subst_call_ret([inst {10}, inst {1}], inst |'W: Type, 'T <: Add('W)| 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 # ?T(:> {10} <: Add(?W<1>))<1> @@ -411,15 +411,15 @@ Type variables are bounded to the smallest type that has an implementation. # ?W(:> {1})<1> <: ?T<1> (:> {10}, <: Add(?W(:> {1})<1>)) # serialize # {1} <: ?W<1> or {10} <: ?T<1> <: Add({1}) <: Add(?W<1>) -# The minimal implementation trait for Add(?W)(:> ?V) is Add(Nat) == Nat, since Add is covariant with respect to the first argument +# 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 # If there is only one candidate, finalize the evaluation +# ?T(:> ?W(:> {10}) or {1}, <: Nat).AddO == Nat # 如果只有一个候选人,完成评估 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 f|W: Type, T <: Add(W)|(x: T, y: W): T.AddO = id(x) + y @@ -428,7 +428,7 @@ id|T: Type|(x: T): T = x f(10, 1): Nat ``` -I've also reprinted the original, unexplicitly typed program. +我还重印了原始的、未明确键入的程序。 ``` erg fx, y = id(x) + y diff --git a/doc/zh_CN/compiler/overview.md b/doc/zh_CN/compiler/overview.md index bdbdd075..f20356f1 100644 --- a/doc/zh_CN/compiler/overview.md +++ b/doc/zh_CN/compiler/overview.md @@ -1,36 +1,36 @@ -# overview of `erg` +# `erg` 概览 -We will introduce the function of each layer and the particularly important functions and 方法. +我们将介绍每一层的功能以及特别重要的功能和方法。 -## 1. Lexical Analysis +## 1. 词法分析 -* 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. +* `Lexer` 进行词法分析。 `Lexer::next`(`Lexer`被实现为一个迭代器)负责词法分析的主要逻辑。 `Token` 作为解析的结果输出。 -## 2. Parsing +## 2. 解析 -* `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. +* `Parser` 进行解析。特别重要的是`Parser::parse_expr`。作为解析的结果,输出作为`ast::Expr`的集合的`AST`。 -## 3. Desugaring +## 3. 脱糖 -* Desugaring is done by `Desugarer`. `AST` will be output. +* 脱糖由 `Desugarer` 完成。 `AST` 将被输出。 -## 4. Type checking/type inference +## 4. 类型检查/类型推断 -* `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. +* `ASTLowerer` 进行打字。类型检查主要由 `Context` 完成。尤其重要的是 `Context::supertype_of`(确定子类型关系)、`Context::unify/sub_unify`(统一/半统一类型变量)、`Context::init_builtin_*`(定义内置 API)。 `HIR` 作为分析结果输出。 -## 5. Side effect check +## 5. 副作用检查 -* `SideEffectChecker` does. +* `SideEffectChecker` 可以。 -## 6. Ownership check +## 6. 所有权检查 -* `OwnershipChecker` does. +* `OwnershipChecker` 可以。 -## 7. Bytecode Generation +## 7. 字节码生成 -* `CodeGenerator` converts `HIR` to `CodeObj`. `CodeObj` holds bytecode and execution configuration. Of particular importance is `CodeGenerator::compile_expr`. +* `CodeGenerator` 将 `HIR` 转换为 `CodeObj`。 `CodeObj` 保存字节码和执行配置。特别重要的是`CodeGenerator::compile_expr`。 --- -* 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 +* 以上所有的处理都是由`Compiler`作为一个门面组合起来的。 +* 当然 Python 会执行生成的字节码,称为 `DummyVM`。 \ No newline at end of file diff --git a/doc/zh_CN/compiler/parsing.md b/doc/zh_CN/compiler/parsing.md index fbc7fc76..9e4a544f 100644 --- a/doc/zh_CN/compiler/parsing.md +++ b/doc/zh_CN/compiler/parsing.md @@ -1,9 +1,9 @@ -# Parsing the Erg language +# 解析 Erg 语言 -## 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 `()`. +尔格语法的一个特点是它对空间敏感。 +这是为了弥补因省略`()`而造成的表达力损失。在 Nim 中可以找到类似的语法,它也允许省略 `()`。 ```python f +1 == f(+1) @@ -14,20 +14,20 @@ f(1,) == f(1) (f() -> ...) == (f() -> ...) ``` -## 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 中,左侧的值并不像 `=` 的左侧那么简单。 +事实上,`=` 左侧有一个右值(非常令人困惑),而 `=` 右侧有一个左值。 +右值中甚至可以有左值。 ```python -# 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] 是右边的值 i: Array(Int) = [1, 2, 3] -# `[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 +# `[1, 2, 3].iter().map i -> i + 1`是右边的值,但是->左边的i是左边的值 a = [1, 2, 3].iter().map i -> i + 1 -# {x = 1; y = 2} is the right side value, but x, y are the left side values +# {x = 1; y = 2} 是右侧值,但 x, y 是左侧值 r = {x = 1; y = 2} ``` -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. +左侧和右侧值的精确定义是“如果它是可评估的,则为右侧值,否则为左侧值”。 +例如,考虑代码 ``i = 1; i``,其中第二个 `i` 是右侧值,因为它是可评估的,但第一个 `i` 是左侧值。 \ No newline at end of file diff --git a/doc/zh_CN/compiler/refinement_subtyping.md b/doc/zh_CN/compiler/refinement_subtyping.md index f6695330..5a47803f 100644 --- a/doc/zh_CN/compiler/refinement_subtyping.md +++ b/doc/zh_CN/compiler/refinement_subtyping.md @@ -1,6 +1,4 @@ -# Sieve type - -The sieve type is the following type. +# 筛子类型 ``` erg {I: Int | I >= 0} @@ -8,11 +6,11 @@ The sieve type is the following type. {T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0} ``` -Erg enables type determination by converting Enum and Interval types into sieve types. +Erg 通过将 Enum 和 Interval 类型转换为筛选类型来实现类型确定。 -## 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. +在 [Sieve types] 一节中,我们说过区间类型和枚举类型是 sieve 类型的语法糖。每个转换如下。 * {0} -> {I: Int | I == 0} * {0, 1} -> {I: Int | I == 0 or I == 1} @@ -23,36 +21,36 @@ In the section [Sieve types], we said that interval types and enum types are syn * {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} -## 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: +描述了一种用于确定筛类型 A 是否是另一筛类型 B 的子类型的算法。正式地,(所有)子类型定义如下: ```console -A <: B <=> ∀a∈A; a ∈ B +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+ε}` -* 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}` -* 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 @@ -63,37 +61,37 @@ Specifically, the following inference rules are applied. Boolean expressions are * {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 )) - * basic formula + * 基本公式 * {I >= l} <: {I >= r} = (l >= r) * {I <= l} <: {I <= r} = (l <= r) * {I >= l} <: {I <= r} = False * {I <= l} <: {I >= r} = False -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. +布尔表达式的简化规则如下。 min, max 不能被删除。此外,多个 or, and 被转换为嵌套的 min, max。 -* ordering rules - * `I == a` => `I >= a and I <= a` - * `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)` -* 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 +* 组合规则 + * `I == a` => `I >= a 和 I <= a` + * `i != a` => `I >= a+1 或 I <= a-1` +* 一致性规则 + * `I >= a 或 I <= b (a < b)` == `{...}` +* 恒常规则 + * `I >= a 和 I <= b (a > b)` == `{}` +* 替换规则 + * 以 `I >= n` 和 `I <= n` 的顺序替换顺序表达式。 +* 扩展规则 + * `I == n 或 I >= n+1` => `I >= n` + * `I == n 或 I <= n-1` => `I <= n` +* 最大规则 + * `I <= m 或 I <= n` => `I <= max(m, n)` + * `I >= m 和 I >= n` => `I >= max(m, n)` +* 最低规则 + * `I >= m 或 I >= n` => `I >= min(m, n)` + * `I <= m 和 I <= n` => `I <= min(m, n)` +* 淘汰规则 + * 当 `I >= a (n >= a)` 或 `I <= b (n <= b)` 或 `I == n` 在右侧时,左侧的 `I == n` 被删除能够。 + * 如果无法消除所有左手方程,则为 False -e.g. +例如 ```python 1.._<: Nat diff --git a/doc/zh_CN/compiler/trait_method_resolving.md b/doc/zh_CN/compiler/trait_method_resolving.md index 2e44e180..0f17e37b 100644 --- a/doc/zh_CN/compiler/trait_method_resolving.md +++ b/doc/zh_CN/compiler/trait_method_resolving.md @@ -1,31 +1,31 @@ -# Resolving patch 方法 +# 解决补丁方法 -`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? +`Nat` 是零个或多个`Int`,`Int` 的子类型。 +`Nat` 在 Python 类层次结构中不存在。 我想知道 Erg 是如何解决这个补丁方法的? ``` erg 1.times do: log "hello world" ``` -`.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. +`.times` 是一种 `NatImpl` 补丁方法。 +由于`1`是`Int`的一个实例,首先通过跟踪`Int`的MRO(方法解析顺序)来搜索它。 +Erg 在 `Int` 的 MRO 中有 `Int`、`Object`。它来自 Python(Python 中的`int.__mro__ == [int, object]`)。 +`.times` 方法在它们中都不存在。现在让我们探索那个子类型。 ~ -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? +整数显然应该在其超类型中包含实数、复数甚至整数,但这一事实并没有出现在 Python 兼容层中。 +然而,`1 in Complex` 和 `1 in Num` 在 Erg 中实际上是 `True`。 +至于`Complex`,即使是与`Int`没有继承关系的类,也被判断为类型兼容。这到底是怎么回事? ~ -An object has an infinite number of types to which it belongs. -But we really only have to think about types with 方法, i.e. types with names. +一个对象有无数种它所属的类型。 +但是我们真的只需要考虑带有方法的类型,即带有名称的类型。 -The Erg compiler has a hashmap of patch types with all provided 方法 and their implementations. -This table is updated each time a new type is defined. +Erg 编译器有一个补丁类型的哈希图,其中包含所有提供的方法及其实现。 +每次定义新类型时都会更新此表。 ``` erg provided_method_table = { @@ -37,47 +37,47 @@ 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. +具有 `.times` 方法的类型是 `Nat`、`Foo`。从这些中,找到与“{1}”类型匹配的一个。 +有两种类型的符合性确定。它们是筛式判断和记录式判断。这是通过筛子类型确定来完成的。 -## 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`. +检查候选类型是否与 `1` 的类型 `{1}` 兼容。与“{1}”兼容的筛子类型有“{0, 1}”、“0..9”等。 +有限元代数类型,例如 `0..1 或 3..4`、`-1..2 和 0..3`,在声明为基本类型(即 {0, 1, 3, 4}`,`{0, 1, 2}`)。 +在这种情况下,`Nat` 是 `0.._ == {I: Int | I >= 0}`,所以 `{1}` 与 `Nat` 兼容。 -## Determine record type +## 确定记录类型 -Check if the candidate type is compatible with `Int`, a class of 1. -Others that are 修补程序 of `Int` and that `Int` has all the required attributes are also compatible. +检查候选类型是否与 `Int` 兼容,1 类。 +其他是`Int`的修复程序并且`Int`具有所有必需属性的也是兼容的。 ~ -So `Nat` fit. However, if `Foo` also matches, it is determined by the containment relationship between `Nat` and `Foo`. -That is, subtype 方法 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. +所以`Nat`适合。但是,如果 `Foo` 也匹配,则由 `Nat` 和 `Foo` 之间的包含关系决定。 +即,选择子类型方法。 +如果两者之间没有包含关系,则会发生编译错误(这是一种安全措施,防止违背程序员的意图执行方法)。 +要消除错误,您需要明确指定补丁。 ``` erg o.method(x) -> P.method(o, x) ``` -## method resolution for universal 修补程序 +## 通用方法解析修补程序 -Define a patch like this: +像这样定义一个补丁: ``` 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. +在 `FnType` 补丁下可以使用如下代码。 我想知道这将如何解决。 ``` erg assert (Int -> Int).type == Int ``` -First, `FnType(T)` is registered in `provided_method_table` in the following format. +首先,`FnType(T)` 以下列格式注册到`provided_method_table` 中。 ``` erg provided_method_table = { @@ -87,8 +87,8 @@ provided_method_table = { } ``` -`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}`). +`FnType(T)` 检查匹配类型。 在这种情况下,`FnType(T)` 补丁类型是 `Type -> Type`。 +这匹配 `Int -> Int`。 如果合适,进行单态化和替换(取 `T -> T` 和 `Int -> Int`、`{T => Int}` 的差异)。 ``` erg assert FnType(Int).type == Int diff --git a/doc/zh_CN/compiler/transpile.md b/doc/zh_CN/compiler/transpile.md index 0f640339..5145268e 100644 --- a/doc/zh_CN/compiler/transpile.md +++ b/doc/zh_CN/compiler/transpile.md @@ -1,15 +1,15 @@ -# How is Erg code transpiled to Python code? +# Erg 代码如何转译成 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. +准确地说,Erg 代码被转译为 Python 字节码。 +但是,由于 Python 字节码几乎可以重构为 Python 代码,因此这里以等效的 Python 代码为例。 +顺便说一句,这里展示的示例是低优化级别。 +更高级的优化消除了不需要实例化的东西。 -## Record, Record type +## 记录,记录类型 -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__`. +它将被转译为一个命名元组。 +对于 namedtuple,请参阅 [此处](https://docs.python.jp/3/library/collections.html#collections.namedtuple)。 +有一个类似的函数,dataclass,但是由于 `__eq__` 和 `__hash__` 的自动实现,dataclass 的性能略有下降。 ``` erg Employee = Class {.name = Str; .id = Int} @@ -32,16 +32,16 @@ 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 +## 多态类型 -> WIPs +> 在制品 -## Instant Scope +## 即时范围 -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. +如果没有发生命名空间冲突,它只会被破坏和扩展。 +`x::y` 等名称在字节码中使用,不能与 Python 代码关联,但如果强制表示,则会如下所示。 ``` erg x = @@ -54,7 +54,7 @@ x::y = 1 x = x::y + 1 ``` -In case of conflict, define and use a function that can only be referenced internally. +万一发生冲突,定义和使用只能在内部引用的函数。 ``` erg x = @@ -70,10 +70,10 @@ def _(): x = _() ``` -## Visibility +## 可见性 -It does nothing for public variables as it is Python's default. -Private variables are handled by mangling. +它对公共变量没有任何作用,因为它是 Python 的默认值。 +私有变量由 mangling 处理。 ``` erg x=1 diff --git a/doc/zh_CN/compiler/type_var_normalization.md b/doc/zh_CN/compiler/type_var_normalization.md index 391e814c..fded3f21 100644 --- a/doc/zh_CN/compiler/type_var_normalization.md +++ b/doc/zh_CN/compiler/type_var_normalization.md @@ -1,39 +1,39 @@ -# Normalization +# 归一化 -* Erg's type argument normalization is based on SymPy's simplify function. +* Erg 的类型参数规范化基于 SymPy 的简化函数。 -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 方法 are as follows. +例如,当您定义 `concat: |T, M, N|([T; M], [T; N] -> [T; M+N])` 时,您可以匹配类型变量和参数而无需实例化它们.必须作出判断。 +平等判断自然有其局限性,但目前可能的判断及其方法如下。 -* 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` - Normalize to Σ[c] x == c*x, where c is a constant. - Constants are normalized by placing them on the left side of binary operations. + 归一化为 Σ[c] x == c*x,其中 c 是一个常数。 + 常量通过将它们放在二进制操作的左侧进行标准化。 -* Equality of double expressions: +* 双重表达式的相等性: `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` + `n >= m 和 m >= n -> m == n` -* Transitivity of inequalities: +* 不等式的传递性: `n > 0 -> n > -1` \ No newline at end of file From 06f8edc9e2c0cee34f6396fd7c64ec834ffb5352 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 12:56:25 +0800 Subject: [PATCH 10/42] translate save --- doc/EN/API/funcs.md | 12 +- doc/EN/API/modules/external/alstruct.md | 10 +- doc/EN/API/modules/repl.md | 2 +- doc/EN/API/modules/unit.md | 4 +- doc/EN/API/modules/unsound.md | 2 +- doc/EN/API/procs.md | 4 +- doc/EN/API/special.md | 20 +- doc/EN/API/types/classes/ArrayWithLen(T,N).md | 6 +- .../types/classes/ArrayWithMutLength!(T,N).md | 6 +- doc/EN/API/types/classes/Function(N).md | 2 +- doc/EN/API/types/classes/IntRange.md | 4 +- doc/EN/API/types/classes/Interval.md | 4 +- doc/EN/API/types/classes/Nat.md | 4 +- doc/EN/API/types/classes/Never.md | 2 +- doc/EN/API/types/classes/Option.md | 2 +- doc/EN/API/types/classes/Record.md | 2 +- doc/EN/API/types/classes/Result.md | 2 +- doc/EN/API/types/classes/Subroutine.md | 2 +- doc/EN/API/types/classes/Tensor.md | 4 +- doc/EN/API/types/classes/TransCell(T).md | 2 +- doc/EN/API/types/classes/Tuple.md | 4 +- doc/EN/API/types/traits/Add(R,O).md | 8 +- doc/EN/API/types/traits/Div(R,O).md | 2 +- doc/EN/API/types/traits/Num.md | 2 +- doc/EN/API/types/traits/SafeDiv(R,O).md | 2 +- doc/EN/API/types/traits/Sample.md | 4 +- doc/EN/API/types/traits/Unpack.md | 2 +- doc/EN/compiler/hir.md | 6 +- doc/EN/compiler/inference.md | 78 +-- doc/EN/compiler/refinement_subtyping.md | 2 +- doc/EN/compiler/trait_method_resolving.md | 14 +- doc/EN/compiler/transpile.md | 8 +- doc/EN/dev_guide/build_features.md | 8 +- doc/EN/dev_guide/faq_syntax.md | 8 +- doc/EN/dev_guide/terms.md | 6 +- doc/EN/dev_guide/unify_terms.md | 2 +- doc/EN/migration_from_py.md | 4 +- doc/EN/syntax/06_operator.md | 4 +- doc/EN/syntax/14_set.md | 10 +- doc/EN/syntax/18_ownership.md | 12 +- doc/EN/syntax/19_visibility.md | 34 +- doc/EN/syntax/20_naming_rule.md | 10 +- doc/EN/syntax/21_lambda.md | 18 +- doc/EN/syntax/23_closure.md | 14 +- doc/EN/syntax/24_module.md | 4 +- doc/EN/syntax/25_object_system.md | 4 +- doc/EN/syntax/26_pattern_matching.md | 24 +- doc/EN/syntax/27_comprehension.md | 6 +- doc/EN/syntax/28_spread_syntax.md | 8 +- doc/EN/syntax/29_decorator.md | 14 +- doc/EN/syntax/30_error_handling.md | 8 +- doc/EN/syntax/31_pipeline.md | 4 +- doc/EN/syntax/container_ownership.md | 6 +- doc/EN/syntax/quick_tour.md | 50 +- doc/EN/syntax/type/08_value.md | 4 +- doc/EN/syntax/type/14_dependent.md | 10 +- doc/EN/syntax/type/18_mut.md | 26 +- doc/EN/syntax/type/19_bound.md | 2 +- doc/EN/syntax/type/advanced/GADTs.md | 8 +- doc/EN/syntax/type/advanced/_rank2type.md | 24 +- doc/EN/syntax/type/advanced/default_param.md | 4 +- doc/EN/syntax/type/advanced/keyword_param.md | 6 +- doc/EN/syntax/type/advanced/kind.md | 26 +- doc/EN/syntax/type/advanced/marker_trait.md | 8 +- doc/EN/syntax/type/advanced/special.md | 6 +- doc/EN/syntax/type/advanced/typeof.md | 6 +- doc/EN/syntax/type/advanced/variance.md | 12 +- doc/EN/syntax/type/advanced/widening.md | 14 +- doc/EN/tools/pack.md | 2 +- doc/EN/tools/test.md | 6 +- doc/JA/dev_guide/build_features.md | 6 +- doc/zh_CN/API/modules/external/alstruct.md | 10 +- doc/zh_CN/API/modules/repl.md | 2 +- doc/zh_CN/API/modules/unit.md | 4 +- doc/zh_CN/API/modules/unsound.md | 2 +- doc/zh_CN/API/procs.md | 4 +- doc/zh_CN/API/special.md | 4 +- doc/zh_CN/compiler/inference.md | 78 +-- doc/zh_CN/compiler/refinement_subtyping.md | 2 +- doc/zh_CN/compiler/trait_method_resolving.md | 14 +- doc/zh_CN/compiler/transpile.md | 8 +- doc/zh_CN/dev_guide/build_features.md | 18 +- doc/zh_CN/dev_guide/doc_guideline.md | 16 +- doc/zh_CN/dev_guide/env.md | 24 +- doc/zh_CN/dev_guide/faq_syntax.md | 6 +- doc/zh_CN/dev_guide/rust_code_guideline.md | 30 +- doc/zh_CN/dev_guide/terms.md | 629 +++++++++--------- doc/zh_CN/dev_guide/unify_terms.md | 66 +- doc/zh_CN/migration_from_py.md | 4 +- doc/zh_CN/syntax/06_operator.md | 4 +- doc/zh_CN/syntax/14_set.md | 10 +- doc/zh_CN/syntax/18_ownership.md | 12 +- doc/zh_CN/syntax/19_visibility.md | 34 +- doc/zh_CN/syntax/20_naming_rule.md | 10 +- doc/zh_CN/syntax/21_lambda.md | 18 +- doc/zh_CN/syntax/23_closure.md | 14 +- doc/zh_CN/syntax/24_module.md | 4 +- doc/zh_CN/syntax/25_object_system.md | 4 +- doc/zh_CN/syntax/26_pattern_matching.md | 24 +- doc/zh_CN/syntax/27_comprehension.md | 6 +- doc/zh_CN/syntax/28_spread_syntax.md | 8 +- doc/zh_CN/syntax/29_decorator.md | 14 +- doc/zh_CN/syntax/30_error_handling.md | 8 +- doc/zh_CN/syntax/31_pipeline.md | 4 +- doc/zh_CN/syntax/container_ownership.md | 6 +- doc/zh_CN/syntax/quick_tour.md | 50 +- doc/zh_CN/syntax/type/08_value.md | 4 +- doc/zh_CN/syntax/type/14_dependent.md | 10 +- doc/zh_CN/syntax/type/18_mut.md | 26 +- doc/zh_CN/syntax/type/19_bound.md | 2 +- doc/zh_CN/syntax/type/advanced/GADTs.md | 8 +- doc/zh_CN/syntax/type/advanced/_rank2type.md | 24 +- .../syntax/type/advanced/default_param.md | 4 +- .../syntax/type/advanced/keyword_param.md | 6 +- doc/zh_CN/syntax/type/advanced/kind.md | 26 +- .../syntax/type/advanced/marker_trait.md | 8 +- doc/zh_CN/syntax/type/advanced/special.md | 6 +- doc/zh_CN/syntax/type/advanced/typeof.md | 6 +- doc/zh_CN/syntax/type/advanced/variance.md | 12 +- doc/zh_CN/syntax/type/advanced/widening.md | 14 +- doc/zh_CN/tools/pack.md | 2 +- doc/zh_CN/tools/test.md | 6 +- 122 files changed, 988 insertions(+), 983 deletions(-) diff --git a/doc/EN/API/funcs.md b/doc/EN/API/funcs.md index 78128595..81ba7fef 100644 --- a/doc/EN/API/funcs.md +++ b/doc/EN/API/funcs.md @@ -27,7 +27,7 @@ Emoji-capable terminals have a 🚨 prefix. Throw away `x`. Used when the return value is not used. Unlike `del`, it does not make the variable `x` inaccessible. -``` erg +```python p!x= # Let q! return some None or non-() value # use `discard` if you don't need it @@ -56,7 +56,7 @@ The structure type determined at compile time is obtained with `Typeof`. ### repeat|T|(x: T) -> RepeatIterator T -``` erg +```python rep = repeat 1 # Repeater(1) for! rep, i => print!i @@ -65,7 +65,7 @@ for! rep, i => ### dup|T; N|(x: T, N: Nat) -> [T; N] -``` erg +```python [a, b, c] = dup new(), 3 print! a # print! a == b # False @@ -73,7 +73,7 @@ print! a == b # False ### cycle|T|(it: Iterable T) -> CycleIterator T -``` erg +```python cycle([0, 1]).take 4 # [0, 1, 0, 1] cycle("hello").take 3 # "hellohellohello" ``` @@ -85,7 +85,7 @@ cycle("hello").take 3 # "hellohellohello" 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 +```python C = Class {i = Int} NewInt = ClassInt Months = Class 1..12 @@ -111,7 +111,7 @@ Create a new trait. Currently, only record types can be specified. 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 +```python x: Type of i = ... # TypeWarning: Typeof(i) == Int, please replace it ``` diff --git a/doc/EN/API/modules/external/alstruct.md b/doc/EN/API/modules/external/alstruct.md index 11946490..f38c0292 100644 --- a/doc/EN/API/modules/external/alstruct.md +++ b/doc/EN/API/modules/external/alstruct.md @@ -6,7 +6,7 @@ Modules that provide traits representing algebraic structures and patches for th ## BinOp -``` erg +```python BinOp Op: Kind 2 = Subsume Op(Self, Self.ReturnTypeOf Op), Additional: { .ReturnTypeof = TraitType -> Type } @@ -20,7 +20,7 @@ assert Nat.ReturnTypeof(Div) == Positive Ratio ## SemiGroup -``` erg +```python SemiGroup Op: Kind 2 = Op(Self, Self) IntIsSemiGroupAdd = Patch Int, Impl=SemiGroupAdd @@ -30,7 +30,7 @@ Int <: SemiGroup Add ## Functors -``` erg +```python # * Identity law: x.map(id) == x # * Composition law: x.map(f).map(g) == x.map(f.then g) Functor = Trait { @@ -40,7 +40,7 @@ Functor = Trait { ## Applicative -``` erg +```python # * Identity law: x.app(X.pure(id)) == x Applicative = Subsume Functor, Additional: { .pure|T: Type| = T -> Self T @@ -50,7 +50,7 @@ Applicative = Subsume Functor, Additional: { ## Monad -``` erg +```python Monad = Subsume Applicative, Additional: { .bind|T, U: Type| = (Self(T), T -> Self U) -> Self U } diff --git a/doc/EN/API/modules/repl.md b/doc/EN/API/modules/repl.md index a4091909..a0782532 100644 --- a/doc/EN/API/modules/repl.md +++ b/doc/EN/API/modules/repl.md @@ -18,7 +18,7 @@ View information about an object in a browser. Can be used offline. Infers a function given its arguments and return value. -``` erg +```python 1.guess((1,), 2) # [1, 2].guess((3, 4), [1, 2, 3, 4]) # ``` \ No newline at end of file diff --git a/doc/EN/API/modules/unit.md b/doc/EN/API/modules/unit.md index eab1babf..ba593143 100644 --- a/doc/EN/API/modules/unit.md +++ b/doc/EN/API/modules/unit.md @@ -6,7 +6,7 @@ By using the `unit` module, you can avoid mistakes such as passing numbers with 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 +```python {*} = import "unit" x = 6m # equivalent to `x = Meter.new(6)` @@ -33,7 +33,7 @@ In addition, the types `Unit1`, `UnitMul`, and `UnitDiv` are defined, which can 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 +```python Hertz = Patch UnitDiv(Unit1, Sec) SquareMeter = Patch UnitMul(Meter, Meter) ``` diff --git a/doc/EN/API/modules/unsound.md b/doc/EN/API/modules/unsound.md index 28998a72..9fc8ee9e 100644 --- a/doc/EN/API/modules/unsound.md +++ b/doc/EN/API/modules/unsound.md @@ -6,7 +6,7 @@ Provides APIs perform unsound and unsafe operations that cannot be guaranteed sa 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 +```python unsound = import "unsound" i = unsound. unsafe! do!: diff --git a/doc/EN/API/procs.md b/doc/EN/API/procs.md index 371b2f7c..36696540 100644 --- a/doc/EN/API/procs.md +++ b/doc/EN/API/procs.md @@ -2,7 +2,7 @@ ## print! -``` erg +```python print!(x) -> NoneType ``` @@ -10,7 +10,7 @@ print!(x) -> NoneType ##debug! -``` erg +```python debug!(x, type = Info) -> NoneType ``` diff --git a/doc/EN/API/special.md b/doc/EN/API/special.md index 698429dc..80dd6d28 100644 --- a/doc/EN/API/special.md +++ b/doc/EN/API/special.md @@ -8,7 +8,7 @@ Also, types such as `Pattern`, `Body`, and `Conv` appear for convenience, but su 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 +```python record = {i = 1; j = 2} f(x: Int, y = 2) = ... ``` @@ -16,7 +16,7 @@ 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 +```python print! Class() # > print! x: Int -> x + 1 # > C = Class() @@ -34,7 +34,7 @@ print! L # The `=` operator has a return value of "undefined". Multiple assignments and `=` in functions result in syntax errors. -``` erg +```python i = j = 1 # SyntaxError: multiple assignments are not allowed print!(x=1) # SyntaxError: cannot use `=` in function arguments # hint: did you mean keyword arguments (`x: 1`)? @@ -54,14 +54,14 @@ Generate anonymous procedure, procedure type. Determine if subject matches T. If they don't match, throw a compile error. -``` erg +```python a: Int f x: Int, y: Int = x / y ``` Also used for `:` applied styles. -``` erg +```python fx: y z @@ -69,7 +69,7 @@ fx: Like `:` and `=`, the result of the operation is undefined. -``` erg +```python _ = x: Int # SyntaxError: print!(x: Int) # SyntaxError: ``` @@ -91,7 +91,7 @@ Postfix operator. Call `x.unwrap()` and `return` immediately in case of error. For obj, execute lambdas that match the pattern. -``` erg +```python match[1, 2, 3]: (l: Int) -> log "this is type of Int" [[a], b] -> log a, b @@ -103,7 +103,7 @@ match[1, 2, 3]: Delete the variable `x`. However, built-in objects cannot be deleted. -``` erg +```python a = 1 del a # OK @@ -123,7 +123,7 @@ Generate an anonymous procedure with no arguments. Syntactic sugar for `() =>`. 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 +```python choice = 1 else 2 assert choice.get_then() == 1 assert choice.get_else() == 2 @@ -152,7 +152,7 @@ Generates sieve type, rank 2 type. Expand a nested collection. It can also be used for pattern matching. -``` erg +```python [x,...y] = [1, 2, 3] assert x == 1 and y == [2, 3] assert [x, ...y] == [1, 2, 3] diff --git a/doc/EN/API/types/classes/ArrayWithLen(T,N).md b/doc/EN/API/types/classes/ArrayWithLen(T,N).md index c9dd51c3..a80e0b96 100644 --- a/doc/EN/API/types/classes/ArrayWithLen(T,N).md +++ b/doc/EN/API/types/classes/ArrayWithLen(T,N).md @@ -6,7 +6,7 @@ * values_at(self, selectors: [Nat; N]) -> [T; N] -``` erg +```python assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] ``` @@ -15,7 +15,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] 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 + ```python assert[].all(_ -> False) ``` @@ -28,7 +28,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] * freq self -> [{T: Nat}] Returns the frequency of occurrence of an object. -``` erg +```python assert ["a", "b", "c", "b", "c", "b"].freq() \ == [{"a", 1}, {"b": 3}, {"c": 2}] ``` \ No newline at end of file diff --git a/doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md index 0a6fed5c..9a3bf966 100644 --- a/doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md +++ b/doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md @@ -6,7 +6,7 @@ * values_at(self, selectors: [Nat; N]) -> [T; N] -``` erg +```python assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] ``` @@ -15,7 +15,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] 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 + ```python assert[].all(_ -> False) ``` @@ -28,7 +28,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] * freq self -> [{T: Nat}] Returns the frequency of occurrence of an object. -``` erg +```python assert ["a", "b", "c", "b", "c", "b"].freq() \ == [{"a", 1}, {"b": 3}, {"c": 2}] ``` \ No newline at end of file diff --git a/doc/EN/API/types/classes/Function(N).md b/doc/EN/API/types/classes/Function(N).md index e210780b..e261d525 100644 --- a/doc/EN/API/types/classes/Function(N).md +++ b/doc/EN/API/types/classes/Function(N).md @@ -4,6 +4,6 @@ * then(self, g: Self) -> Self -``` erg +```python assert f(g(x)) == f.then(g) x ``` \ No newline at end of file diff --git a/doc/EN/API/types/classes/IntRange.md b/doc/EN/API/types/classes/IntRange.md index 1fb54f07..1e740156 100644 --- a/doc/EN/API/types/classes/IntRange.md +++ b/doc/EN/API/types/classes/IntRange.md @@ -2,7 +2,7 @@ `L..R` class. -``` erg +```python IntRange L, R: Int == L..R ``` @@ -12,7 +12,7 @@ IntRange L, R: Int == L..R normal addition. Addition of `Int` and `Nat` is defined here under the pretense that it is defined in each class. -``` erg +```python 0..10 + 1..12 == 1..22 Int + 0..10 == _..|Int|_ + 0..10 == _..|Int|_ == Int Nat + Nat == 0.._ + 0.._ == 0.._ == Nat diff --git a/doc/EN/API/types/classes/Interval.md b/doc/EN/API/types/classes/Interval.md index 5492537d..cab5d7b9 100644 --- a/doc/EN/API/types/classes/Interval.md +++ b/doc/EN/API/types/classes/Interval.md @@ -2,14 +2,14 @@ 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 +```python Months = 1..12 Alphabet = "a".."z" Weekdays = Monday..Friday Winter = November..December or January..February ``` -``` erg +```python 0..1 # integer range 0.0..1.0 # real (rational) range # or same for 0/1..1/1 diff --git a/doc/EN/API/types/classes/Nat.md b/doc/EN/API/types/classes/Nat.md index 6291fedb..8b2c8611 100644 --- a/doc/EN/API/types/classes/Nat.md +++ b/doc/EN/API/types/classes/Nat.md @@ -4,7 +4,7 @@ A type that represents a natural number. Used for array indices and range types. ## def -``` erg +```python Nat = 0.._ ``` @@ -12,7 +12,7 @@ Nat = 0.._ * times!(self, p: () => NoneType) -> NoneType -``` erg +```python 100.times! () => print! "hello!" ``` \ No newline at end of file diff --git a/doc/EN/API/types/classes/Never.md b/doc/EN/API/types/classes/Never.md index c6cdea6b..7cd3b284 100644 --- a/doc/EN/API/types/classes/Never.md +++ b/doc/EN/API/types/classes/Never.md @@ -3,7 +3,7 @@ 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 +```python # Never <: Panic f(): Panic = exit 0 # OK g(): Never = panic() # TypeError diff --git a/doc/EN/API/types/classes/Option.md b/doc/EN/API/types/classes/Option.md index a66367d9..f4e3f351 100644 --- a/doc/EN/API/types/classes/Option.md +++ b/doc/EN/API/types/classes/Option.md @@ -8,7 +8,7 @@ A type that represents "may fail". Extract it expecting the contents to be `T` type. If it is `None`, output `msg` and panic. -``` erg +```python x = "...".parse(Int).into(Option Int) x.unwrap() # UnwrappingError: unwrapped a None value x.unwrap("failed to convert from string to number") # UnwrappingError: failed to convert from string to number diff --git a/doc/EN/API/types/classes/Record.md b/doc/EN/API/types/classes/Record.md index 8e0bf5fc..d2398619 100644 --- a/doc/EN/API/types/classes/Record.md +++ b/doc/EN/API/types/classes/Record.md @@ -3,7 +3,7 @@ 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 +```python assert not Structural({i = Int}) in Class assert {i = Int} in Class diff --git a/doc/EN/API/types/classes/Result.md b/doc/EN/API/types/classes/Result.md index 64824ce6..bc80c435 100644 --- a/doc/EN/API/types/classes/Result.md +++ b/doc/EN/API/types/classes/Result.md @@ -1,6 +1,6 @@ # Result T, E -``` erg +```python Result T, E <: Error = Either T, E ``` diff --git a/doc/EN/API/types/classes/Subroutine.md b/doc/EN/API/types/classes/Subroutine.md index c7533cac..77a61f6c 100644 --- a/doc/EN/API/types/classes/Subroutine.md +++ b/doc/EN/API/types/classes/Subroutine.md @@ -8,7 +8,7 @@ Base type of Func and Proc. Interrupts a subroutine and returns the specified value. Useful for quickly escaping from a nest. -``` erg +```python f x = for 0..10, i -> if i == 5: diff --git a/doc/EN/API/types/classes/Tensor.md b/doc/EN/API/types/classes/Tensor.md index 98488e92..6d825cc7 100644 --- a/doc/EN/API/types/classes/Tensor.md +++ b/doc/EN/API/types/classes/Tensor.md @@ -3,13 +3,13 @@ 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 +```python Tensor.arrange(0..9) #Tensor[10] ``` * reshape(self, NewShape: [Nat; M]) -> Self NewShape -``` erg +```python (1..9).into(Tensor).reshape[3, 3] ``` diff --git a/doc/EN/API/types/classes/TransCell(T).md b/doc/EN/API/types/classes/TransCell(T).md index 9b042627..1ccf727c 100644 --- a/doc/EN/API/types/classes/TransCell(T).md +++ b/doc/EN/API/types/classes/TransCell(T).md @@ -3,7 +3,7 @@ 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 +```python a = TransCell!.new None a: TransCell! !NoneType a.set! 1 diff --git a/doc/EN/API/types/classes/Tuple.md b/doc/EN/API/types/classes/Tuple.md index fb4b33ee..1c58c0fc 100644 --- a/doc/EN/API/types/classes/Tuple.md +++ b/doc/EN/API/types/classes/Tuple.md @@ -8,7 +8,7 @@ A collection that holds objects of multiple types. Composites two ordered collections (arrays or tuples). - ``` erg + ```python assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4) ``` @@ -17,7 +17,7 @@ A collection that holds objects of multiple types. 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 + ```python assert ([1, 2, 3].zip([4, 5, 6]))[0] == (1, 4) assert ([1, 2, 3].zip_by((), [4, 5, 6]))[0] == (1, 4) assert ([1, 2, 3].zip_by([], [4, 5, 6]))[0] == [1, 4] diff --git a/doc/EN/API/types/traits/Add(R,O).md b/doc/EN/API/types/traits/Add(R,O).md index 952dd1b8..21febcc1 100644 --- a/doc/EN/API/types/traits/Add(R,O).md +++ b/doc/EN/API/types/traits/Add(R,O).md @@ -1,6 +1,6 @@ # Add R -``` erg +```python Add R = Trait { .AddO = Type .`_+_` = (Self, R) -> Self.AddO @@ -10,13 +10,13 @@ Add R = Trait { `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 +```python `_+_`(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 +```python assert [1, 2, 3].fold(0, `_+_`) == 6 call op, x, y = op(x, y) @@ -25,7 +25,7 @@ assert call(`_+_`, 1, 2) == 3 Addition is typed like this. -``` erg +```python f: |O: Type; A <: Add(Int, O)| A -> O f x = x + 1 diff --git a/doc/EN/API/types/traits/Div(R,O).md b/doc/EN/API/types/traits/Div(R,O).md index 3f0906d6..b08ece35 100644 --- a/doc/EN/API/types/traits/Div(R,O).md +++ b/doc/EN/API/types/traits/Div(R,O).md @@ -2,7 +2,7 @@ Use `SafeDiv` if there are no errors due to division by zero. -``` erg +```python Div R, O = Trait { .`/` = Self.(R) -> O or Panic } diff --git a/doc/EN/API/types/traits/Num.md b/doc/EN/API/types/traits/Num.md index a49e9815..73b1dc44 100644 --- a/doc/EN/API/types/traits/Num.md +++ b/doc/EN/API/types/traits/Num.md @@ -2,7 +2,7 @@ ## definition -``` erg +```python Num R = Add(R) and Sub(R) and Mul(R) and Eq Num = Num Self ``` diff --git a/doc/EN/API/types/traits/SafeDiv(R,O).md b/doc/EN/API/types/traits/SafeDiv(R,O).md index d214d620..8754edae 100644 --- a/doc/EN/API/types/traits/SafeDiv(R,O).md +++ b/doc/EN/API/types/traits/SafeDiv(R,O).md @@ -1,6 +1,6 @@ # SafeDiv R, O -``` erg +```python SafeDiv R, O = Subsume Div, { @Override .`/` = Self.(R) -> O diff --git a/doc/EN/API/types/traits/Sample.md b/doc/EN/API/types/traits/Sample.md index a51d45ac..f6646fdf 100644 --- a/doc/EN/API/types/traits/Sample.md +++ b/doc/EN/API/types/traits/Sample.md @@ -6,7 +6,7 @@ Note that this is a trait that assumes that you want an appropriate instance for 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 +```python assert Int. sample() == 42 assert Str. sample() == "example" # Int is sampled in 64bit range by default @@ -16,7 +16,7 @@ print! {x = Int; y = Int}.sample!() # {x = -32432892, y = 78458576891} Below is an implementation example of `Sample`. -``` erg +```python EmailAddress = Class {header = Str; domain = Str}, Impl=Sample and Show @Impl Show Email address. diff --git a/doc/EN/API/types/traits/Unpack.md b/doc/EN/API/types/traits/Unpack.md index 2b1c1d40..77530ca7 100644 --- a/doc/EN/API/types/traits/Unpack.md +++ b/doc/EN/API/types/traits/Unpack.md @@ -2,7 +2,7 @@ marker trait. When implemented, elements can be decomposed by pattern matching like records. -``` erg +```python C = Class {i = Int}, Impl = Unpack C.new i = Self::new {i;} {i} = C.new(1) diff --git a/doc/EN/compiler/hir.md b/doc/EN/compiler/hir.md index 896e6e61..501040f5 100644 --- a/doc/EN/compiler/hir.md +++ b/doc/EN/compiler/hir.md @@ -5,7 +5,7 @@ This struct contains the complete type information for every expression in the s 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 +```python v = ![] for! 0..10, i => v.push!i @@ -14,7 +14,7 @@ log v.sum() The AST generated from this code looks like this: -``` erg +```python AST(Module[ VarDef{ sig: VarSignature { @@ -71,7 +71,7 @@ AST(Module[ And the HIR generated from the AST looks like this: -``` erg +```python HIR(Module[ VarDef{ sig: VarSignature { diff --git a/doc/EN/compiler/inference.md b/doc/EN/compiler/inference.md index 4f513eb2..49815670 100644 --- a/doc/EN/compiler/inference.md +++ b/doc/EN/compiler/inference.md @@ -4,7 +4,7 @@ The notation used below is shown. -``` erg +```python Free type variables (type, unbound): ?T, ?U, ... Free-type variables (values, unbound): ?a, ?b, ... type environment (Γ): { x: T, ... } @@ -14,7 +14,7 @@ Type argument evaluation environment (E): { e -> e', ... } Let's take the following code as an example. -``` erg +```python v = ![] v.push! 1 print! v @@ -100,7 +100,7 @@ Type schemes are not usually considered first-class types. Configuring the type 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 +```python gen ?T = 'T inst 'T = ?T (?T ∉ Γ) ``` @@ -114,7 +114,7 @@ In addition, the operation that obtains the return type if the expression is a c 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 +```python unify(?T, Int) == Ok(()) # ?T == (Int) # S is the type assignment rule, T is the applicable type @@ -132,7 +132,7 @@ 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 +```python # If the formal parameter type is T f(x: T): T = ... @@ -147,7 +147,7 @@ Generalization is not a simple task. When multiple scopes are involved, "level m 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 +```python x -> y = x y @@ -156,7 +156,7 @@ x -> First, Erg allocates type variables as follows: The type of y is also unknown, but is left unassigned for now. -``` erg +```python x(: ?T) -> y = x y @@ -165,7 +165,7 @@ x(: ?T) -> 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 +```python x(: ?T) -> y = x (: inst ?T) y @@ -173,13 +173,13 @@ x(: ?T) -> Generalize when registering as the type of lvalue y. However, as we will see later, this generalization is imperfect and produces erroneous results. -``` erg +```python x(: ?T) -> y(:gen?T) = x(:?T) y ``` -``` erg +```python x(: ?T) -> y(: 'T) = x y @@ -187,7 +187,7 @@ x(: ?T) -> The type of y is now a quantified type variable `'T`. In the next line, `y` is used immediately. Concrete. -``` erg +```python x: ?T -> y(: 'T) = x y(: inst 'T) @@ -195,7 +195,7 @@ x: ?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 +```python x: ?T -> y = x y(: ?U) @@ -207,7 +207,7 @@ 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 +```python # normal type variable ?T<1>, ?T<2>, ... # type variable with subtype constraint @@ -216,7 +216,7 @@ So we introduce the level of type variables with the following notation. Levels Let's try again. -``` erg +```python x -> y = x y @@ -225,7 +225,7 @@ x -> 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 +```python # level 1 x (: ?T<2>) -> # level 2 @@ -235,7 +235,7 @@ x (: ?T<2>) -> First, instantiate the rvalue `x`. Same as before, nothing changed. -``` erg +```python x (: ?T<2>) -> y = x (: inst ?T<2>) y @@ -245,11 +245,11 @@ Here is the key. This is a generalization when assigning to the type of lvalue ` 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 +```python gen ?T = if n <= current_level, then= ?T, else= 'T ``` -``` erg +```python x (: ?T<2>) -> # current_level = 2 y(: gen ?T<2>) = x(: ?T<2>) @@ -258,7 +258,7 @@ x (: ?T<2>) -> That is, the lvalue `y` has type `?T<2>`. -``` erg +```python x (: ?T<2>) -> # ↓ not generalized y(: ?T<2>) = x @@ -267,13 +267,13 @@ x (: ?T<2>) -> 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 +```python x (: ?T<2>) -> y(: ?T<2>) = x y (: inst ?T<2>) ``` -``` erg +```python x (: ?T<2>) -> y = x y (: ?T<2>) @@ -283,7 +283,7 @@ 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 +```python fx, y = id(x) + y id x = x @@ -296,7 +296,7 @@ During the inference of `f`, the later defined function constant `id` is referen 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 +```python id: ?T<1> -> ?U<1> f x (: ?V<2>), y (: ?W<2>) = id(x) (: subst_call_ret([inst ?V<2>], inst ?T<1> -> ?U<1>)) + y @@ -308,7 +308,7 @@ 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 +```python # BAD f x (: ?V<2>), y (: ?W<2>) = # ?V<2>(<: ?T<1>) @@ -320,24 +320,24 @@ 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 +```python # OK f x (: ?V<2>), y (: ?W<2>) = # ?V<2> --> ?T<1> id(x) (: ?U<1>) + y (: ?W<2>) ``` -``` erg +```python f x (: ?T<1>), y (: ?W<2>) = (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], inst |'L <: Add('R)| ('L, 'R) -> 'L .AddO) ``` -``` erg +```python f x (: ?T<1>), y (: ?W<2>) = (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], (?L(<: Add(?R<2>))<2>, ?R<2 >) -> ?L<2>.AddO) ``` -``` erg +```python id: ?T<1> -> ?U<1> f x (: ?T<1>), y (: ?W<2>) = # ?U<1>(<: Add(?W<2>)) # Inherit the constraints of ?L @@ -346,26 +346,26 @@ f x (: ?T<1>), y (: ?W<2>) = (id(x) + x) (: ?U<1>.AddO) ``` -``` erg +```python # current_level = 1 f(x, y) (: gen ?T<1>, gen ?W<2> -> gen ?U<1>.AddO) = id(x) + x ``` -``` erg +```python id: ?T<1> -> ?U<1> f(x, y) (: |'W: Type| (?T<1>, 'W) -> gen ?U<1>(<: Add(?W<2>)).AddO) = id(x) + x ``` -``` erg +```python f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) = id(x) + x ``` When defining, raise the level so that it can be generalized. -``` erg +```python # ?T<1 -> 2> # ?U<1 -> 2> id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>) @@ -373,7 +373,7 @@ 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 +```python # ?U<2> --> ?T<2> f(x, y) (: |'W: Type| (?T<2>, 'W) -> ?T<2>(<: Add(?W<2>)).AddO) = id(x) + x @@ -385,13 +385,13 @@ 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 +```python f(x, y) (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = id(x) + x id(x) (: |'T: Type| 'T -> gen 'T) = x ``` -``` erg +```python f x, y (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = id(x) + y id(x) (: 'T -> 'T) = x @@ -399,13 +399,13 @@ id(x) (: 'T -> 'T) = x f(10, 1) (: subst_call_ret([inst {10}, inst {1}], inst |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T .AddO) ``` -``` erg +```python f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<1>) -> ? T<1>.AddO)) ``` Type variables are bounded to the smallest type that has an implementation. -``` erg +```python # ?T(:> {10} <: Add(?W<1>))<1> # ?W(:> {1})<1> # ?W(:> {1})<1> <: ?T<1> (:> {10}, <: Add(?W(:> {1})<1>)) @@ -421,7 +421,7 @@ f(10, 1) (: ({10}, {1}) -> Nat) The resulting type for the entire program is: -``` erg +```python f|W: Type, T <: Add(W)|(x: T, y: W): T.AddO = id(x) + y id|T: Type|(x: T): T = x @@ -430,7 +430,7 @@ f(10, 1): Nat I've also reprinted the original, unexplicitly typed program. -``` erg +```python fx, y = id(x) + y id x = x diff --git a/doc/EN/compiler/refinement_subtyping.md b/doc/EN/compiler/refinement_subtyping.md index f6695330..45a5c2d1 100644 --- a/doc/EN/compiler/refinement_subtyping.md +++ b/doc/EN/compiler/refinement_subtyping.md @@ -2,7 +2,7 @@ The sieve type is the following type. -``` erg +```python {I: Int | I >= 0} {S: StrWithLen N | N >= 1} {T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0} diff --git a/doc/EN/compiler/trait_method_resolving.md b/doc/EN/compiler/trait_method_resolving.md index f0d8b1a6..154b0d89 100644 --- a/doc/EN/compiler/trait_method_resolving.md +++ b/doc/EN/compiler/trait_method_resolving.md @@ -3,7 +3,7 @@ `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 +```python 1.times do: log "hello world" ``` @@ -27,7 +27,7 @@ But we really only have to think about types with methods, i.e. types with names 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 +```python provided_method_table = { ... "foo": [Foo], @@ -58,7 +58,7 @@ 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 +```python o.method(x) -> P.method(o, x) ``` @@ -66,20 +66,20 @@ o.method(x) -> P.method(o, x) Define a patch like this: -``` erg +```python 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 +```python assert (Int -> Int).type == Int ``` First, `FnType(T)` is registered in `provided_method_table` in the following format. -``` erg +```python provided_method_table = { ... "type": [FnType(T)], @@ -90,6 +90,6 @@ provided_method_table = { `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 +```python assert FnType(Int).type == Int ``` \ No newline at end of file diff --git a/doc/EN/compiler/transpile.md b/doc/EN/compiler/transpile.md index 0f640339..33dfd3e4 100644 --- a/doc/EN/compiler/transpile.md +++ b/doc/EN/compiler/transpile.md @@ -11,7 +11,7 @@ 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 +```python Employee = Class {.name = Str; .id = Int} employee = Employee.new({.name = "John Smith"; .id = 100}) @@ -43,7 +43,7 @@ It will also be converted to a simple tuple if it can be further optimized. 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 +```python x = y = 1 y+1 @@ -56,7 +56,7 @@ x = x::y + 1 In case of conflict, define and use a function that can only be referenced internally. -``` erg +```python x = y = 1 y+1 @@ -75,7 +75,7 @@ x = _() It does nothing for public variables as it is Python's default. Private variables are handled by mangling. -``` erg +```python x=1 y = x = 2 diff --git a/doc/EN/dev_guide/build_features.md b/doc/EN/dev_guide/build_features.md index d31e879d..9c5c10fe 100644 --- a/doc/EN/dev_guide/build_features.md +++ b/doc/EN/dev_guide/build_features.md @@ -10,10 +10,12 @@ Independent of Rust's `debug_assertions` flag. Set the system language to Japanese. Erg internal options, help (help, copyright, license, etc.) and error display are guaranteed to be Japanese. -## simplified_chinese +## simplified Chinese Set the system language to Simplified Chinese. +Erg internal options, help (help, copyright, license, etc.) and errors are displayed in Simplified Chinese. -## traditional_chinese +## traditional Chinese -Set the system language to Traditional Chinese. \ No newline at end of file +Set the system language to Traditional Chinese. +Erg internal options, help (help, copyright, license, etc.) and errors are displayed in Traditional Chinese. \ No newline at end of file diff --git a/doc/EN/dev_guide/faq_syntax.md b/doc/EN/dev_guide/faq_syntax.md index 6a34452a..b99627fe 100644 --- a/doc/EN/dev_guide/faq_syntax.md +++ b/doc/EN/dev_guide/faq_syntax.md @@ -11,7 +11,7 @@ This is because shared mutable state is prone to bugs and even violates type saf This is because `<>` and `[]` cause syntax conflicts. -``` erg +```python # version [] id[T: Type] [t]: [T] = t y = id[Int] # is this a function? @@ -30,7 +30,7 @@ y = id|Int| # OK This is because Erg is designed so that the type itself can also be treated as a value. -``` erg +```python A = [Int; 3] assert A[2] == Int T = (Int, Str) @@ -53,7 +53,7 @@ Because in many cases error handling with the `Result` type is a better solution In Erg, the `?` operator makes writing error-free. -``` erg +```python read_file!() = f = open!("foo.txt")? # Returns an error immediately if it fails, so f is of type File f.read_all!() @@ -84,7 +84,7 @@ However, in Erg, classes are final by default and multiple/multilevel inheritanc Pointing to structural traits by default complicates typing and can introduce behavior unintended by the programmer. -``` erg +```python # If T is a subtype of a structural trait... # f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T. f|T| x, y: T = x + y - x diff --git a/doc/EN/dev_guide/terms.md b/doc/EN/dev_guide/terms.md index d3bbc42f..d8d2c605 100644 --- a/doc/EN/dev_guide/terms.md +++ b/doc/EN/dev_guide/terms.md @@ -237,7 +237,7 @@ Or the mutating operator. To check (typically at runtime) whether a condition is true in code. This is done using the `assert` function, etc. -``` erg +```python sum = !0 for! 0..10, i => sum.add!i @@ -282,7 +282,7 @@ An object created by a class. An element of class type. ### [instant block](../syntax/00_basic.md#expression separator) -``` erg +```python x = y = f(a) z = g(b,c) @@ -644,7 +644,7 @@ To pass an argument to a function object and get the evaluation result. ### [decorator](../syntax/29_decorator.md) -``` erg +```python @deco f x = ... ``` diff --git a/doc/EN/dev_guide/unify_terms.md b/doc/EN/dev_guide/unify_terms.md index 02806bf1..abac7e76 100644 --- a/doc/EN/dev_guide/unify_terms.md +++ b/doc/EN/dev_guide/unify_terms.md @@ -25,7 +25,7 @@ In its original meaning, * 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). -``` erg +```python algebraic name <: (name == identifier) ​​<: symbol variable + constant == algebra ``` diff --git a/doc/EN/migration_from_py.md b/doc/EN/migration_from_py.md index af3a0e43..5e8565e7 100644 --- a/doc/EN/migration_from_py.md +++ b/doc/EN/migration_from_py.md @@ -9,7 +9,7 @@ s: str i: int = int(s) ``` -``` erg +```python s: Str res: Result(Int, IntParseError) = s. parse Int i: Int = res.unwrap() @@ -18,7 +18,7 @@ f: Result(Float, FloatParseError) = s. parse Float You can also use the `try_from` method. -``` erg +```python s: Str i: Int = Int.try_from(s).unwrap() f: Float = Float.try_from(s).unwrap() diff --git a/doc/EN/syntax/06_operator.md b/doc/EN/syntax/06_operator.md index abe81367..087f6862 100644 --- a/doc/EN/syntax/06_operator.md +++ b/doc/EN/syntax/06_operator.md @@ -5,7 +5,7 @@ Operators are symbols that represent operations. Operands are things to the (lef Operators are a kind of function, and thus are themselves first-class objects that can be bound to variables. When binding, it is necessary to enclose it with ``. For `+` (and `-`), there are both unary and binary operators, so `_+_`(binary operation)/`+_`(unary operation ) must be specified. -``` erg +```python add = `+` # SyntaxError: specify `_+_` or `+_` add=`_+_` assert f(1, 2) == 3 @@ -17,7 +17,7 @@ assert g(1, 2) == 2 Some fundamental operators, called special forms, cannot be bound. -``` erg +```python def = `=` # SyntaxError: cannot bind `=` operator, this is a special form # NG: def x, 1 function = `->` # SyntaxError: cannot bind `->` operator, this is a special form diff --git a/doc/EN/syntax/14_set.md b/doc/EN/syntax/14_set.md index 324b4969..3bace4d6 100644 --- a/doc/EN/syntax/14_set.md +++ b/doc/EN/syntax/14_set.md @@ -2,7 +2,7 @@ A set represents a collection, which is structurally a duplicate, unordered array. -``` erg +```python assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3} assert {1, 2} == {1, 1, 2} # duplicates are automatically removed assert {1, 2} == {2, 1} @@ -10,7 +10,7 @@ assert {1, 2} == {2, 1} Sets can perform set operations. -``` erg +```python assert 1 in {1, 2, 3} assert not 1 in {} assert {1} or {2} == {1, 2} @@ -20,7 +20,7 @@ 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 +```python s: {Int or Str} = {"a", 1, "b", -1} ``` @@ -28,7 +28,7 @@ s: {Int or Str} = {"a", 1, "b", -1} Sets can also be treated as types. Such types are called __Enum types__. -``` erg +```python i: {1, 2, 3} = 1 assert i in {1, 2, 3} ``` @@ -36,7 +36,7 @@ assert i in {1, 2, 3} Elements of the set are directly elements of the type. Note that the sets themselves are different. -``` erg +```python mut_set = {1, 2, 3}.into {Int; !3} mut_set.insert!(4) ``` diff --git a/doc/EN/syntax/18_ownership.md b/doc/EN/syntax/18_ownership.md index 1f1e0232..6c724767 100644 --- a/doc/EN/syntax/18_ownership.md +++ b/doc/EN/syntax/18_ownership.md @@ -9,7 +9,7 @@ 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 +```python v = [1, 2, 3].into [Int; !3] push! vec, x = @@ -34,7 +34,7 @@ The duplicated object is exactly the same as the original, but independent of ea 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 +```python capitalize s: Str!= s. capitalize!() s @@ -51,7 +51,7 @@ This is called freezing. Freezing is used, for example, when creating an iterato 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 +```python # Compute the sum of the values ​​produced by the iterator sum|T <: Add + HasUnit| i: Iterator T = ... @@ -69,7 +69,7 @@ y # y can still be touched Borrowing is cheaper than duplicating or freezing. Borrowing can be done in the following simple cases: -``` erg +```python peek_str ref(s: Str!) = log s @@ -80,7 +80,7 @@ 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 +```python steal_str ref(s: Str!) = # Since the log function only borrows the arguments, it can be sub-leased log s @@ -89,7 +89,7 @@ steal_str ref(s: Str!) = # hint: use `clone` method ``` -``` erg +```python steal_str ref(s: Str!) = # This is no good either (= consumes the right side) x = s # OwnershipError: cannot consume a borrowed value diff --git a/doc/EN/syntax/19_visibility.md b/doc/EN/syntax/19_visibility.md index e5ef1e80..170616f8 100644 --- a/doc/EN/syntax/19_visibility.md +++ b/doc/EN/syntax/19_visibility.md @@ -4,12 +4,12 @@ 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 +```python # foo.er x = "this is an invisible variable" ``` -``` erg +```python #bar.er foo = import "foo" foo.x # AttributeError: Module 'foo' has no attribute 'x' ('x' is private) @@ -18,12 +18,12 @@ 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 +```python # foo.er .x = "this is a visible variable" ``` -``` erg +```python #bar.er foo = import "foo" assert foo.x == "this is a visible variable" @@ -31,7 +31,7 @@ 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 +```python ::x = "this is an invisible variable" assert ::x == x assert self ::x == ::x @@ -40,7 +40,7 @@ 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 +```python ::x = "this is a private variable" y = x + 1 # exactly module::x @@ -50,7 +50,7 @@ By using `::`, you can distinguish variables with the same name within the scope Specify the scope of the variable you want to refer to on the left. Specify `module` for the top level. If not specified, the innermost variable is referenced as usual. -``` erg +```python ::x = 0 assert x == 0 y = @@ -66,7 +66,7 @@ y = In the anonymous subroutine scope, `self` specifies its own scope. -``` erg +```python x = 0 f = x -> log module::x, self::x @@ -75,7 +75,7 @@ f1# 0 1 `::` is also responsible for accessing private instance attributes. -``` erg +```python x = 0 C = Class {x = Int} C. @@ -89,12 +89,12 @@ C. A class defined in one module can actually define methods from an external module. -``` erg +```python # foo.er .Foo = Class() ``` -``` erg +```python #bar.er {Foo; ...} = import "foo" @@ -113,7 +113,7 @@ 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 +```python # baz.er {Foo; ...} = import "foo" @@ -124,7 +124,7 @@ foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defi 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 +```python #bar.er {.Foo; ...} = import "foo" @@ -136,7 +136,7 @@ Foo. If you want to do something like this, define a [patch](./type/07_patch.md). -``` erg +```python #bar.er {Foo; ...} = import "foo" @@ -147,7 +147,7 @@ Foo Impl. public self = self::private() ``` -``` erg +```python # baz.er {Foo; ...} = import "foo" {FooImpl; ...} = import "bar" @@ -161,7 +161,7 @@ foo.public() Variable visibility is not limited to complete public/private. You can also publish with restrictions. -``` erg +```python # foo.er .record = { .a = { @@ -179,7 +179,7 @@ _ = .record.a.y # OK _ = .record.a.z # OK ``` -``` erg +```python foo = import "foo" _ = foo.record.a.x # VisibilityError _ = foo.record.a.y # VisibilityError diff --git a/doc/EN/syntax/20_naming_rule.md b/doc/EN/syntax/20_naming_rule.md index dee0d1cf..bba494fb 100644 --- a/doc/EN/syntax/20_naming_rule.md +++ b/doc/EN/syntax/20_naming_rule.md @@ -2,7 +2,7 @@ If you want to use a variable as a constant expression, make sure it starts with a capital letter. Two or more letters may be lowercase. -``` erg +```python i: Option Type = Int match i: t: Type -> log "type" @@ -12,7 +12,7 @@ match i: Objects with side effects always end with `!`. Procedures and procedural methods, and mutable types. However, the `Proc` type itself is not mutable. -``` erg +```python # Callable == Func or Proc c: Callable = print! match c: @@ -22,7 +22,7 @@ match c: If you want to expose an attribute to the outside world, define it with `.` at the beginning. If you don't put `.` at the beginning, it will be private. To avoid confusion, they cannot coexist within the same scope. -``` erg +```python o = {x = 1; .x = 2} # SyntaxError: private and public variables with the same name cannot coexist ``` @@ -32,7 +32,7 @@ The above rule can be circumvented by enclosing the string in single quotes ('') A character string enclosed in single quotes like this is called a literal identifier. This is used when calling APIs (FFI) of other languages ​​such as Python. -``` erg +```python bar! = pyimport("foo").'bar' ``` @@ -40,7 +40,7 @@ Identifiers that are also valid in Erg do not need to be enclosed in ''. Furthermore, literal identifiers can contain both symbols and spaces, so strings that cannot normally be used as identifiers can be used as identifiers. -``` erg +```python '∂/∂t' y 'test 1: pass x to y'() ``` diff --git a/doc/EN/syntax/21_lambda.md b/doc/EN/syntax/21_lambda.md index 08415e13..9a534f48 100644 --- a/doc/EN/syntax/21_lambda.md +++ b/doc/EN/syntax/21_lambda.md @@ -2,7 +2,7 @@ Anonymous functions are a syntax for creating function objects on the fly without naming them. -``` erg +```python # `->` is an anonymous function operator # same as `f x, y = x + y` f = (x, y) -> x + y @@ -12,7 +12,7 @@ g = (x, y: Int): Int -> x + y You can omit the `()` if there is only one argument. -``` erg +```python assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4] assert ((i, j) -> [i, j])(1, 2) == [1, 2] ``` @@ -20,14 +20,14 @@ 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 +```python for 0..9, i: Int -> ... ``` In anonymous functions, there is a difference in parsing due to whitespace. -``` erg +```python # In this case, interpreted as `T(() -> Int)` i: T() -> Int # in this case it is interpreted as (U()) -> Int @@ -36,7 +36,7 @@ k: U() -> Int Anonymous functions can be used without arguments. -``` erg +```python # `=>` is an anonymous procedure operator p! = () => print! "`p!` was called" # `() ->`, `() =>` have syntax sugar `do`, `do!` @@ -46,7 +46,7 @@ p!() # `p!` was called No-argument functions can be used for lazy initialization. -``` erg +```python time = import "time" date = import "datetime" now = if! True: @@ -59,7 +59,7 @@ now = if! True: 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 +```python n = (Complex or Ratio or Int).sample!() i = matchn: PI -> PI # if equal to constant PI @@ -71,7 +71,7 @@ i = matchn: Error handling is also generally done using `?` or `match`. -``` erg +```python res: ParseResult Int matchres: i: Int -> i @@ -85,7 +85,7 @@ match res2: ## Anonymous polycorrelation coefficient -``` erg +```python # same as id|T| x: T = x id = |T| x: T -> x ``` diff --git a/doc/EN/syntax/23_closure.md b/doc/EN/syntax/23_closure.md index 52c6c917..06128bf3 100644 --- a/doc/EN/syntax/23_closure.md +++ b/doc/EN/syntax/23_closure.md @@ -2,7 +2,7 @@ Erg subroutines have a feature called a "closure" that captures external variables. -``` erg +```python outer = 1 f x = outer + x assert f(1) == 2 @@ -10,7 +10,7 @@ assert f(1) == 2 As with immutable objects, mutable objects can also be captured. -``` erg +```python sum = !0 for! 1..10, i => sum.add!i @@ -25,7 +25,7 @@ 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 +```python # !!! This code actually gives an error !!! i = !0 f x = i + x @@ -39,7 +39,7 @@ 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 +```python i = !0 immut_i = i.clone().freeze() fx = immut_i + x @@ -50,7 +50,7 @@ assert f 1 == 1 ## avoid mutable state, functional programming -``` erg +```python # Erg sum = !0 for! 1..10, i => @@ -71,7 +71,7 @@ assert sum == 45 However, Erg recommends a simpler notation. Instead of carrying around state using subroutines and mutable objects, use a style of localizing state using functions. This is called functional programming. -``` erg +```python # Functional style sum = (1..10).sum() assert sum == 45 @@ -83,7 +83,7 @@ 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 +```python # start with 0, result will sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i) assert sum == 45 diff --git a/doc/EN/syntax/24_module.md b/doc/EN/syntax/24_module.md index 98027038..c33a57dc 100644 --- a/doc/EN/syntax/24_module.md +++ b/doc/EN/syntax/24_module.md @@ -7,7 +7,7 @@ Erg allows you to think of the file itself as a single record. This is called a .i = 1 ``` -``` erg +```python # Defining the foo module is almost the same as defining this record foo = {.i = 1} ``` @@ -21,7 +21,7 @@ assert foo.i == 1 Since module types are also record types, deconstruction assignment is possible. -``` erg +```python {sin; cos; ...} = import "math" ``` diff --git a/doc/EN/syntax/25_object_system.md b/doc/EN/syntax/25_object_system.md index c02573ea..ed398a98 100644 --- a/doc/EN/syntax/25_object_system.md +++ b/doc/EN/syntax/25_object_system.md @@ -15,7 +15,7 @@ All data that can be assigned to a variable. The attributes of the `Object` clas An object generated by a record literal (`{attr = value; ...}`). This object has basic methods such as `.clone` and `.__sizeof__`. -``` erg +```python obj = {.x = 1} assert obj.x == 1 @@ -27,7 +27,7 @@ assert obj2.x == 1 and obj2.y == 2 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 +```python # note that there is no `.` in private_attr record = {.public_attr = j; private_attr = 2; .method = self -> self.i + 1} record. public_attr == 2 diff --git a/doc/EN/syntax/26_pattern_matching.md b/doc/EN/syntax/26_pattern_matching.md index 8539689e..c48c07c7 100644 --- a/doc/EN/syntax/26_pattern_matching.md +++ b/doc/EN/syntax/26_pattern_matching.md @@ -4,7 +4,7 @@ ### variable pattern -``` erg +```python # basic assignments i = 1 # with type @@ -28,7 +28,7 @@ a: Array Int, 4 = [0, 1, 2, 3] ### Literal patterns -``` erg +```python # Raise a TypeError if `i` cannot be determined to be 1 at compile time. # omit `_: {1} = i` 1 = i @@ -47,7 +47,7 @@ fibn: Nat = fibn-1 + fibn-2 ### constant pattern -``` erg +```python cond=False match! cond: True => print! "cond is True" @@ -64,7 +64,7 @@ name = match num: ### Sieve pattern -``` erg +```python # these two are the same Array(T, N: {N | N >= 3}) Array(T, N | N >= 3) @@ -75,7 +75,7 @@ f(1, 0) # TypeError: N (2nd parameter) must be 1 or more ### discard (wildcard) pattern -``` erg +```python _ = 1 _: Int = 1 zero_ = 0 @@ -86,7 +86,7 @@ right(_, r) = r It is used in combination with the tuple/array/record pattern described later. -``` erg +```python [i,...j] = [1, 2, 3, 4] assert j == [2, 3, 4] first|T|(fst: T, ...rest: T) = fst @@ -95,7 +95,7 @@ assert first(1, 2, 3) == 1 ### Tuple pattern -``` erg +```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) # If not nested, () can be omitted (1, 2 are treated as (1, 2)) @@ -106,7 +106,7 @@ f(x, y) = ... ### array pattern -``` erg +```python [i, j] = [1, 2] [[k, l], _] = [[1, 2], [3, 4]] @@ -116,7 +116,7 @@ length[_, ...rest] = 1 + lengthrest #### record pattern -``` erg +```python record = {i = 1; j = 2; k = 3} {j; ...} = record # i, k will be freed @@ -133,7 +133,7 @@ f {x: Int; y: Int} = ... ### Data class pattern -``` erg +```python Point = Inherit {x = Int; y = Int} p = Point::{x = 1; y = 2} Point::{x; y} = p @@ -156,7 +156,7 @@ List T. *Actually, it's just an enumeration type -``` erg +```python match x: i: {1, 2} -> "one or two: {i}" _ -> "other" @@ -166,7 +166,7 @@ match x: *Actually, it is just an interval type. -``` erg +```python # 0 < i < 1 i: 0<..<1 = 0.5 # 1 < j <= 2 diff --git a/doc/EN/syntax/27_comprehension.md b/doc/EN/syntax/27_comprehension.md index bd4ea15b..24c903e0 100644 --- a/doc/EN/syntax/27_comprehension.md +++ b/doc/EN/syntax/27_comprehension.md @@ -9,7 +9,7 @@ A guard clause can be omitted, but a bind clause cannot be omitted, and a guard Comprehension example -``` erg +```python # the layout clause is i # bind clause is i <- [0, 1, 2] assert [i | i <- [0, 1, 2]] == [0, 1, 2] @@ -36,7 +36,7 @@ For Haskell list comprehensions, the order of variables makes a difference in th [(i, j) | j <- [3..5], i <- [1..3]] == [(1,3),(2,3),(3,3),(1 ,4),(2,4),(3,4),(1,5),(2,5),(3,5)] ``` -``` erg +```python # Erg assert [(i, j) | i <- 1..<3; j <- 3..<5] == [(i, j) | j <- 3..<5; i <- 1.. <3] ``` @@ -53,7 +53,7 @@ assert [(i, j) for i in range(1, 3) for j in range(3, 5)] == [(i, j) for j in ra Similar to comprehensions are sieve types. A sieve type is a type (enumerated type) created in the form `{Name: Type | Predicate}`. In the case of the sieve type, only one Name can be specified and the layout cannot be specified (however, multiple values ​​can be handled if it is a tuple type), and the Predicate can be calculated at compile time, that is, only a constant expression can be specified. -``` erg +```python Nat = {I: Int | I >= 0} # If the predicate expression is only and, it can be replaced with ; # Nat2D = {(I, J): (Int, Int) | I >= 0; J >= 0} diff --git a/doc/EN/syntax/28_spread_syntax.md b/doc/EN/syntax/28_spread_syntax.md index aed87510..5f8f760a 100644 --- a/doc/EN/syntax/28_spread_syntax.md +++ b/doc/EN/syntax/28_spread_syntax.md @@ -2,7 +2,7 @@ In a decomposing assignment, putting `...` in front of a variable expands all remaining elements into that variable. This is called expansion assignment. -``` erg +```python [x,...y] = [1, 2, 3] assert x == 1 assert y == [2, 3] @@ -16,7 +16,7 @@ assert y == (2, 3) 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 +```python {sin; cos; tan; ..} = import "math" ``` @@ -24,14 +24,14 @@ After that, you can use `sin, cos, tan` locally. You can do the same with records. -``` erg +```python record = {x = 1; y = 2} {x; y; ...} = record ``` If you want to expand all, use `{*} = record`. It is `open` in OCaml. -``` erg +```python record = {x = 1; y = 2} {*} = records assert x == 1 and y == 2 diff --git a/doc/EN/syntax/29_decorator.md b/doc/EN/syntax/29_decorator.md index a5ed389c..243fe7f0 100644 --- a/doc/EN/syntax/29_decorator.md +++ b/doc/EN/syntax/29_decorator.md @@ -3,7 +3,7 @@ Decorators are used to add or demonstrate a particular state or behavior to a type or function. The syntax of the decorator is as follows. -``` erg +```python @deco X=... ``` @@ -12,7 +12,7 @@ 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 +```python X=... X = deco(X) ``` @@ -20,7 +20,7 @@ X = deco(X) Erg doesn't allow reassignment of variables, so code like the one above won't work. For simple variables it's the same as `X = deco(...)`, but for instant blocks and subroutines you can't do that, so you need a decorator. -``` erg +```python @deco f x = y = ... @@ -50,7 +50,7 @@ Used when overriding attributes. By default, Erg will throw an error if you try Indicates that the argument trait is implemented. -``` erg +```python Add = Trait { .`_+_` = Self.(Self) -> Self } @@ -71,7 +71,7 @@ C. Specifies the attachment patch that comes with the trait by default. This allows you to reproduce the same behavior as Rust traits. -``` erg +```python # foo.er Add R = Trait { .AddO = Type @@ -88,7 +88,7 @@ AddForOdd.AddO = Even This will automatically apply the attachment patch when importing traits from other modules. -``` erg +```python # Originally, IntIsBinAdd and OddIsBinAdd should be imported at the same time, but if it's an attachment patch, you can omit it {BinAdd; ...} = import "foo" @@ -98,7 +98,7 @@ assert Odd.AddO == Even Internally it's just attached using the trait's `.attach` method. Conflicts can be removed with the trait's `.detach` method. -``` erg +```python @Attach X T = Trait... assert X in T. attaches diff --git a/doc/EN/syntax/30_error_handling.md b/doc/EN/syntax/30_error_handling.md index c67e363a..c52d5cbf 100644 --- a/doc/EN/syntax/30_error_handling.md +++ b/doc/EN/syntax/30_error_handling.md @@ -30,7 +30,7 @@ except 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 +```python # Erg try!: do!: @@ -50,7 +50,7 @@ The benefits of using the `Result` type don't stop there. The `Result` type is a Since the `Error`/`Result` type alone does not cause side effects, unlike exceptions, it cannot have information such as the sending location (Context), but if you use the `.context` method, you can put information in the `Error` object. can be added. The `.context` method is a type of method that consumes the `Error` object itself and creates a new `Error` object. They are chainable and can hold multiple contexts. -``` erg +```python f() = todo() \ .context "to be implemented in ver 1.2" \ @@ -71,7 +71,7 @@ Therefore, in Erg, the `Error` object has an attribute called `.stack`, and repr `.stack` is an array of caller objects. Each time an Error object is `returned` (including by `?`) it pushes its calling subroutine onto the `.stack`. And if it is `?`ed or `.unwrap`ed in a context where `return` is not possible, it will panic with a traceback. -``` erg +```python f x = ... y = foo.try_some(x)? @@ -100,7 +100,7 @@ An unrecoverable error is an error caused by an external factor such as a softwa Panic is done with the `panic` function. -``` erg +```python panic "something went wrong!" ``` diff --git a/doc/EN/syntax/31_pipeline.md b/doc/EN/syntax/31_pipeline.md index 652f756d..258c7cc9 100644 --- a/doc/EN/syntax/31_pipeline.md +++ b/doc/EN/syntax/31_pipeline.md @@ -2,7 +2,7 @@ Pipeline operators are used like this: -``` erg +```python assert f(g(x)) == (x |> g |> f) assert f(g(x, y)) == ((x, y) |> g |> f) ``` @@ -11,7 +11,7 @@ In other words, the order `Callable(object)` can be changed to `object |> Callab The pipeline operator can also be used on methods. For methods, `object.method(args)` changes to `object |>.method(args)`. It looks like just more `|>`, but since the bond strength is low, you may be able to reduce the amount of `()`. -``` erg +```python rand = -1.0..1.0 |>.sample!() log rand # 0.2597... diff --git a/doc/EN/syntax/container_ownership.md b/doc/EN/syntax/container_ownership.md index 3067bb35..f9206220 100644 --- a/doc/EN/syntax/container_ownership.md +++ b/doc/EN/syntax/container_ownership.md @@ -2,7 +2,7 @@ `[]` is different from normal methods. -``` erg +```python a = [!1, !2] a[0].inc!() assert a == [2, 2] @@ -13,7 +13,7 @@ The type of `a[0]` here should clearly be `Ref!(Int!)` (the type of `a[0]` depen 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 +```python C = Class {i = Int!} C. get(ref self) = self::i # TypeError: `self::i` is `Int!` (require ownership) but `get` doesn't own `self` @@ -33,7 +33,7 @@ own_do! C.new({i = 1}).steal(), i => i.inc!() Also, `[]` can be disowned, but the element is not shifted. -``` erg +```python a = [!1, !2] i = a[0] i.inc!() diff --git a/doc/EN/syntax/quick_tour.md b/doc/EN/syntax/quick_tour.md index 0c5e6cf7..eca193f8 100644 --- a/doc/EN/syntax/quick_tour.md +++ b/doc/EN/syntax/quick_tour.md @@ -10,7 +10,7 @@ Please think that the parts not mentioned are the same as Python. Variables are defined with `=`. As with Haskell, variables once defined cannot be changed. However, it can be shadowed in another scope. -``` erg +```python i = 0 if True: i = 1 @@ -20,7 +20,7 @@ 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 +```python PI = 3.141592653589793 match random.random!(0..10): PIs: @@ -32,7 +32,7 @@ match random.random!(0..10): 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 +```python i: Int i = 10 ``` @@ -41,7 +41,7 @@ i = 10 You can define it just like in Haskell. -``` erg +```python fib0 = 0 fib1 = 1 fibn = fib(n - 1) + fib(n - 2) @@ -49,7 +49,7 @@ fibn = fib(n - 1) + fib(n - 2) An anonymous function can be defined like this: -``` erg +```python i -> i + 1 assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4] ``` @@ -62,7 +62,7 @@ The Erg-specific operators are: It's like `ref` in Ocaml. -``` erg +```python i = !0 i.update! x -> x + 1 assert i == 1 @@ -72,13 +72,13 @@ assert i == 1 Subroutines with side effects are called procedures and are marked with `!`. -``` erg +```python print! 1 # 1 ``` ## generic function (polycorrelation) -``` erg +```python id|T|(x: T): T = x id(1): Int id("a"): Str @@ -88,7 +88,7 @@ id("a"): Str You can use the equivalent of records in ML-like languages ​​(or object literals in JS). -``` erg +```python p = {x = 1; y = 2} ``` @@ -96,7 +96,7 @@ p = {x = 1; y = 2} Ergs are owned by mutable objects (objects mutated with the `!` operator) and cannot be rewritten from multiple places. -``` erg +```python i = !0 j = i assert j == 0 @@ -109,13 +109,13 @@ Immutable objects, on the other hand, can be referenced from multiple places. Prefixing a variable with `.` makes it a public variable and allows it to be referenced from external modules. -``` erg +```python # foo.er .x = 1 y = 1 ``` -``` erg +```python foo = import "foo" assert foo.x == 1 foo.y # VisibilityError @@ -125,7 +125,7 @@ foo.y # VisibilityError ### variable pattern -``` erg +```python # basic assignments i = 1 # with type @@ -137,7 +137,7 @@ fn: Int -> Int = x -> x + 1 ### Literal patterns -``` erg +```python # if `i` cannot be determined to be 1 at compile time, TypeError occurs. # shorthand of `_: {1} = i` 1 = i @@ -154,7 +154,7 @@ fibn: Nat = fibn-1 + fibn-2 ### constant pattern -``` erg +```python PI = 3.141592653589793 E = 2.718281828459045 num = PI @@ -166,7 +166,7 @@ name = match num: ### discard (wildcard) pattern -``` erg +```python _ = 1 _: Int = 1 right(_, r) = r @@ -176,7 +176,7 @@ right(_, r) = r Used in combination with the tuple/array/record pattern described later. -``` erg +```python [i,...j] = [1, 2, 3, 4] assert j == [2, 3, 4] first|T|(fst: T, ...rest: T) = fst @@ -185,7 +185,7 @@ assert first(1, 2, 3) == 1 ### Tuple pattern -``` erg +```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) # If not nested, () can be omitted (1, 2 are treated as (1, 2)) @@ -194,14 +194,14 @@ m, n = 1, 2 ### array pattern -``` erg +```python length[] = 0 length[_, ...rest] = 1 + lengthrest ``` #### record pattern -``` erg +```python {sin; cos; tan; ...} = import "math" {*} = import "math" # import all @@ -213,7 +213,7 @@ age = match person: ### Data class pattern -``` erg +```python Point = Inherit {x = Int; y = Int} p = Point::{x = 1; y = 2} Point::{x; y} = p @@ -221,7 +221,7 @@ Point::{x; y} = p ## Comprehensions -``` erg +```python odds = [i | i <- 1..100; i % 2 == 0] ``` @@ -234,7 +234,7 @@ Erg does not support multiple/multilevel inheritance. 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 +```python XY = Trait {x = Int; y = Int} Z = Trait {z = Int} XYZ = XY and Z @@ -254,13 +254,13 @@ You can give implementations to classes and traits. A predicate expression can be type-restricted. -``` erg +```python Nat = {I: Int | I >= 0} ``` ## parametric type with value (dependent type) -``` erg +```python a: [Int; 3] b: [Int; 4] a + b: [Int; 7] diff --git a/doc/EN/syntax/type/08_value.md b/doc/EN/syntax/type/08_value.md index 21db678b..9f0bf89c 100644 --- a/doc/EN/syntax/type/08_value.md +++ b/doc/EN/syntax/type/08_value.md @@ -2,7 +2,7 @@ Value types are Erg built-in types that can be evaluated at compile time, specifically: -``` erg +```python Value = ( Int or Nat @@ -23,7 +23,7 @@ Value = ( Value-type objects, constants, and compile-time subroutines applied to them are called __constant expressions__. -``` erg +```python 1, 1.0, 1+2im, True, None, "aaa", [1, 2, 3], Fib(12) ``` diff --git a/doc/EN/syntax/type/14_dependent.md b/doc/EN/syntax/type/14_dependent.md index c7ec3eb6..4871c095 100644 --- a/doc/EN/syntax/type/14_dependent.md +++ b/doc/EN/syntax/type/14_dependent.md @@ -6,7 +6,7 @@ A dependent type is a type that takes a value as an argument. Ordinary polymorph 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 +```python a1 = [1, 2, 3] assert a1 in [Nat; 3] a2 = [4, 5, 6, 7] @@ -16,7 +16,7 @@ assert a1 + a2 in [Nat; 7] If the type object passed in the function argument is related to the return type, write: -``` erg +```python narray: |N: Nat| {N} -> [{N}; N] narray(N: Nat): [N; N] = [N; N] assert array(3) == [3, 3, 3] @@ -26,7 +26,7 @@ When defining a dependent type, all type arguments must be constants. Dependent types themselves exist in existing languages, but Erg has the feature of defining procedural methods on dependent types. -``` erg +```python x=1 f x = print! f::x, module::x @@ -42,7 +42,7 @@ T(1).x() # 1 Type arguments of mutable dependent types can be transitioned by method application. Transition specification is done with `~>`. -``` erg +```python # Note that `Id` is an immutable type and cannot be transitioned VM!(State: {"stopped", "running"}! := _, Id: Nat := _) = Class(..., Impl := Phantom! State) VM!(). @@ -66,7 +66,7 @@ vm.stop!() # TypeError: VM!(!"stopped", 1) doesn't have .stop!() You can also embed or inherit existing types to create dependent types. -``` erg +```python MyArray(T, N) = Inherit[T; N] # The type of self: Self(T, N) changes in conjunction with .array diff --git a/doc/EN/syntax/type/18_mut.md b/doc/EN/syntax/type/18_mut.md index 63ab9719..137e1954 100644 --- a/doc/EN/syntax/type/18_mut.md +++ b/doc/EN/syntax/type/18_mut.md @@ -5,7 +5,7 @@ By default all types in Erg are immutable, i.e. their internal state cannot be updated. But you can of course also define mutable types. Variable types are declared with `!`. -``` erg +```python Person! = Class({name = Str; age = Nat!}) Person!. greet! ref! self = print! "Hello, my name is {self::name}. I am {self::age}." @@ -19,7 +19,7 @@ Mutable types can define procedural methods that rewrite instances, but having p Destructive operations on mutable objects are primarily done via the `.update!` method. The `.update!` method is a higher-order procedure that updates `self` by applying the function `f`. -``` erg +```python i = !1 i.update! old -> old + 1 assert i == 2 @@ -27,7 +27,7 @@ assert i == 2 The `.set!` method simply discards the old content and replaces it with the new value. .set!x = .update!_ -> x. -``` erg +```python i = !1 i.set! 2 assert i == 2 @@ -35,14 +35,14 @@ assert i == 2 The `.freeze_map` method operates on values ​​unchanged. -``` erg +```python a = [1, 2, 3].into [Nat; !3] x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(Array) ``` In a polymorphic immutable type the type argument `T` of the type is implicitly assumed to be immutable. -``` erg +```python # ImmutType < Type KT: ImmutType = Class ... K!T: Type = Class ... @@ -53,7 +53,7 @@ In the standard library, variable `(...)!` types are often based on immutable `( Note that there are several types of object mutability. Below we will review the immutable/mutable semantics of the built-in collection types. -``` erg +```python # array type ## immutable types [T; N] # Cannot perform mutable operations @@ -72,7 +72,7 @@ For variable array types, just add `!` to the part you want to be variable, and These array types are syntactic sugar, the actual types are: -``` erg +```python # actually 4 types [T; N] = Array(T, N) [T; !N] = Array!(T, !N) @@ -85,7 +85,7 @@ These array types are syntactic sugar, the actual types are: This is what it means to be able to change the type. -``` erg +```python a = [1, 2, 3].into [!Nat; 3] a.map!(_ -> "a") a: [!Str; 3] @@ -93,7 +93,7 @@ a: [!Str; 3] The same is true for other collection types. -``` erg +```python # tuple type ## immutable types (T, U) # No change in number of elements, contents cannot be changed @@ -103,7 +103,7 @@ The same is true for other collection types. ... ``` -``` erg +```python # Set type ## immutable types {T; N} # number of immutable elements, contents cannot be changed @@ -114,7 +114,7 @@ The same is true for other collection types. ... ``` -``` erg +```python # Dictionary type ## immutable types {K: V} # immutable length, contents cannot be changed @@ -124,7 +124,7 @@ The same is true for other collection types. ... ``` -``` erg +```python # Record type ## immutable types {x = Int; y = Str} # content cannot be changed @@ -137,7 +137,7 @@ The same is true for other collection types. 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 +```python # Sieve type ## Enums {1, 2, 3} # one of 1, 2, 3, cannot be changed diff --git a/doc/EN/syntax/type/19_bound.md b/doc/EN/syntax/type/19_bound.md index 90411ac4..c3365d95 100644 --- a/doc/EN/syntax/type/19_bound.md +++ b/doc/EN/syntax/type/19_bound.md @@ -9,7 +9,7 @@ Guards are written after the return type. You can specify the condition that the variable satisfies with an expression (predicate expression) that returns `Bool`. Only [value objects](./08_value.md) and operators can be used. Compile-time functions may be supported in future versions. -``` erg +```python f a: [T; N] | T, N, N > 5 = ... g a: [T; N | N > 5] | T, N = ... Odd = {I: Int | I % 2 == 1} diff --git a/doc/EN/syntax/type/advanced/GADTs.md b/doc/EN/syntax/type/advanced/GADTs.md index ee5da587..4d6cc616 100644 --- a/doc/EN/syntax/type/advanced/GADTs.md +++ b/doc/EN/syntax/type/advanced/GADTs.md @@ -2,7 +2,7 @@ Erg can create Generalized Algebraic Data Types (GADTs) by classifying Or types. -``` erg +```python Nil T = Class(Impl := Phantom T) Cons T = Class {head = T; rest = List T}, Impl := Unpack List T: Type = Class(Nil T or Cons T) @@ -20,7 +20,7 @@ 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 +```python i = List.nil() _: List Int = cons 1, i ``` @@ -28,7 +28,7 @@ _: List Int = cons 1, i The `List T` defined here is GADTs, but it's a naive implementation and doesn't show the true value of GADTs. For example, the `.head` method above will throw a runtime error if the body is empty, but this check can be done at compile time. -``` erg +```python List: (Type, {"Empty", "Nonempty"}) -> Type List T, "Empty" = Class(Impl := Phantom T) List T, "Nonempty" = Class {head = T; rest = List(T, _)}, Impl := Unpack @@ -46,7 +46,7 @@ print! nil().head() # TypeError An example of GADTs that is often explained on the street is a list that can judge whether the contents are empty or not by type as above. Erg can be further refined to define a list with length. -``` erg +```python List: (Type, Nat) -> Type List T, 0 = Class(Impl := Phantom T) List T, N = Class {head = T; rest = List(T, N-1)}, Impl := Unpack diff --git a/doc/EN/syntax/type/advanced/_rank2type.md b/doc/EN/syntax/type/advanced/_rank2type.md index 11b4afcd..c46fc43b 100644 --- a/doc/EN/syntax/type/advanced/_rank2type.md +++ b/doc/EN/syntax/type/advanced/_rank2type.md @@ -6,7 +6,7 @@ Erg allows you to define functions that accept various types such as `id|T|(x: T So, can we define a function that accepts polycorrelations? For example, a function like this (note that this definition is erroneous): -``` erg +```python # I want tuple_map(i -> i * 2, (1, "a")) == (2, "aa") tuple_map|T|(f: T -> T, tup: (Int, Str)): (Int, Str) = (f(tup.0), f(tup.1)) ``` @@ -15,7 +15,7 @@ Note that `1` and `"a"` have different types, so the anonymous function is not m 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 +```python arr = [1, 2, 3] arr.map i -> i + 1 ``` @@ -25,7 +25,7 @@ arr.map i -> i + 1 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 +```python # tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) tuple_map f: (|T: Type| T -> T), tup: (Int, Str) = (f(tup.0), f(tup.1)) assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa") @@ -34,7 +34,7 @@ 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 +```python id x = x id: |T: Type| T -> T ``` @@ -43,7 +43,7 @@ A universal type has special rules for association with the function type constr Think about this in terms of simple one-argument functions. -``` erg +```python f1: (T -> T) -> Int | T # a function that takes any function and returns an Int f2: (|T: Type| T -> T) -> Int # Function that receives polycorrelation and returns Int f3: Int -> (|T: Type| T -> T) # A function that takes an Int and returns a closed universal function @@ -52,7 +52,7 @@ 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 +```python # id: |T: Type| T -> T id x = x # same type as `f1` @@ -67,7 +67,7 @@ take_i_and_return_arbit_f|T: Type|(_: Int): (T -> T) = id After applying it, you will notice the difference. -``` erg +```python _ = take_univq_f_and_return_i(x -> x, 1) # OK _ = take_univq_f_and_return_i(x: Int -> x, 1) #NG _ = take_univq_f_and_return_i(x: Str -> x, 1) # NG @@ -90,7 +90,7 @@ But the types of functions like `f2` are clearly different from normal types, an 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 +```python # K is a polynomial kind such as Option R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0) ``` @@ -99,7 +99,7 @@ Next, types with first-order universal quantification, such as `|T| T -> T`, or 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 +```python R1 = (|...| R0) or (R0 -> R1) or K(R1) or R0 R2 = (|...| R1) or (R1 -> R2) or K(R2) or R1 ... @@ -108,7 +108,7 @@ Rn = (|...| Rn-1) or (Rn-1 -> Rn) or K(Rn) or Rn-1 Let's look at some examples. -``` erg +```python (|T: Type| T -> T) -> (|U: Type| U -> U) => R1 -> R1 => R1 -> R2 @@ -122,7 +122,7 @@ Option(|T: Type| T -> T) By definition, `tuple_map` is a rank-2 type. -``` erg +```python tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) => (R1, R0) -> R0 @@ -133,7 +133,7 @@ tuple_map: 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 +```python # this is a rank-3 type function # |X, Y: Type|((|T: Type| T -> T), (X, Y)) -> (X, Y) generic_tuple_map|X, Y: Type| f: (|T: Type| T -> T), tup: (X, Y) = (f(tup.0), f(tup.1)) diff --git a/doc/EN/syntax/type/advanced/default_param.md b/doc/EN/syntax/type/advanced/default_param.md index d18a9e02..d7bf81ab 100644 --- a/doc/EN/syntax/type/advanced/default_param.md +++ b/doc/EN/syntax/type/advanced/default_param.md @@ -2,7 +2,7 @@ First, let's look at an example of using default arguments. -``` erg +```python f: (Int, Int, z := Int) -> Int f(x, y, z := 0) = x + y + z @@ -19,7 +19,7 @@ assert fold(g, [1, 2, 3]) == 8 Arguments after `:=` are default arguments. The subtyping rules are as follows. -``` erg +```python ((X, y := Y) -> Z) <: (X -> Z) ((X, y := Y, ...) -> Z) <: ((X, ...) -> Z) ``` diff --git a/doc/EN/syntax/type/advanced/keyword_param.md b/doc/EN/syntax/type/advanced/keyword_param.md index 45db64bc..789fbe7e 100644 --- a/doc/EN/syntax/type/advanced/keyword_param.md +++ b/doc/EN/syntax/type/advanced/keyword_param.md @@ -1,13 +1,13 @@ # Function type with keyword arguments -``` erg +```python h(f) = f(y: 1, x: 2) h: |T: Type|((y: Int, x: Int) -> T) -> T ``` The subtyping rules for functions with keyword arguments are as follows. -``` erg +```python ((x: T, y: U) -> V) <: ((T, U) -> V) # x, y are arbitrary keyword parameters ((y: U, x: T) -> V) <: ((x: T, y: U) -> V) ((x: T, y: U) -> V) <: ((y: U, x: T) -> V) @@ -18,7 +18,7 @@ But you can't do both at the same time. That is, you cannot cast `(x: T, y: U) -> V` to `(U, T) -> V`. Note that keyword arguments are attached only to top-level tuples, and not to arrays or nested tuples. -``` erg +```python Valid: [T, U] -> V Invalid: [x: T, y: U] -> V Valid: (x: T, ys: (U,)) -> V diff --git a/doc/EN/syntax/type/advanced/kind.md b/doc/EN/syntax/type/advanced/kind.md index 64cd1f35..a8a9fd77 100644 --- a/doc/EN/syntax/type/advanced/kind.md +++ b/doc/EN/syntax/type/advanced/kind.md @@ -9,7 +9,7 @@ Note that `->` itself, which is an anonymous function operator, can also be seen Also note that a kind that is not an atomic kind is not a type. Just as `-1` is a number but `-` is not, `Option Int` is a type but `Option` is not. `Option` etc. are sometimes called type constructors. -``` erg +```python assert not Option in Type assert Option in Type -> Type ``` @@ -17,7 +17,7 @@ assert Option in Type -> Type So code like the following will result in an error: In Erg, methods can only be defined in atomic kinds, and the name `self` cannot be used anywhere other than the first argument of a method. -``` erg +```python #K is an unary kind K: Type -> Type K T = Class... @@ -32,7 +32,7 @@ Examples of binary or higher kinds are `{T: U}`(: `(Type, Type) -> Type`), `(T, There is also a zero-term kind `() -> Type`. This is sometimes equated with an atomic kind in type theory, but is distinguished in Erg. An example is `Class`. -``` erg +```python Nil = Class() ``` @@ -40,7 +40,7 @@ Nil = Class() There is also a partial type relation, or rather a partial kind relation, between multinomial kinds. -``` erg +```python K T = ... L = Inherit K L<: K @@ -48,7 +48,7 @@ L<: K That is, for any `T`, if `L T <: K T`, then `L <: K`, and vice versa. -``` erg +```python ∀T. L T <: K T <=> L <: K ``` @@ -56,7 +56,7 @@ That is, for any `T`, if `L T <: K T`, then `L <: K`, and vice versa. There is also a higher-order kind. This is a kind of the same concept as a higher-order function, a kind that receives a kind itself. `(Type -> Type) -> Type` is a higher kind. Let's define an object that belongs to a higher kind. -``` erg +```python IntContainerOf K: Type -> Type = K Int assert IntContainerOf Option == Option Int assert IntContainerOf Result == Result Int @@ -69,26 +69,26 @@ The bound variables of a polynomial kind are usually denoted as K, L, ..., where In type theory, there is the concept of a record. This is almost the same as the Erg record [2](#2). -``` erg +```python # This is a record, and it corresponds to what is called a record in type theory {x = 1; y = 2} ``` When all record values ​​were types, it was a kind of type called a record type. -``` erg +```python assert {x = 1; y = 2} in {x = Int; y = Int} ``` A record type types a record. A good guesser might have thought that there should be a "record kind" to type the record type. Actually it exists. -``` erg +```python log Typeof {x = Int; y = Int} # {{x = Int; y = Int}} ``` A type like `{{x = Int; y = Int}}` is a record kind. This is not a special notation. It is simply an enumeration type that has only `{x = Int; y = Int}` as an element. -``` erg +```python Point = {x = Int; y = Int} Pointy = {Point} ``` @@ -96,7 +96,7 @@ Pointy = {Point} An important property of record kind is that if `T: |T|` and `U <: T` then `U: |T|`. This is also evident from the fact that enums are actually syntactic sugar for sieve types. -``` erg +```python # {c} == {X: T | X == c} for normal objects, but # Equality may not be defined for types, so |T| == {X | X <: T} {Point} == {P | P <: Point} @@ -105,7 +105,7 @@ This is also evident from the fact that enums are actually syntactic sugar for s `U <: T` in type constraints is actually syntactic sugar for `U: |T|`. A kind that is a set of such types is commonly called a set kind. Setkind also appears in the Iterator pattern. -``` erg +```python Iterable T = Trait { .Iterator = {Iterator} .iter = Self(T).() -> Self.Iterator T @@ -114,7 +114,7 @@ Iterable T = Trait { ## Type inference for polynomial kinds -``` erg +```python Container K: Type -> Type, T: Type = Patch K(T, T) Container (K). f self = ... diff --git a/doc/EN/syntax/type/advanced/marker_trait.md b/doc/EN/syntax/type/advanced/marker_trait.md index 17b8326b..bbf90ad4 100644 --- a/doc/EN/syntax/type/advanced/marker_trait.md +++ b/doc/EN/syntax/type/advanced/marker_trait.md @@ -6,15 +6,15 @@ It seems meaningless without the required attribute, but since the information t All marker traits are subsumed by the `Marker` trait. `Light` provided as standard is a kind of marker trait. -``` erg +```python Light = Subsume Marker ``` -``` erg +```python Person = Class {.name = Str; .age = Nat} and Light ``` -``` erg +```python M = Subsume Marker MarkedInt = Inherit Int, Impl := M @@ -26,6 +26,6 @@ assert i in M Marker classes can also be excluded with the `Excluding` argument. -``` erg +```python NInt = Inherit MarkedInt, Impl := N, Excluding: M ``` \ No newline at end of file diff --git a/doc/EN/syntax/type/advanced/special.md b/doc/EN/syntax/type/advanced/special.md index 8fa6825b..800e37bb 100644 --- a/doc/EN/syntax/type/advanced/special.md +++ b/doc/EN/syntax/type/advanced/special.md @@ -2,7 +2,7 @@ `Self` represents its own type. You can just use it as an alias, but note that the meaning changes in derived types (refers to the own type). -``` erg +```python @Inheritable C = Class() C. @@ -16,7 +16,7 @@ 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 +```python @Inheritable C = Class() @@ -33,7 +33,7 @@ classof D. new_c() # C `Self` and `Super` can be used as type variables in structured types and traits. This refers to classes that are subtypes of that type. That is, `Self` in type `T` means `Self <: T`. -``` erg +```python Add R = Trait { .AddO = Type .`_+_`: Self, R -> Self.AddO diff --git a/doc/EN/syntax/type/advanced/typeof.md b/doc/EN/syntax/type/advanced/typeof.md index ab16bb84..b320d7a0 100644 --- a/doc/EN/syntax/type/advanced/typeof.md +++ b/doc/EN/syntax/type/advanced/typeof.md @@ -2,7 +2,7 @@ `Typeof` is a function that can peek into Erg's type inference system, and its behavior is complex. -``` erg +```python assert Typeof(1) == {I: Int | I == 1} i: 1..3 or 5..10 = ... assert Typeof(i) == {I: Int | (I >= 1 and I <= 3) or (I >= 5 and I <= 10)} @@ -21,7 +21,7 @@ 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 +```python i: Int = ... assert Typeof(i) == {__valueclass_tag__ = Phantom Int} s: Str = ... @@ -38,7 +38,7 @@ Erg infers object types as sieve types as much as possible, and when that is not 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 +```python C = Class {i = Int} assert Structure(C) == {i = Int} D = Inherit C diff --git a/doc/EN/syntax/type/advanced/variance.md b/doc/EN/syntax/type/advanced/variance.md index 6a7bec59..eaa300cf 100644 --- a/doc/EN/syntax/type/advanced/variance.md +++ b/doc/EN/syntax/type/advanced/variance.md @@ -49,7 +49,7 @@ This is because `SharedCell! T!` is a shared reference. See [shared references]( A universal type variable can specify its upper and lower bounds. -``` erg +```python |A <: T| K(A) |B :> T| K(B) ``` @@ -59,14 +59,14 @@ In this case, `T` is also called the upper type for `A` and the lower type for ` Mutation specifications can also overlap. -``` erg +```python # U U} ``` Here is an example of code that uses a variable specification. -``` erg +```python show|S <: Show| s: S = log s Nil T = Class(Impl = Phantom T) @@ -90,7 +90,7 @@ For example, `List Int` can be upcast to `List Object` and `Obj -> Obj` can be u Now let's consider what happens if we omit the variable specification of the method. -``` erg +```python ... List T = Class {head = T; rest = Cons T} List(T). @@ -109,7 +109,7 @@ Similarly, a cast from `List T` to `List U` is possible subject to the constrain Now let's see what happens if we allow this upcast. Let's invert the denaturation designation. -``` erg +```python ... List T = Class {head = T; rest = Cons T} List(T). @@ -128,7 +128,7 @@ Mutations of user-defined types are immutable by default. However, you can also 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 +```python K T = Class(...) assert not K(Str) <= K(Object) assert not K(Str) >= K(Object) diff --git a/doc/EN/syntax/type/advanced/widening.md b/doc/EN/syntax/type/advanced/widening.md index 7d0a9b47..d29e27cf 100644 --- a/doc/EN/syntax/type/advanced/widening.md +++ b/doc/EN/syntax/type/advanced/widening.md @@ -2,7 +2,7 @@ For example, define the polycorrelation coefficient as follows. -``` erg +```python ids|T|(x: T, y: T) = x, y ``` @@ -10,7 +10,7 @@ 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 +```python assert ids(1, 2) == (1, 2) assert ids(1, 2.0) == (1.0, 2.0) ids(1, "a") #TypeError @@ -18,7 +18,7 @@ ids(1, "a") #TypeError Now, what about types that have different derived types? -``` erg +```python i: Int or Str j: Int or NoneType ids(i, j) # ? @@ -26,7 +26,7 @@ ids(i, j) # ? Before explaining this, we have to focus on the fact that Erg's type system doesn't actually look at (runtime) classes. -``` erg +```python 1: {__valueclass_tag__ = Phantom Int} 2: {__valueclass_tag__ = Phantom Int} 2.0: {__valueclass_tag__ = Phantom Ratio} @@ -43,7 +43,7 @@ Of course, the class of an object of type `Int` is defined as `Int`, but in this 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 +```python i: Int or Str j: Int or NoneType ids(i, j) # TypeError: types of i and j not matched @@ -67,7 +67,7 @@ ids(i, j) # OK Erg defaults to an error if return types do not match. -``` erg +```python parse_to_int s: Str = if not s.is_numeric(): do parse_to_int::return error("not numeric") @@ -81,7 +81,7 @@ parse_to_int s: Str = In order to solve this, it is necessary to explicitly specify the return type as Or type. -``` erg +```python parse_to_int(s: Str): Int or Error = if not s.is_numeric(): do parse_to_int::return error("not numeric") diff --git a/doc/EN/tools/pack.md b/doc/EN/tools/pack.md index ae02aa88..d2e2f561 100644 --- a/doc/EN/tools/pack.md +++ b/doc/EN/tools/pack.md @@ -34,7 +34,7 @@ Also see [package_system.md](../syntax/33_package_system.md) for the Erg package `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 +```python name = "example" # package name author = "John Smith" # package author name version="0.1.0" diff --git a/doc/EN/tools/test.md b/doc/EN/tools/test.md index 6e449ac8..5844047c 100644 --- a/doc/EN/tools/test.md +++ b/doc/EN/tools/test.md @@ -7,7 +7,7 @@ The erg command has a subcommand called test, which supports test implementation 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 +```python # tests/test1.er {add; ...} = import "foo" @@ -24,12 +24,12 @@ In Erg, `#` and `#[` are comment lines, but `##` and `#[[` are doc comments, and 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 +```python VMs =... ... #[[ execute commands. - ``` erg + ```python # VM in standard configuration {vm1; ...} = import "tests/mock" diff --git a/doc/JA/dev_guide/build_features.md b/doc/JA/dev_guide/build_features.md index f437b1c8..c78abb3e 100644 --- a/doc/JA/dev_guide/build_features.md +++ b/doc/JA/dev_guide/build_features.md @@ -12,8 +12,10 @@ Erg内部のオプション、ヘルプ(help, copyright, licenseなど)、エラ ## simplified_chinese -システム言語を簡体字中国語にする。 +システム言語を簡体字中国語に設定します。 +Erg 内部オプション、ヘルプ (ヘルプ、著作権、ライセンスなど)、エラーは簡体字中国語で表示されます。 ## traditional_chinese -システム言語を繁体字中国語にする。 +システム言語を繁体字中国語に設定します。 +Erg 内部オプション、ヘルプ (ヘルプ、著作権、ライセンスなど)、エラーは繁体字中国語で表示されます。 \ 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 ffa4c4d9..8bdc85db 100644 --- a/doc/zh_CN/API/modules/external/alstruct.md +++ b/doc/zh_CN/API/modules/external/alstruct.md @@ -6,7 +6,7 @@ ## 二进制运算 -``` erg +```python BinOp Op: Kind 2 = Subsume Op(Self, Self.ReturnTypeOf Op), Additional: { .ReturnTypeof = TraitType -> Type } @@ -20,7 +20,7 @@ assert Nat.ReturnTypeof(Div) == Positive Ratio ## 半群(一个二元运算的代数系统) -``` erg +```python SemiGroup Op: Kind 2 = Op(Self, Self) IntIsSemiGroupAdd = Patch Int, Impl=SemiGroupAdd @@ -30,7 +30,7 @@ Int <: SemiGroup Add ## 函子 -``` erg +```python # * Identity law: x.map(id) == x # * Composition law: x.map(f).map(g) == x.map(f.then g) Functor = Trait { @@ -40,7 +40,7 @@ Functor = Trait { ## 应用 -``` erg +```python # * Identity law: x.app(X.pure(id)) == x Applicative = Subsume Functor, Additional: { .pure|T: Type| = T -> Self T @@ -50,7 +50,7 @@ Applicative = Subsume Functor, Additional: { ## 单子(交互式命令行工具以及面向对象的脚本技术) -``` erg +```python Monad = Subsume Applicative, Additional: { .bind|T, U: Type| = (Self(T), T -> Self U) -> Self U } diff --git a/doc/zh_CN/API/modules/repl.md b/doc/zh_CN/API/modules/repl.md index 413b2235..0395afcb 100644 --- a/doc/zh_CN/API/modules/repl.md +++ b/doc/zh_CN/API/modules/repl.md @@ -18,7 +18,7 @@ 在给定参数和返回值的情况下推断函数。 -``` erg +```python 1.guess((1,), 2) # [1, 2].guess((3, 4), [1, 2, 3, 4]) # ``` \ No newline at end of file diff --git a/doc/zh_CN/API/modules/unit.md b/doc/zh_CN/API/modules/unit.md index d3536e38..d2172508 100644 --- a/doc/zh_CN/API/modules/unit.md +++ b/doc/zh_CN/API/modules/unit.md @@ -6,7 +6,7 @@ Erg 数值类型包括 `Nat`、`Int`、`Ratio` 等。但是,这些类型没有 这样的错误确实会发生,并且会导致诸如[由于错误的单位系统导致火星探测器丢失](http://www.sydrose.com/case100/287/)之类的严重错误。 如果您希望代码在进行数值计算时更加健壮,您应该使用此模块。 -``` erg +```python {*} = import "unit" x = 6m # 相当于 `x = Meter.new(6)` @@ -32,7 +32,7 @@ print! x + 2s # 类型错误: `+`(Meter, Sec) 未实现 例如`UnitDiv(Unit1, Sec)`,因为频率单位赫兹(hertz)被定义为振动周期(秒)的倒数。 如果要将此类型视为有意义的类型(例如添加专用方法),则应创建 [patch](./../../syntax/type/07_patch.md)。 -``` erg +```python Hertz = Patch UnitDiv(Unit1, Sec) SquareMeter = Patch UnitMul(Meter, Meter) ``` diff --git a/doc/zh_CN/API/modules/unsound.md b/doc/zh_CN/API/modules/unsound.md index 999b8fc4..adfe6ccf 100644 --- a/doc/zh_CN/API/modules/unsound.md +++ b/doc/zh_CN/API/modules/unsound.md @@ -6,7 +6,7 @@ 执行“不安全”过程。 就像 Rust 一样,`Unsafe` API 不能直接调用,而是作为高阶函数传递给这个过程。 -``` erg +```python unsound = import "unsound" i = unsound. unsafe! do!: diff --git a/doc/zh_CN/API/procs.md b/doc/zh_CN/API/procs.md index 914c8846..14831c0c 100644 --- a/doc/zh_CN/API/procs.md +++ b/doc/zh_CN/API/procs.md @@ -2,7 +2,7 @@ ## print! -``` erg +```python 打印!(x)->无类型 ``` @@ -10,7 +10,7 @@ ## 调试&排除; -``` erg +```python 调试!(x,类型=信息)-> NoneType ``` diff --git a/doc/zh_CN/API/special.md b/doc/zh_CN/API/special.md index 8f90dd40..48d999e0 100644 --- a/doc/zh_CN/API/special.md +++ b/doc/zh_CN/API/special.md @@ -34,7 +34,7 @@ print! L # `=` 运算符的返回值为“未定义”。 函数中的多个赋值和 `=` 会导致语法错误。 -``` erg +```python i = j = 1 # SyntaxError: 不允许多次赋值 print!(x=1) # SyntaxError: cannot use `=` in function arguments # 提示:您的意思是关键字参数(`x: 1`)吗? @@ -152,7 +152,7 @@ assert True.then(choice) == 1 展开嵌套集合。它也可以用于模式匹配。 -``` erg +```python [x, ...y] = [1, 2, 3] assert x == 1 and y == [2, 3] assert [x, ...y] == [1, 2, 3] diff --git a/doc/zh_CN/compiler/inference.md b/doc/zh_CN/compiler/inference.md index 936bfd56..290680b3 100644 --- a/doc/zh_CN/compiler/inference.md +++ b/doc/zh_CN/compiler/inference.md @@ -4,7 +4,7 @@ 显示了下面使用的符号 -``` erg +```python Free type variables (type, unbound): ?T, ?U, ... Free-type variables (values, unbound): ?a, ?b, ... type environment (Γ): { x: T, ... } @@ -14,7 +14,7 @@ Type argument evaluation environment (E): { e -> e', ... } 我们以下面的代码为例: -``` erg +```python v = ![] v.push! 1 print! v @@ -100,7 +100,7 @@ pub enum Type { 现在,当在使用它的类型推断(例如,`id 1`,`id True`)中使用获得的类型方案(例如`'T -> 'T(id's type scheme)`)时,必须释放generalize。这种逆变换称为 __instantiation__。我们将调用操作`inst`。 -``` erg +```python gen ?T = 'T inst 'T = ?T (?T ∉ Γ) ``` @@ -114,7 +114,7 @@ inst 'T = ?T (?T ∉ Γ) 类型替换规则 `{?T --> X}` 意味着将 `?T` 和 `X` 重写为相同类型。 此操作称为 __Unification__。 `X` 也可以是类型变量。 [单独部分](./unification.md) 中描述了详细的统一算法。 我们将统一操作表示为“统一”。 -``` erg +```python unify(?T, Int) == Ok(()) # ?T == (Int) # S为类型分配规则,T为适用类型 @@ -132,7 +132,7 @@ subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y 因为实际参数的类型必须是形式参数类型的子类型。 如果参数类型是类型变量,我们需要更新子类型关系以满足它。 -``` erg +```python # 如果形参类型是T f(x: T): T = ... @@ -147,7 +147,7 @@ f(a) 为了看到层级管理的必要性,我们首先确认没有层级管理的类型推断会导致问题。 推断以下匿名函数的类型。 -``` erg +```python x -> y = x y @@ -156,7 +156,7 @@ x -> 首先,Erg 分配类型变量如下: y 的类型也是未知的,但暂时未分配。 -``` erg +```python x(: ?T) -> y = x y @@ -165,7 +165,7 @@ x(: ?T) -> 首先要确定的是右值 x 的类型。 右值是一种“用途”,因此我们将其具体化。 但是 x 的类型 `?T` 已经被实例化了,因为它是一个自由变量。 Yo`?T` 成为右值的类型。 -``` erg +```python x(: ?T) -> y = x (: inst ?T) y @@ -173,13 +173,13 @@ x(: ?T) -> 注册为左值 y 的类型时进行泛化。 然而,正如我们稍后将看到的,这种概括是不完善的,并且会产生错误的结果。 -``` erg +```python x(: ?T) -> y(:gen?T) = x(:?T) y ``` -``` erg +```python x(: ?T) -> y(: 'T) = x y @@ -187,7 +187,7 @@ x(: ?T) -> y 的类型现在是一个量化类型变量“T”。 在下一行中,立即使用 `y`。 具体的。 -``` erg +```python x: ?T -> y(: 'T) = x y(: inst 'T) @@ -195,7 +195,7 @@ x: ?T -> 请注意,实例化必须创建一个与任何已经存在的(自由)类型变量不同的(自由)类型变量(概括类似)。 这样的类型变量称为新类型变量。 -``` erg +```python x: ?T -> y = x y(: ?U) @@ -207,7 +207,7 @@ x: ?T -> 所以我们用下面的符号来介绍类型变量的层次。 级别表示为自然数。 -``` erg +```python # 普通类型变量 ?T<1>, ?T<2>, ... # 具有子类型约束的类型变量 @@ -216,7 +216,7 @@ x: ?T -> 让我们再尝试一次: -``` erg +```python x -> y = x y @@ -225,7 +225,7 @@ x -> 首先,按如下方式分配一个 leveled 类型变量: toplevel 级别为 1。随着范围的加深,级别增加。 函数参数属于内部范围,因此它们比函数本身高一级。 -``` erg +```python # level 1 x (: ?T<2>) -> # level 2 @@ -235,7 +235,7 @@ x (: ?T<2>) -> 首先,实例化右值`x`。和以前一样,没有任何改变。 -``` erg +```python x (: ?T<2>) -> y = x (: inst ?T<2>) y @@ -245,11 +245,11 @@ x (: ?T<2>) -> 早些时候,这里的结果很奇怪,所以我们将改变泛化算法。 如果类型变量的级别小于或等于当前范围的级别,则泛化使其保持不变。 -``` erg +```python gen ?T = if n <= current_level, then= ?T, else= 'T ``` -``` erg +```python x (: ?T<2>) -> # current_level = 2 y(: gen ?T<2>) = x(: ?T<2>) @@ -258,7 +258,7 @@ x (: ?T<2>) -> That is, the lvalue `y` has type `?T<2>`. -``` erg +```python x (: ?T<2>) -> # ↓ 不包括 y(: ?T<2>) = x @@ -267,13 +267,13 @@ x (: ?T<2>) -> y 的类型现在是一个未绑定的类型变量 `?T<2>`。 具体如下几行:但是 `y` 的类型没有被概括,所以什么也没有发生 -``` erg +```python x (: ?T<2>) -> y(: ?T<2>) = x y (: inst ?T<2>) ``` -``` erg +```python x (: ?T<2>) -> y = x y (: ?T<2>) @@ -283,7 +283,7 @@ x (: ?T<2>) -> 让我们看另一个例子。 这是更一般的情况,具有函数/运算符应用程序和前向引用。 -``` erg +```python fx, y = id(x) + y id x = x @@ -296,7 +296,7 @@ f10,1 在这种情况下,在 `f` 之前插入一个假设的 `id` 声明,并为其分配一个自由类型变量。 注意此时类型变量的级别是`current_level`。 这是为了避免在其他函数中泛化。 -``` erg +```python id: ?T<1> -> ?U<1> f x (: ?V<2>), y (: ?W<2>) = id(x) (: subst_call_ret([inst ?V<2>], inst ?T<1> -> ?U<1>)) + y @@ -308,7 +308,7 @@ f x (: ?V<2>), y (: ?W<2>) = 类型变量之间的半统一有点不同。 不同级别的类型变量不得相互施加类型约束。 -``` erg +```python # BAD f x (: ?V<2>), y (: ?W<2>) = # ?V<2>(<: ?T<1>) @@ -320,24 +320,24 @@ f x (: ?V<2>), y (: ?W<2>) = 对于 Type 类型变量,执行正常统一而不是半统一。 也就是说,统一到下层。 -``` erg +```python # OK f x (: ?V<2>), y (: ?W<2>) = # ?V<2> --> ?T<1> id(x) (: ?U<1>) + y (: ?W<2>) ``` -``` erg +```python f x (: ?T<1>), y (: ?W<2>) = (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], inst |'L <: Add('R)| ('L, 'R) -> 'L .AddO) ``` -``` erg +```python f x (: ?T<1>), y (: ?W<2>) = (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], (?L(<: Add(?R<2>))<2>, ?R<2 >) -> ?L<2>.AddO) ``` -``` erg +```python id: ?T<1> -> ?U<1> f x (: ?T<1>), y (: ?W<2>) = # ?U<1>(<: Add(?W<2>)) # Inherit the constraints of ?L @@ -346,26 +346,26 @@ f x (: ?T<1>), y (: ?W<2>) = (id(x) + x) (: ?U<1>.AddO) ``` -``` erg +```python # current_level = 1 f(x, y) (: gen ?T<1>, gen ?W<2> -> gen ?U<1>.AddO) = id(x) + x ``` -``` erg +```python id: ?T<1> -> ?U<1> f(x, y) (: |'W: Type| (?T<1>, 'W) -> gen ?U<1>(<: Add(?W<2>)).AddO) = id(x) + x ``` -``` erg +```python f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) = id(x) + x ``` 定义时,提高层次,使其可以泛化。 -``` erg +```python # ?T<1 -> 2> # ?U<1 -> 2> id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>) @@ -373,7 +373,7 @@ id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>) 如果已经分配了返回类型,则与结果类型统一(`?U<2> --> ?T<2>`)。 -``` erg +```python # ?U<2> --> ?T<2> f(x, y) (: |'W: Type| (?T<2>, 'W) -> ?T<2>(<: Add(?W<2>)).AddO) = id(x) + x @@ -385,13 +385,13 @@ id(x) (: gen ?T<2> -> gen ?T<2>) = x (: ?T<2>) 依赖于它的类型变量也将是一个 Type 类型变量。 广义类型变量对于每个函数都是独立的。 -``` erg +```python f(x, y) (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = id(x) + x id(x) (: |'T: Type| 'T -> gen 'T) = x ``` -``` erg +```python f x, y (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = id(x) + y id(x) (: 'T -> 'T) = x @@ -399,13 +399,13 @@ id(x) (: 'T -> 'T) = x f(10, 1) (: subst_call_ret([inst {10}, inst {1}], inst |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T .AddO) ``` -``` erg +```python f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<1>) -> ? T<1>.AddO)) ``` 类型变量绑定到具有实现的最小类型 -``` erg +```python # ?T(:> {10} <: Add(?W<1>))<1> # ?W(:> {1})<1> # ?W(:> {1})<1> <: ?T<1> (:> {10}, <: Add(?W(:> {1})<1>)) @@ -421,7 +421,7 @@ f(10, 1) (: ({10}, {1}) -> Nat) 整个程序的结果类型是: -``` erg +```python f|W: Type, T <: Add(W)|(x: T, y: W): T.AddO = id(x) + y id|T: Type|(x: T): T = x @@ -430,7 +430,7 @@ f(10, 1): Nat 我还重印了原始的、未明确键入的程序。 -``` erg +```python fx, y = id(x) + y id x = x diff --git a/doc/zh_CN/compiler/refinement_subtyping.md b/doc/zh_CN/compiler/refinement_subtyping.md index 5a47803f..3bacb6bb 100644 --- a/doc/zh_CN/compiler/refinement_subtyping.md +++ b/doc/zh_CN/compiler/refinement_subtyping.md @@ -1,6 +1,6 @@ # 筛子类型 -``` erg +```python {I: Int | I >= 0} {S: StrWithLen N | N >= 1} {T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0} diff --git a/doc/zh_CN/compiler/trait_method_resolving.md b/doc/zh_CN/compiler/trait_method_resolving.md index 0f17e37b..8dd3a966 100644 --- a/doc/zh_CN/compiler/trait_method_resolving.md +++ b/doc/zh_CN/compiler/trait_method_resolving.md @@ -3,7 +3,7 @@ `Nat` 是零个或多个`Int`,`Int` 的子类型。 `Nat` 在 Python 类层次结构中不存在。 我想知道 Erg 是如何解决这个补丁方法的? -``` erg +```python 1.times do: log "hello world" ``` @@ -27,7 +27,7 @@ Erg 在 `Int` 的 MRO 中有 `Int`、`Object`。它来自 Python(Python 中的 Erg 编译器有一个补丁类型的哈希图,其中包含所有提供的方法及其实现。 每次定义新类型时都会更新此表。 -``` erg +```python provided_method_table = { ... "foo": [Foo], @@ -58,7 +58,7 @@ provided_method_table = { 如果两者之间没有包含关系,则会发生编译错误(这是一种安全措施,防止违背程序员的意图执行方法)。 要消除错误,您需要明确指定补丁。 -``` erg +```python o.method(x) -> P.method(o, x) ``` @@ -66,20 +66,20 @@ o.method(x) -> P.method(o, x) 像这样定义一个补丁: -``` erg +```python FnType T: Type = Patch T -> T FnType.type = T ``` 在 `FnType` 补丁下可以使用如下代码。 我想知道这将如何解决。 -``` erg +```python assert (Int -> Int).type == Int ``` 首先,`FnType(T)` 以下列格式注册到`provided_method_table` 中。 -``` erg +```python provided_method_table = { ... "type": [FnType(T)], @@ -90,6 +90,6 @@ provided_method_table = { `FnType(T)` 检查匹配类型。 在这种情况下,`FnType(T)` 补丁类型是 `Type -> Type`。 这匹配 `Int -> Int`。 如果合适,进行单态化和替换(取 `T -> T` 和 `Int -> Int`、`{T => Int}` 的差异)。 -``` erg +```python assert FnType(Int).type == Int ``` \ No newline at end of file diff --git a/doc/zh_CN/compiler/transpile.md b/doc/zh_CN/compiler/transpile.md index 5145268e..396c72d7 100644 --- a/doc/zh_CN/compiler/transpile.md +++ b/doc/zh_CN/compiler/transpile.md @@ -11,7 +11,7 @@ 对于 namedtuple,请参阅 [此处](https://docs.python.jp/3/library/collections.html#collections.namedtuple)。 有一个类似的函数,dataclass,但是由于 `__eq__` 和 `__hash__` 的自动实现,dataclass 的性能略有下降。 -``` erg +```python Employee = Class {.name = Str; .id = Int} employee = Employee.new({.name = "John Smith"; .id = 100}) @@ -43,7 +43,7 @@ assert employee.name == 'John Smith' 如果没有发生命名空间冲突,它只会被破坏和扩展。 `x::y` 等名称在字节码中使用,不能与 Python 代码关联,但如果强制表示,则会如下所示。 -``` erg +```python x = y = 1 y+1 @@ -56,7 +56,7 @@ x = x::y + 1 万一发生冲突,定义和使用只能在内部引用的函数。 -``` erg +```python x = y = 1 y+1 @@ -75,7 +75,7 @@ x = _() 它对公共变量没有任何作用,因为它是 Python 的默认值。 私有变量由 mangling 处理。 -``` erg +```python x=1 y = x = 2 diff --git a/doc/zh_CN/dev_guide/build_features.md b/doc/zh_CN/dev_guide/build_features.md index d31e879d..5a4aebdc 100644 --- a/doc/zh_CN/dev_guide/build_features.md +++ b/doc/zh_CN/dev_guide/build_features.md @@ -1,19 +1,21 @@ -# `erg` build features +# `erg` 构建功能 -## debug +## 调试 -Enter debug mode. As a result, the behavior inside Erg is sequentially displayed in the log. -Independent of Rust's `debug_assertions` flag. +进入调试模式。结果,Erg 内部的行为顺序显示在日志中。 +独立于 Rust 的 `debug_assertions` 标志。 ## japanese -Set the system language to Japanese. -Erg internal options, help (help, copyright, license, etc.) and error display are guaranteed to be Japanese. +将系统语言设置为日语。 +Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为日语。 ## simplified_chinese -Set the system language to Simplified Chinese. +将系统语言设置为简体中文。 +Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为简体中文。 ## traditional_chinese -Set the system language to Traditional Chinese. \ No newline at end of file +将系统语言设置为繁体中文。 +Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为繁体中文。 \ 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 26f717a9..b5a1babc 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)。 +* 如果文档内容过时,按照【此方法】更新(https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)。 --- -1 See this for how to write footnotes. [↩](#f1) \ No newline at end of file +1 参见这里了解如何编写脚注。[↩](#f1) \ No newline at end of file diff --git a/doc/zh_CN/dev_guide/env.md b/doc/zh_CN/dev_guide/env.md index ff6ab791..9f6d9264 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) +* Rust(与 rustup 一起安装) - * ver >= 1.63.0 - * 2021 edition + * 版本 >= 1.63.0 + * 2021年版 -* [pre-commit](https://pre-commit.com/) +* [预提交](https://pre-commit.com/) -* Python3 interpreter +* Python3 解释器 -## Recommendation +## 推荐 -* 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 +* 编辑器:Visual Studio Code +* VSCode 扩展:Rust-analyzer、GitLens、Git Graph、GitHub Pull Requests and Issues、Markdown All in One、markdownlint +* 操作系统:Windows 10/11 | Ubuntu 20.04/22.04 | Mac OS Monterey +* 其他:pyenv、模具 \ No newline at end of file diff --git a/doc/zh_CN/dev_guide/faq_syntax.md b/doc/zh_CN/dev_guide/faq_syntax.md index 5eab9ded..1e54da09 100644 --- a/doc/zh_CN/dev_guide/faq_syntax.md +++ b/doc/zh_CN/dev_guide/faq_syntax.md @@ -14,7 +14,7 @@ id[T: Type] [t]: [T] = t y = id[Int] # 这是一个功能吗? # <>版 id {t: T} = t -y = (id 1) # これはタプル? +y = (id 1) # 这是一个元组吗? # {}版 id{T: Type} {t: T} = t y = id{Int} # 这是一个功能吗? @@ -79,10 +79,10 @@ Python 的库中有一些类设计为继承,如果完全取消继承,这些 ```python -# If T is a subtype of a structural trait... +# 如果 T 是结构特征的子类型... # f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T f|T| x, y: T = x + y - x -# T is a subtype of a nominal trait +# T 是名义特征的子类型 # g: |T <: Add() and Sub()| (T, T) -> T g|T| x, y: T = x + y - x ``` diff --git a/doc/zh_CN/dev_guide/rust_code_guideline.md b/doc/zh_CN/dev_guide/rust_code_guideline.md index 17be981f..49db6c84 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 @@ -# Guidelines for Rust code +# Rust 代码指南 -## local rules +## 本地规则 -* Use `log!` for output for debugging (use `println!` etc. for output processing that is also necessary for release). -* Unused or internal variables/方法 (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. +* 使用 `log!` 进行调试输出(使用 `println!` 等进行输出处理,这也是发布所必需的)。 +* 未使用或内部变量/方法(私有且仅用于特定功能)必须以 `_` 为前缀。如果要避免与保留字冲突,请在末尾添加一个`_`。 -## Recommended code +## 推荐代码 -* 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`. +* 定义和使用特定领域的枚举而不是数字枚举或布尔值。 +* 将访问修饰符保持在最低限度。即使在发布时也要优先使用 `pub(mod)` 或 `pub(crate)`。 +* 将 for 表达式中的可迭代对象显式转换为迭代器(`for i in x.iter()` 而不是 `for i in x`)。 +* 懒惰的评价。例如,如果 `default` 不是文字,请使用 `unwrap_or_else` 而不是 `unwrap_or`。 -## Code not encouraged +## 不鼓励使用代码 -* 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. +* 大量使用返回类型重载。特别是使用大量非显而易见的 `.into` 的代码。这是因为类型推断结果可能违反直觉。在这种情况下,建议使用 `from` 代替。 +* 大量使用 `Deref`。这有效地提出了与继承相同的问题。 -## Code that makes decisions based on context +## 根据上下文做出决策的代码 -* Define unused helper 方法. -* Use `unwrap` and `clone` a lot. In some cases there is nothing better than doing so. \ No newline at end of file +* 定义未使用的辅助方法。 +* 大量使用 `unwrap` 和 `clone`。在某些情况下,没有什么比这样做更好的了。 \ No newline at end of file diff --git a/doc/zh_CN/dev_guide/terms.md b/doc/zh_CN/dev_guide/terms.md index 01ba474a..2b6d9fc0 100644 --- a/doc/zh_CN/dev_guide/terms.md +++ b/doc/zh_CN/dev_guide/terms.md @@ -1,11 +1,10 @@ -# 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/# comment) @@ -235,9 +234,9 @@ Or the mutating operator. ### [Assertion] -To check (typically at runtime) whether a condition is true in code. This is done using the `assert` function, etc. +检查(通常在运行时)代码中的条件是否为真。 这是使用 `assert` 函数等来完成的。 -``` erg +```python sum = !0 for! 0..10, i => sum.add!i @@ -245,595 +244,595 @@ for! 0..10, i => assert sum == 55 ``` -### Value Object +### 值对象 -In Erg, equivalent to base object. It can be evaluated at compile time and has a trivial comparison method. +在 Erg 中,相当于基础对象。 它可以在编译时进行评估,并且具有简单的比较方法。 -### [Attachment patch](../syntax/29_decorator.md#attach) +### [附件补丁](../syntax/29_decorator.md#attach) -A patch that gives the trait a standard implementation. +为特征提供标准实现的补丁。 -### Ad hoc polymorphism -> [No overloading](../syntax/type/overloading.md) +### Ad hoc 多态性 -> [无重载](../syntax/type/overloading.md) -Polymorphism with so-called overloading. +具有所谓重载的多态性。 -### Attribute -> [attribute] +### 属性-> [属性] -The `y` part in the `x.y` identifier. +`x.y` 标识符中的 `y` 部分。 ### Arity -How many operands the operator takes. +运算符需要多少个操作数。 -### [Dependent type](../syntax/type/dependent_type.md) +### [依赖类型](../syntax/type/dependent_type.md) -A type whose argument is a value (idiomatically, not a type). +参数是值的类型(习惯上说,不是类型)。 -### immutable -> [immutable] +### 不可变 -> [不可变] -Indicates that the target will not change. -Variables in other languages ​​are also immutable/mutable, but in Erg all variables are immutable. +表示目标不会改变。 +其他语言中的变量也是不可变/可变的,但是在 Erg 中所有的变量都是不可变的。 -### arguments -> [arguments] +### 参数 -> [参数] -### instance +### 实例 -An object created by a class. An element of class type. +由类创建的对象。 类类型的元素。 -### [instant block](../syntax/00_basic.md#expression separator) +### [即时封锁](../syntax/00_basic.md#expression separator) -``` erg +```python x = y = f(a) z = g(b,c) y+z ``` -### index +### 指数 -of the form `x[i]`, or the `i` part thereof. We call `x` an Indexable object. +形式为“x[i]”,或其“i”部分。我们称 `x` 为 Indexable 对象。 -### [indent](../syntax/00_basic.md#indent) +### [缩进](../syntax/00_basic.md#indent) -Align text to the right by moving toward spaces. Indentation. -Ergs represent blocks by indentation. This is called the offside rule. +通过向空格移动将文本向右对齐。缩进。 +Ergs 通过缩进表示块。这称为越位规则。 -### Aliases +### 别名 -Alias. +别名。 -### error +### 错误 -Abnormal conditions defined in the specification. +规范中定义的异常情况。 -* [Error handling] +* [错误处理] -### [operator](../syntax/06_operator.md) +### [运算符](../syntax/06_operator.md) -An object that applies an operation to its operands. or a symbol denoting that object. +将操作应用于其操作数的对象。或表示该对象的符号。 -* [operator binding strength] +* [运算符绑定强度] -### Override +### 覆盖 -Overriding superclass 方法 in subclasses. -In Erg you have to add `Override` decorator when overriding. +在子类中覆盖超类方法。 +在 Erg 中,您必须在覆盖时添加 `Override` 装饰器。 -### [No overloading](../syntax/type/overloading.md) +### [不重载](../syntax/type/overloading.md) -### Offside rule -> [indent](../syntax/00_basic.md#indent) +### 越位规则-> [缩进](../syntax/00_basic.md#indent) -### [object] +### [目的] -* Object-orientation +* 面向对象 -### operand -> [operand](../syntax/06_operator.md) +### 操作数 -> [操作数](../syntax/06_operator.md) -### operator -> [operator](../syntax/06_operator.md) +### 运算符 -> [运算符](../syntax/06_operator.md) -## Ka line +##嘉线 -### [kind](../syntax/type/advanced/kind.md) +### [种类](../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. +对术语进行分组的对象。 -* [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] +* [类型规格] +* [类型擦除](../syntax/type/advanced/erasure.md) +* [类型推断] +* [类型注释](../syntax/type/conv_type.md) +* [类型参数] +* [类型添加](../syntax/type/advanced/erasure.md) +* [类型变量](../syntax/type/type_variable.md) +* [类型约束] -### [Guard] +### 监视 -### Encapsulation +### 封装 -Hiding implementation details. +隐藏实现细节。 -### [variable] +### [多变的] -Must not be immutable. +不能是一成不变的。 -* [mutable object] -* [variable] -* [variable reference] -* [variable array] -* [variable arguments] +* [可变对象] +* [多变的] +* [变量参考] +* [变量数组] +* [可变参数] -### [function](../syntax/04_function.md) +### [函数](../syntax/04_function.md) -A subroutine with no side effects. +没有副作用的子程序。 -* [Functional programming](../syntax/23_scope.md#Avoiding mutable stateFunctional programming) +* [函数式编程](../syntax/23_scope.md#避免可变状态函数式编程) -### base type +### 基本类型 -### nominative +###主格 -Distinguish by name rather than by symmetrical structure. +通过名称而不是对称结构来区分。 -* [named type] -> [class](../syntax/type/04_class.md) -* [Annunciation] -* [nominal subtype](../syntax/type/05_nst_vs_sst.md) +* [命名类型] -> [类](../syntax/type/04_class.md) +* [报喜] +* [名义子类型](../syntax/type/05_nst_vs_sst.md) -### capture -> [closure] +### 捕获-> [关闭] -### [covariant] +### [协变] -In Erg, if `T <: U` then `K(T) <: K(U)` then `K` is said to be covariant. +在 Erg 中,如果 `T <: U` 则 `K(T) <: K(U)` 则称 `K` 是协变的。 -### [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. +`k` 以函数调用 `f(k: v)` 的形式出现。您可以通过形式参数名称而不是按顺序指定实际参数。 -### empty set -> [{}] +### 空集 -> [{}] -### section +### 部分 -* [Interval type](../syntax/type/11_interval.md) -* interval operator +* [区间类型](../syntax/type/11_interval.md) +* 区间运算符 -### Embedded +### 嵌入式 -Erg standard APIs not implemented in .er files. +Erg 标准 API 未在 .er 文件中实现。 -### [class](../syntax/type/04_class.md) +### [类](../syntax/type/04_class.md) -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. +具有继承功能的结构/抽象数据类型。在 Erg 中,它是一种实现命名子类型化和覆盖的类型。 +在 Erg 中,模块是模块对象负责,类型是类型对象,而其他语言可能负责模块和类型。 -### [Closure] +### [关闭] -### [global variables] +### [全局变量] -### [Clone] +### [克隆] -### [inheritance](../syntax/type/07_inheritance.md) +### [继承](../syntax/type/07_inheritance.md) -To define a class that is a 父类et 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 +### 高楼层 -* [higher-order kind](../syntax/type/advanced/kind.md) -* higher order type -* Higher-order functions +* [高阶种类](../syntax/type/advanced/kind.md) +* 高阶类型 +* 高阶函数 -### [public variables] +### [公共变量] -### [structural subtype] +### [结构子类型] -### ~~back reference~~ -> [back reference] +### ~~后向引用~~ -> [后向引用] -### [copy] +### [复制] -### comment +### 评论 -### [Collection](../syntax/10_array.md) +### [集合](../syntax/10_array.md) -### Colon -> [:] +### 冒号 -> [:] -### [constructor](../syntax/type/04_class.md) +### [构造函数](../syntax/type/04_class.md) -### container +### 容器 -### Compiler +### 编译器 -### [compile-time computation](../syntax/04_function.md#compile-time function) +### [编译时计算](../syntax/04_function.md#compile-time function) -### comma -> [,] +### 逗号 -> [,] -## sa line +## sa线 -### recursion +### 递归 -Refer to yourself. +参考自己。 -* recursive -* [Recursive function](../syntax/04_function.md#Recursive function) +* 递归 +* [递归函数](../syntax/04_function.md#递归函数) -### subscript -> [index] +### 下标 -> [索引] -### [subtyping polymorphism](../syntax/type/overloading.md) +### [子类型多态性](../syntax/type/overloading.md) -Polymorphism with subtyping. Subtyping corresponds to set containment in types. +具有子类型的多态性。子类型对应于类型中的集合包含。 -### Subroutine +### 子程序 -An object that modularizes processing. A generic term for functions, procedures, and 方法 in Erg. +模块化处理的对象。 Erg 中函数、过程和方法的通用术语。 -### [reference](../syntax/18_memory_management.md#borrowed) +### [参考](../syntax/18_memory_management.md#borrowed) -* reference object -* [Reference counting (RC)](../syntax/18_memory_management.md#memory management) -* Reference equality -> [side effect](../syntax/07_side_effect.md) +* 参考对象 +* [引用计数 (RC)](../syntax/18_memory_management.md#memory management) +* 引用相等 -> [副作用](../syntax/07_side_effect.md) -### [identifier](../syntax/02_variable.md/# assignment) +### [标识符](../syntax/02_variable.md/# 赋值) -### signature +### 签名 -* type signature +* 类型签名 ### [dict](../syntax/11_dict.md) -### [natural number] -> [Nat] +### 自然数 -> Nat -### Generics -> [Generic] +### 泛型 -> 泛型 -### Generator +### 发电机 -### [projective type] +### 投影类型 -### borrow -> [reference](../syntax/18_memory_management.md#borrowed) +### 借用-> [参考](../syntax/18_memory_management.md#borrowed) -### [shadowing](../syntax/02_name.md# variables) +### [阴影](../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] +### set -> set -In Erg, it means a Set object. +在 Erg 中,它表示一个 Set 对象。 -### 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. +对象唯一性的概念。 +如果您拥有对象的所有权,则可以使用 mutable 参考它。 -### Boolean -> [Bool] +### 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] +* 符号化 -### [script](../syntax/00_basic.md# script) +### [脚本](../syntax/00_basic.md# 脚本) -A file containing an Erg program. +包含 Erg 程序的文件。 -### Scope +### 范围 -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. +变量管理单元。外部作用域不能引用内部作用域中存在的变量。 +当范围退出时,引用计数为 0 的对象将被释放。 -### spread operator -> [expansion assignment] +### 扩展运算符 -> expansion assignment -### [slice](../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]`. +表示数组子序列的对象,以 `x[a..b]` 的形式生成。 -### control characters +### 控制字符 -### [Integer] -> [Int] +### 整数 -> Int -A set of natural numbers plus negative numbers. +一组自然数加上负数。 -### [set](../syntax/12_set.md) +### [设置](../syntax/12_set.md) -### Semicolon -> [;] +### 分号 -> ; -### [Declaration](../syntax/03_declaration.md) +### [声明](../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 +* 通用类型 -> [多态类型](../syntax/type/quantified.md) + * 封闭式通用 + * 打开通用 +* 通用函数 -> 多相关函数 +* 通用量化 -### prefix operator +### 前缀运算符 -Operator `∘` applied in the form `∘x`. +运算符 `∘` 以 `∘x` 的形式应用。 -### mutual recursion +### 相互递归 -### subscript -> [index] +### 下标 -> index -### [attributes] +### 属性 -* [attribute subtype] +* 属性子类型 -## Ta line +## 塔线 -### [algebra](../syntax/02_name.md) +### [代数](../syntax/02_name.md) -* [algebraic type](../syntax/type/13_algebraic.md) -* algebraic data types +* [代数类型](../syntax/type/13_algebraic.md) +* 代数数据类型 -### [assignment](../syntax/02_variable.md/#assignment) +### [赋值](../syntax/02_variable.md/#assignment) -### Multiple +### 多 -* [Multiple inheritance](../syntax/type/07_inheritance.md/#Prohibition of multiple inheritance) -* Multiple assignment -* Overload -> [No overloading] +* [多重继承](../syntax/type/07_inheritance.md/#禁止多重继承) +* 多重赋值 +* 重载 -> [不重载] -### Polymorphism +### 多态性 -* [polymorphic type](../syntax/type/quantified.md) -* polycorrelation coefficient +* [多态类型](../syntax/type/quantified.md) +* 多相关系数 -### polymorphism -> [polymorphism] +### 多态性 -> [多态性] -### duck typing +### 鸭子类型 -### [tuple](../syntax/11_tuple.md) +### [元组](../syntax/11_tuple.md) -### Single-phase +### 单相 -* Single phase -* Single-phase type -* Single correlation coefficient +* 单相 +* 单相型 +* 单相关系数 -### [Lazy initialization] +### [延迟初始化] -### Extraction Assignment +### 提取分配 -### Abstract syntax tree -> [AST] +### 抽象语法树 -> [AST] -### Infix operator +### 中缀运算符 -The operator `∘` applied in the form `x∘y`. +运算符 `∘` 以 `x∘y` 的形式应用。 -### [constant](../syntax/02_name.md/#constant) +### [常数](../syntax/02_name.md/#constant) -Immutable, compile-time evaluable algebra. +不可变的,编译时可评估的代数。 -* [constant type](../syntax/type/advanced/const.md) -* [constant expression](../syntax/type/advanced/const.md) +* [常量类型](../syntax/type/advanced/const.md) +* [常量表达式](../syntax/type/advanced/const.md) -### [definition] +### 定义 -Allocating an object corresponding to a variable. +分配与变量对应的对象。 -### Provided Attributes +### 提供的属性 -Attributes available as API. Especially attributes auto-implemented by traits. +可作为 API 使用的属性。特别是由特征自动实现的属性。 -### [Apply] +### 申请 -To pass an argument to a function object and get the evaluation result. +将参数传递给函数对象并获取评估结果。 -### [decorator](../syntax/29_decorator.md) +### [装饰器](../syntax/29_decorator.md) -``` erg +``` python @deco f x = ... ``` -syntactic sugar, or `deco`. Roughly equal to `_f x = ...; f = deco _f`. `deco` itself is just a higher-order subroutine. +语法糖,或“装饰”。大致等于`_f x = ...; f = 装饰 _f`。 `deco` 本身只是一个高阶子程序。 -### destructor +### 析构函数 -Method called when the object is destroyed. +对象被销毁时调用的方法。 -### procedure -> [procedure](../syntax/08_procedure.md) +### 程序 -> [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. +读取和写入可变状态的子程序。 +有时会说程序的执行结果可以根据调用过程的顺序而改变,但如果我们谈论交换性,这是不正确的。 +例如,作为函数子类型的运算符通常不可交换。 -### [default arguments](../syntax/04_function.md/#default arguments default-parameters) +### [默认参数](../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] +* 扩展运算符 +* 扩展分配 -### [special format](../syntax/../API/special.md) +### [特殊格式](../syntax/../API/special.md) -An object that cannot be passed as an actual argument. +不能作为实际参数传递的对象。 -### anonymous function -> [anonymous function](../syntax/20_lambda.md) +### 匿名函数 -> [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] +### 点运算符 (`.`) -> attribute reference -### Top +### 顶部 -* Top type -> [Structural Object] -* Top class -> [Object] +* 顶部类型 -> [结构对象] +* 顶级 -> [对象] -### [trait](../syntax/type/03_trait.md) +### [特征](../syntax/type/03_trait.md) ## na line -### [Comprehension](../syntax/27_comprehension.md) +### [理解](../syntax/27_comprehension.md) -### ~~Infix operator~~ -> [Infix operator] +### ~~中缀运算符~~ -> 中缀运算符 -### [namespace] +### 命名空间 -## is a line +## 是一行 -### [Array](../syntax/10_array.md) +### [数组](../syntax/10_array.md) -### [derived type](../syntax/type/variances.md/# user-defined type variations) +### [派生类型](../syntax/type/variances.md/# 用户定义的类型变体) -### [pattern (match)](../syntax/26_pattern_matching.md) +### [模式(匹配)](../syntax/26_pattern_matching.md) -### [package](../syntax/33_package_system.md) +### [包](../syntax/33_package_system.md) ### hashmap -> [dict](../syntax/11_dict.md) -### [patch](../syntax/type/07_patch.md) +### [补丁](../syntax/type/07_patch.md) -### public variables -> [public variables](../syntax/19_visibility.md) +### 公共变量-> [public variables](../syntax/19_visibility.md) -### parameter -> [argument](../syntax/04_function.md) +### 参数 -> [argument](../syntax/04_function.md) -### [Parametric Polymorphism](../syntax/type/overloading.md) +### [参数多态](../syntax/type/overloading.md) -### [contravariant](../syntax/type/advanced/variance.md) +### [逆变](../syntax/type/advanced/variance.md) -### Compare +### 相比 -* [comparison operator] -* [comparable type] +* 比较运算符 +* 可比类型 -### [private variable](../syntax/19_visibility.md) +### [私有变量](../syntax/19_visibility.md) -### standard +### 标准 -* standard output -* standard input -* standard library +* 标准输出 +* 标准输入 +* 标准库 -### [side effects](../syntax/07_side_effect.md) +### [副作用](../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] +### 布尔代数-> Bool -### [procedure](../syntax/08_procedure.md) +### [程序](../syntax/08_procedure.md) -### [arguments](../syntax/04_function.md) +### [参数](../syntax/04_function.md) -### Partial Typing -> [Subtyping] +### 部分类型 -> Subtyping -### [immutable] +### [不可变] -In Erg, an object should never change its contents. +在 Erg 中,一个对象永远不应该改变它的内容。 -* [immutable object] -* [immutable type] -* [immutable reference] +* [不可变对象] +* [不可变类型] +* [不可变引用] -### [sieve type](../syntax/type/12_refinement.md) +### [筛子类型](../syntax/type/12_refinement.md) -### [block] +### [堵塞] -### Destructuring assignment +### 解构赋值 -### [variable](../syntax/02_variable.md) +### [变量](../syntax/02_variable.md) -### bottom +### 底部 -* bottom type -> [{}] -* Bottom class -> [Never] +* 底部类型 -> [{}] +* 底层 -> [从不] -### [Polymorphism] +### [多态性] ## ma line -### ~~ prefix operator ~~ -> prefix operator +### ~~ 前缀运算符 ~~ -> 前缀运算符 -### [marker type](../syntax/type/advanced/marker_trait.md) +### [标记类型](../syntax/type/advanced/marker_trait.md) -### [anonymous function](../syntax/21_lambda.md) +### [匿名函数](../syntax/21_lambda.md) -### mutable -> [mutable] +### 可变 -> [可变] -### [move] +### [移动] ### 方法 -### Metacharacters +### 元字符 -### [module](../syntax/24_module.md) +### [模块](../syntax/24_module.md) -### [String] -> [Str] +### [字符串] -> [字符串] -* [String interpolation](../syntax/01_literal.md/#Str literal) +* [字符串插值](../syntax/01_literal.md/#Str 字面量) -### Return value +### 返回值 -## or line +## 或行 -### [phantom type](../syntax/type/advanced/phantom.md) +### [幻像类型](../syntax/type/advanced/phantom.md) -### Request Attributes +### 请求属性 -### [element] +### [元素] -### [call] +### [称呼] -## Ra line +## 拉线 -### [Library] +### [图书馆] -### lambda expression -> [anonymous function](../syntax/20_lambda.md) +### lambda 表达式 -> [匿名函数](../syntax/20_lambda.md) -### rank +### 排名 -* [rank2 polymorphism](../syntax/type/advanced/rank2type.md) +* [rank2 多态性](../syntax/type/advanced/rank2type.md) -### [literal](../syntax/01_literal.md) +### [文字](../syntax/01_literal.md) -* [literal identifier](../syntax/18_naming_rule.md/#literal identifier) +* [文字标识符](../syntax/18_naming_rule.md/#literal identifier) -### [quantified](../syntax/type/quantified.md) +### [量化](../syntax/type/quantified.md) -### [Layout](../syntax/type/mut.md) +### [布局](../syntax/type/mut.md) -### [enum](../syntax/type/10_enum.md) +### [枚举](../syntax/type/10_enum.md) -### [record](../syntax/12_record.md) +### [记录](../syntax/12_record.md) -* [record type] -* Record Polymorphism -> [Column Polymorphism] +* [记录类型] +* 记录多态 -> Column Polymorphism -### [column polymorphism] +### 列多态 -### [local variables](../syntax/19_visibility.md) +### [局部变量](../syntax/19_visibility.md) -## line +## 线 -### Wildcard \ No newline at end of file +### 通配符 \ 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 02806bf1..0aa3be7d 100644 --- a/doc/zh_CN/dev_guide/unify_terms.md +++ b/doc/zh_CN/dev_guide/unify_terms.md @@ -1,56 +1,56 @@ -# Unification of terminology +# 术语统一 -## Accessibility, Visibility +## 可访问性,可见性 -Use Visibility. +使用可见性。 -## Type bound, Type constraint +## 类型绑定,类型约束 -A list of predicate expressions given to quantified and refinement types. Use type bounds. +给定量化和细化类型的谓词表达式列表。使用类型边界。 -## subroutines, routines, subprograms +## 子程序、例程、子程序 -Use subroutines. +使用子程序。 -## Referentially transparent/not, with/without side effects +## 引用透明/不透明,有/没有副作用 -Use with/without side effects. +使用有/无副作用。 -## identifiers, algebra, variables, names, symbols +## 标识符、代数、变量、名称、符号 -In its original meaning, +就其本义而言, -* 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). +* 符号:在源代码中实心编写的字符(符号、控制字符等除外),不是字符串对象(未包含在“”中)。符号在 Ruby、Lisp 等中作为原始类型存在,但在 Erg 中它们不被视为对象。 +* 标识符:(并且可以)引用某个对象的符号,而不是保留字。例如,在 Python 中 class 和 def 不能用作标识符。由于 Erg 没有保留字,所以除了某些符号外,所有符号都可以用作标识符。 +* 名称:与标识符的含义几乎相同。它有时与 Erg 中的代数同义使用。 +* 代数名称:相当于尔格中的标识符。在 C 中,函数名称是标识符,而不是代数名称。 “代数”指的是语言特性本身,它允许您使用 `=`(变量赋值运算符)或 `=`(常量赋值运算符)来分配对象。 -``` erg -algebraic name <: (name == identifier) ​​<: symbol -variable + constant == algebra +```python +代数名称<:(名称==标识符)​​<:符号 +变量 + 常数 == 代数 ``` -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. +然而,应该称为“代数”的东西,往往被称为“变量”。这就是数学术语的效果。 +值内容可以改变的变量是可变变量,值内容不改变的变量是不可变变量。 +请注意,常量始终是不可变的。 -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". . +Erg 中不使用代数名称和名称,使用统一标识符。 +但是,一般来说,具有 `v = 1` 的 `v` 称为“变量 v”,而具有 `C = 1` 的 `C` 称为“常量 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 +## 应用程序,调用 -Giving arguments to a subroutine object and getting a result. -Use Call. This is because Application has a usage of "application software". +为子例程对象提供参数并获得结果。 +使用呼叫。这是因为Application有“应用软件”的用法。 -## Array, List +## 数组列表 -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. +使用数组。 Erg 数组(通常)在内存中是连续的。 +List 是指所谓的链表,或者说列表作为 Python 数据类型。 -## lambda functions, lambda expressions, anonymous functions +## lambda 函数、lambda 表达式、匿名函数 -Unify with anonymous functions. In English, Lambda can be used to shorten the number of characters, but the official name is Anonymous function. +与匿名函数统一。在英文中,可以使用 Lambda 来缩短字符数,但正式名称是 Anonymous function。 \ No newline at end of file diff --git a/doc/zh_CN/migration_from_py.md b/doc/zh_CN/migration_from_py.md index af3a0e43..5e8565e7 100644 --- a/doc/zh_CN/migration_from_py.md +++ b/doc/zh_CN/migration_from_py.md @@ -9,7 +9,7 @@ s: str i: int = int(s) ``` -``` erg +```python s: Str res: Result(Int, IntParseError) = s. parse Int i: Int = res.unwrap() @@ -18,7 +18,7 @@ f: Result(Float, FloatParseError) = s. parse Float You can also use the `try_from` method. -``` erg +```python s: Str i: Int = Int.try_from(s).unwrap() f: Float = Float.try_from(s).unwrap() diff --git a/doc/zh_CN/syntax/06_operator.md b/doc/zh_CN/syntax/06_operator.md index abe81367..087f6862 100644 --- a/doc/zh_CN/syntax/06_operator.md +++ b/doc/zh_CN/syntax/06_operator.md @@ -5,7 +5,7 @@ Operators are symbols that represent operations. Operands are things to the (lef Operators are a kind of function, and thus are themselves first-class objects that can be bound to variables. When binding, it is necessary to enclose it with ``. For `+` (and `-`), there are both unary and binary operators, so `_+_`(binary operation)/`+_`(unary operation ) must be specified. -``` erg +```python add = `+` # SyntaxError: specify `_+_` or `+_` add=`_+_` assert f(1, 2) == 3 @@ -17,7 +17,7 @@ assert g(1, 2) == 2 Some fundamental operators, called special forms, cannot be bound. -``` erg +```python def = `=` # SyntaxError: cannot bind `=` operator, this is a special form # NG: def x, 1 function = `->` # SyntaxError: cannot bind `->` operator, this is a special form diff --git a/doc/zh_CN/syntax/14_set.md b/doc/zh_CN/syntax/14_set.md index 324b4969..3bace4d6 100644 --- a/doc/zh_CN/syntax/14_set.md +++ b/doc/zh_CN/syntax/14_set.md @@ -2,7 +2,7 @@ A set represents a collection, which is structurally a duplicate, unordered array. -``` erg +```python assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3} assert {1, 2} == {1, 1, 2} # duplicates are automatically removed assert {1, 2} == {2, 1} @@ -10,7 +10,7 @@ assert {1, 2} == {2, 1} Sets can perform set operations. -``` erg +```python assert 1 in {1, 2, 3} assert not 1 in {} assert {1} or {2} == {1, 2} @@ -20,7 +20,7 @@ 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 +```python s: {Int or Str} = {"a", 1, "b", -1} ``` @@ -28,7 +28,7 @@ s: {Int or Str} = {"a", 1, "b", -1} Sets can also be treated as types. Such types are called __Enum types__. -``` erg +```python i: {1, 2, 3} = 1 assert i in {1, 2, 3} ``` @@ -36,7 +36,7 @@ assert i in {1, 2, 3} Elements of the set are directly elements of the type. Note that the sets themselves are different. -``` erg +```python mut_set = {1, 2, 3}.into {Int; !3} mut_set.insert!(4) ``` diff --git a/doc/zh_CN/syntax/18_ownership.md b/doc/zh_CN/syntax/18_ownership.md index 1f1e0232..6c724767 100644 --- a/doc/zh_CN/syntax/18_ownership.md +++ b/doc/zh_CN/syntax/18_ownership.md @@ -9,7 +9,7 @@ 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 +```python v = [1, 2, 3].into [Int; !3] push! vec, x = @@ -34,7 +34,7 @@ The duplicated object is exactly the same as the original, but independent of ea 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 +```python capitalize s: Str!= s. capitalize!() s @@ -51,7 +51,7 @@ This is called freezing. Freezing is used, for example, when creating an iterato 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 +```python # Compute the sum of the values ​​produced by the iterator sum|T <: Add + HasUnit| i: Iterator T = ... @@ -69,7 +69,7 @@ y # y can still be touched Borrowing is cheaper than duplicating or freezing. Borrowing can be done in the following simple cases: -``` erg +```python peek_str ref(s: Str!) = log s @@ -80,7 +80,7 @@ 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 +```python steal_str ref(s: Str!) = # Since the log function only borrows the arguments, it can be sub-leased log s @@ -89,7 +89,7 @@ steal_str ref(s: Str!) = # hint: use `clone` method ``` -``` erg +```python steal_str ref(s: Str!) = # This is no good either (= consumes the right side) x = s # OwnershipError: cannot consume a borrowed value diff --git a/doc/zh_CN/syntax/19_visibility.md b/doc/zh_CN/syntax/19_visibility.md index 315ab8e4..3e89fe62 100644 --- a/doc/zh_CN/syntax/19_visibility.md +++ b/doc/zh_CN/syntax/19_visibility.md @@ -4,12 +4,12 @@ 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 +```python # foo.er x = "this is an invisible variable" ``` -``` erg +```python #bar.er foo = import "foo" foo.x # AttributeError: Module 'foo' has no attribute 'x' ('x' is private) @@ -18,12 +18,12 @@ 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 +```python # foo.er .x = "this is a visible variable" ``` -``` erg +```python #bar.er foo = import "foo" assert foo.x == "this is a visible variable" @@ -31,7 +31,7 @@ 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 +```python ::x = "this is an invisible variable" assert ::x == x assert self ::x == ::x @@ -40,7 +40,7 @@ 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 +```python ::x = "this is a private variable" y = x + 1 # exactly module::x @@ -50,7 +50,7 @@ By using `::`, you can distinguish variables with the same name within the scope Specify the scope of the variable you want to refer to on the left. Specify `module` for the top level. If not specified, the innermost variable is referenced as usual. -``` erg +```python ::x = 0 assert x == 0 y = @@ -66,7 +66,7 @@ y = In the anonymous subroutine scope, `self` specifies its own scope. -``` erg +```python x = 0 f = x -> log module::x, self::x @@ -75,7 +75,7 @@ f1# 0 1 `::` is also responsible for accessing private instance attributes. -``` erg +```python x = 0 C = Class {x = Int} C. @@ -89,12 +89,12 @@ C. A class defined in one module can actually define 方法 from an external module. -``` erg +```python # foo.er .Foo = Class() ``` -``` erg +```python #bar.er {Foo; ...} = import "foo" @@ -113,7 +113,7 @@ However, both of those 方法 are only available within that module. Private 方法 defined externally are visible to 方法 of the `Foo` class only within the defining module. Public 方法 are exposed outside the class, but not outside the module. -``` erg +```python # baz.er {Foo; ...} = import "foo" @@ -124,7 +124,7 @@ foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defi Also, 方法 cannot be defined in the type to be re-exported. This is to avoid confusion about 方法 being found or not found depending on the module they are imported from. -``` erg +```python #bar.er {.Foo; ...} = import "foo" @@ -136,7 +136,7 @@ Foo. If you want to do something like this, define a [patch](./type/07_patch.md). -``` erg +```python #bar.er {Foo; ...} = import "foo" @@ -147,7 +147,7 @@ Foo Impl. public self = self::private() ``` -``` erg +```python # baz.er {Foo; ...} = import "foo" {FooImpl; ...} = import "bar" @@ -161,7 +161,7 @@ foo.public() Variable visibility is not limited to complete public/private. You can also publish with restrictions. -``` erg +```python # foo.er .record = { .a = { @@ -179,7 +179,7 @@ _ = .record.a.y # OK _ = .record.a.z # OK ``` -``` erg +```python foo = import "foo" _ = foo.record.a.x # VisibilityError _ = foo.record.a.y # VisibilityError diff --git a/doc/zh_CN/syntax/20_naming_rule.md b/doc/zh_CN/syntax/20_naming_rule.md index e5543f7e..625b4017 100644 --- a/doc/zh_CN/syntax/20_naming_rule.md +++ b/doc/zh_CN/syntax/20_naming_rule.md @@ -2,7 +2,7 @@ If you want to use a variable as a constant expression, make sure it starts with a capital letter. Two or more letters may be lowercase. -``` erg +```python i: Option Type = Int match i: t: Type -> log "type" @@ -12,7 +12,7 @@ match i: Objects with side effects always end with `!`. Procedures and procedural 方法, and mutable types. However, the `Proc` type itself is not mutable. -``` erg +```python # Callable == Func or Proc c: Callable = print! match c: @@ -22,7 +22,7 @@ match c: If you want to expose an attribute to the outside world, define it with `.` at the beginning. If you don't put `.` at the beginning, it will be private. To avoid confusion, they cannot coexist within the same scope. -``` erg +```python o = {x = 1; .x = 2} # SyntaxError: private and public variables with the same name cannot coexist ``` @@ -32,7 +32,7 @@ The above rule can be circumvented by enclosing the string in single quotes ('') A character string enclosed in single quotes like this is called a literal identifier. This is used when calling APIs (FFI) of other languages ​​such as Python. -``` erg +```python bar! = pyimport("foo").'bar' ``` @@ -40,7 +40,7 @@ Identifiers that are also valid in Erg do not need to be enclosed in ''. Furthermore, literal identifiers can contain both symbols and spaces, so strings that cannot normally be used as identifiers can be used as identifiers. -``` erg +```python '∂/∂t' y 'test 1: pass x to y'() ``` diff --git a/doc/zh_CN/syntax/21_lambda.md b/doc/zh_CN/syntax/21_lambda.md index 08415e13..9a534f48 100644 --- a/doc/zh_CN/syntax/21_lambda.md +++ b/doc/zh_CN/syntax/21_lambda.md @@ -2,7 +2,7 @@ Anonymous functions are a syntax for creating function objects on the fly without naming them. -``` erg +```python # `->` is an anonymous function operator # same as `f x, y = x + y` f = (x, y) -> x + y @@ -12,7 +12,7 @@ g = (x, y: Int): Int -> x + y You can omit the `()` if there is only one argument. -``` erg +```python assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4] assert ((i, j) -> [i, j])(1, 2) == [1, 2] ``` @@ -20,14 +20,14 @@ 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 +```python for 0..9, i: Int -> ... ``` In anonymous functions, there is a difference in parsing due to whitespace. -``` erg +```python # In this case, interpreted as `T(() -> Int)` i: T() -> Int # in this case it is interpreted as (U()) -> Int @@ -36,7 +36,7 @@ k: U() -> Int Anonymous functions can be used without arguments. -``` erg +```python # `=>` is an anonymous procedure operator p! = () => print! "`p!` was called" # `() ->`, `() =>` have syntax sugar `do`, `do!` @@ -46,7 +46,7 @@ p!() # `p!` was called No-argument functions can be used for lazy initialization. -``` erg +```python time = import "time" date = import "datetime" now = if! True: @@ -59,7 +59,7 @@ now = if! True: 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 +```python n = (Complex or Ratio or Int).sample!() i = matchn: PI -> PI # if equal to constant PI @@ -71,7 +71,7 @@ i = matchn: Error handling is also generally done using `?` or `match`. -``` erg +```python res: ParseResult Int matchres: i: Int -> i @@ -85,7 +85,7 @@ match res2: ## Anonymous polycorrelation coefficient -``` erg +```python # same as id|T| x: T = x id = |T| x: T -> x ``` diff --git a/doc/zh_CN/syntax/23_closure.md b/doc/zh_CN/syntax/23_closure.md index 52c6c917..06128bf3 100644 --- a/doc/zh_CN/syntax/23_closure.md +++ b/doc/zh_CN/syntax/23_closure.md @@ -2,7 +2,7 @@ Erg subroutines have a feature called a "closure" that captures external variables. -``` erg +```python outer = 1 f x = outer + x assert f(1) == 2 @@ -10,7 +10,7 @@ assert f(1) == 2 As with immutable objects, mutable objects can also be captured. -``` erg +```python sum = !0 for! 1..10, i => sum.add!i @@ -25,7 +25,7 @@ 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 +```python # !!! This code actually gives an error !!! i = !0 f x = i + x @@ -39,7 +39,7 @@ 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 +```python i = !0 immut_i = i.clone().freeze() fx = immut_i + x @@ -50,7 +50,7 @@ assert f 1 == 1 ## avoid mutable state, functional programming -``` erg +```python # Erg sum = !0 for! 1..10, i => @@ -71,7 +71,7 @@ assert sum == 45 However, Erg recommends a simpler notation. Instead of carrying around state using subroutines and mutable objects, use a style of localizing state using functions. This is called functional programming. -``` erg +```python # Functional style sum = (1..10).sum() assert sum == 45 @@ -83,7 +83,7 @@ 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 +```python # start with 0, result will sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i) assert sum == 45 diff --git a/doc/zh_CN/syntax/24_module.md b/doc/zh_CN/syntax/24_module.md index f2309cf0..ac801d3b 100644 --- a/doc/zh_CN/syntax/24_module.md +++ b/doc/zh_CN/syntax/24_module.md @@ -7,7 +7,7 @@ Erg allows you to think of the file itself as a single record. This is called a .i = 1 ``` -``` erg +```python # 定义ining the foo module is almost the same as defining this record foo = {.i = 1} ``` @@ -21,7 +21,7 @@ assert foo.i == 1 Since module types are also record types, deconstruction assignment is possible. -``` erg +```python {sin; cos; ...} = import "math" ``` diff --git a/doc/zh_CN/syntax/25_object_system.md b/doc/zh_CN/syntax/25_object_system.md index 40f0ae5f..05d6ae68 100644 --- a/doc/zh_CN/syntax/25_object_system.md +++ b/doc/zh_CN/syntax/25_object_system.md @@ -15,7 +15,7 @@ All data that can be assigned to a variable. The attributes of the `Object` clas An object generated by a record literal (`{attr = value; ...}`). This object has basic 方法 such as `.clone` and `.__sizeof__`. -``` erg +```python obj = {.x = 1} assert obj.x == 1 @@ -27,7 +27,7 @@ assert obj2.x == 1 and obj2.y == 2 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 +```python # note that there is no `.` in private_attr record = {.public_attr = j; private_attr = 2; .method = self -> self.i + 1} record. public_attr == 2 diff --git a/doc/zh_CN/syntax/26_pattern_matching.md b/doc/zh_CN/syntax/26_pattern_matching.md index 8539689e..c48c07c7 100644 --- a/doc/zh_CN/syntax/26_pattern_matching.md +++ b/doc/zh_CN/syntax/26_pattern_matching.md @@ -4,7 +4,7 @@ ### variable pattern -``` erg +```python # basic assignments i = 1 # with type @@ -28,7 +28,7 @@ a: Array Int, 4 = [0, 1, 2, 3] ### Literal patterns -``` erg +```python # Raise a TypeError if `i` cannot be determined to be 1 at compile time. # omit `_: {1} = i` 1 = i @@ -47,7 +47,7 @@ fibn: Nat = fibn-1 + fibn-2 ### constant pattern -``` erg +```python cond=False match! cond: True => print! "cond is True" @@ -64,7 +64,7 @@ name = match num: ### Sieve pattern -``` erg +```python # these two are the same Array(T, N: {N | N >= 3}) Array(T, N | N >= 3) @@ -75,7 +75,7 @@ f(1, 0) # TypeError: N (2nd parameter) must be 1 or more ### discard (wildcard) pattern -``` erg +```python _ = 1 _: Int = 1 zero_ = 0 @@ -86,7 +86,7 @@ right(_, r) = r It is used in combination with the tuple/array/record pattern described later. -``` erg +```python [i,...j] = [1, 2, 3, 4] assert j == [2, 3, 4] first|T|(fst: T, ...rest: T) = fst @@ -95,7 +95,7 @@ assert first(1, 2, 3) == 1 ### Tuple pattern -``` erg +```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) # If not nested, () can be omitted (1, 2 are treated as (1, 2)) @@ -106,7 +106,7 @@ f(x, y) = ... ### array pattern -``` erg +```python [i, j] = [1, 2] [[k, l], _] = [[1, 2], [3, 4]] @@ -116,7 +116,7 @@ length[_, ...rest] = 1 + lengthrest #### record pattern -``` erg +```python record = {i = 1; j = 2; k = 3} {j; ...} = record # i, k will be freed @@ -133,7 +133,7 @@ f {x: Int; y: Int} = ... ### Data class pattern -``` erg +```python Point = Inherit {x = Int; y = Int} p = Point::{x = 1; y = 2} Point::{x; y} = p @@ -156,7 +156,7 @@ List T. *Actually, it's just an enumeration type -``` erg +```python match x: i: {1, 2} -> "one or two: {i}" _ -> "other" @@ -166,7 +166,7 @@ match x: *Actually, it is just an interval type. -``` erg +```python # 0 < i < 1 i: 0<..<1 = 0.5 # 1 < j <= 2 diff --git a/doc/zh_CN/syntax/27_comprehension.md b/doc/zh_CN/syntax/27_comprehension.md index bd4ea15b..24c903e0 100644 --- a/doc/zh_CN/syntax/27_comprehension.md +++ b/doc/zh_CN/syntax/27_comprehension.md @@ -9,7 +9,7 @@ A guard clause can be omitted, but a bind clause cannot be omitted, and a guard Comprehension example -``` erg +```python # the layout clause is i # bind clause is i <- [0, 1, 2] assert [i | i <- [0, 1, 2]] == [0, 1, 2] @@ -36,7 +36,7 @@ For Haskell list comprehensions, the order of variables makes a difference in th [(i, j) | j <- [3..5], i <- [1..3]] == [(1,3),(2,3),(3,3),(1 ,4),(2,4),(3,4),(1,5),(2,5),(3,5)] ``` -``` erg +```python # Erg assert [(i, j) | i <- 1..<3; j <- 3..<5] == [(i, j) | j <- 3..<5; i <- 1.. <3] ``` @@ -53,7 +53,7 @@ assert [(i, j) for i in range(1, 3) for j in range(3, 5)] == [(i, j) for j in ra Similar to comprehensions are sieve types. A sieve type is a type (enumerated type) created in the form `{Name: Type | Predicate}`. In the case of the sieve type, only one Name can be specified and the layout cannot be specified (however, multiple values ​​can be handled if it is a tuple type), and the Predicate can be calculated at compile time, that is, only a constant expression can be specified. -``` erg +```python Nat = {I: Int | I >= 0} # If the predicate expression is only and, it can be replaced with ; # Nat2D = {(I, J): (Int, Int) | I >= 0; J >= 0} diff --git a/doc/zh_CN/syntax/28_spread_syntax.md b/doc/zh_CN/syntax/28_spread_syntax.md index aed87510..5f8f760a 100644 --- a/doc/zh_CN/syntax/28_spread_syntax.md +++ b/doc/zh_CN/syntax/28_spread_syntax.md @@ -2,7 +2,7 @@ In a decomposing assignment, putting `...` in front of a variable expands all remaining elements into that variable. This is called expansion assignment. -``` erg +```python [x,...y] = [1, 2, 3] assert x == 1 assert y == [2, 3] @@ -16,7 +16,7 @@ assert y == (2, 3) 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 +```python {sin; cos; tan; ..} = import "math" ``` @@ -24,14 +24,14 @@ After that, you can use `sin, cos, tan` locally. You can do the same with records. -``` erg +```python record = {x = 1; y = 2} {x; y; ...} = record ``` If you want to expand all, use `{*} = record`. It is `open` in OCaml. -``` erg +```python record = {x = 1; y = 2} {*} = records assert x == 1 and y == 2 diff --git a/doc/zh_CN/syntax/29_decorator.md b/doc/zh_CN/syntax/29_decorator.md index a5ed389c..243fe7f0 100644 --- a/doc/zh_CN/syntax/29_decorator.md +++ b/doc/zh_CN/syntax/29_decorator.md @@ -3,7 +3,7 @@ Decorators are used to add or demonstrate a particular state or behavior to a type or function. The syntax of the decorator is as follows. -``` erg +```python @deco X=... ``` @@ -12,7 +12,7 @@ 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 +```python X=... X = deco(X) ``` @@ -20,7 +20,7 @@ X = deco(X) Erg doesn't allow reassignment of variables, so code like the one above won't work. For simple variables it's the same as `X = deco(...)`, but for instant blocks and subroutines you can't do that, so you need a decorator. -``` erg +```python @deco f x = y = ... @@ -50,7 +50,7 @@ Used when overriding attributes. By default, Erg will throw an error if you try Indicates that the argument trait is implemented. -``` erg +```python Add = Trait { .`_+_` = Self.(Self) -> Self } @@ -71,7 +71,7 @@ C. Specifies the attachment patch that comes with the trait by default. This allows you to reproduce the same behavior as Rust traits. -``` erg +```python # foo.er Add R = Trait { .AddO = Type @@ -88,7 +88,7 @@ AddForOdd.AddO = Even This will automatically apply the attachment patch when importing traits from other modules. -``` erg +```python # Originally, IntIsBinAdd and OddIsBinAdd should be imported at the same time, but if it's an attachment patch, you can omit it {BinAdd; ...} = import "foo" @@ -98,7 +98,7 @@ assert Odd.AddO == Even Internally it's just attached using the trait's `.attach` method. Conflicts can be removed with the trait's `.detach` method. -``` erg +```python @Attach X T = Trait... assert X in T. attaches diff --git a/doc/zh_CN/syntax/30_error_handling.md b/doc/zh_CN/syntax/30_error_handling.md index c67e363a..c52d5cbf 100644 --- a/doc/zh_CN/syntax/30_error_handling.md +++ b/doc/zh_CN/syntax/30_error_handling.md @@ -30,7 +30,7 @@ except 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 +```python # Erg try!: do!: @@ -50,7 +50,7 @@ The benefits of using the `Result` type don't stop there. The `Result` type is a Since the `Error`/`Result` type alone does not cause side effects, unlike exceptions, it cannot have information such as the sending location (Context), but if you use the `.context` method, you can put information in the `Error` object. can be added. The `.context` method is a type of method that consumes the `Error` object itself and creates a new `Error` object. They are chainable and can hold multiple contexts. -``` erg +```python f() = todo() \ .context "to be implemented in ver 1.2" \ @@ -71,7 +71,7 @@ Therefore, in Erg, the `Error` object has an attribute called `.stack`, and repr `.stack` is an array of caller objects. Each time an Error object is `returned` (including by `?`) it pushes its calling subroutine onto the `.stack`. And if it is `?`ed or `.unwrap`ed in a context where `return` is not possible, it will panic with a traceback. -``` erg +```python f x = ... y = foo.try_some(x)? @@ -100,7 +100,7 @@ An unrecoverable error is an error caused by an external factor such as a softwa Panic is done with the `panic` function. -``` erg +```python panic "something went wrong!" ``` diff --git a/doc/zh_CN/syntax/31_pipeline.md b/doc/zh_CN/syntax/31_pipeline.md index 4093994e..09596b06 100644 --- a/doc/zh_CN/syntax/31_pipeline.md +++ b/doc/zh_CN/syntax/31_pipeline.md @@ -2,7 +2,7 @@ Pipeline operators are used like this: -``` erg +```python assert f(g(x)) == (x |> g |> f) assert f(g(x, y)) == ((x, y) |> g |> f) ``` @@ -11,7 +11,7 @@ In other words, the order `Callable(object)` can be changed to `object |> Callab The pipeline operator can also be used on 方法. For 方法, `object.method(args)` changes to `object |>.method(args)`. It looks like just more `|>`, but since the bond strength is low, you may be able to reduce the amount of `()`. -``` erg +```python rand = -1.0..1.0 |>.sample!() log rand # 0.2597... diff --git a/doc/zh_CN/syntax/container_ownership.md b/doc/zh_CN/syntax/container_ownership.md index af0bc06a..08f90efc 100644 --- a/doc/zh_CN/syntax/container_ownership.md +++ b/doc/zh_CN/syntax/container_ownership.md @@ -2,7 +2,7 @@ `[]` is different from normal 方法. -``` erg +```python a = [!1, !2] a[0].inc!() assert a == [2, 2] @@ -13,7 +13,7 @@ The type of `a[0]` here should clearly be `Ref!(Int!)` (the type of `a[0]` depen 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 +```python C = Class {i = Int!} C. get(ref self) = self::i # TypeError: `self::i` is `Int!` (require ownership) but `get` doesn't own `self` @@ -33,7 +33,7 @@ own_do! C.new({i = 1}).steal(), i => i.inc!() Also, `[]` can be disowned, but the element is not shifted. -``` erg +```python a = [!1, !2] i = a[0] i.inc!() diff --git a/doc/zh_CN/syntax/quick_tour.md b/doc/zh_CN/syntax/quick_tour.md index f3511598..4bd39ad7 100644 --- a/doc/zh_CN/syntax/quick_tour.md +++ b/doc/zh_CN/syntax/quick_tour.md @@ -10,7 +10,7 @@ Please think that the parts not mentioned are the same as Python. Variables are defined with `=`. As with Haskell, variables once defined cannot be changed. However, it can be shadowed in another scope. -``` erg +```python i = 0 if True: i = 1 @@ -20,7 +20,7 @@ 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 +```python PI = 3.141592653589793 match random.random!(0..10): PIs: @@ -32,7 +32,7 @@ match random.random!(0..10): 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 +```python i: Int i = 10 ``` @@ -41,7 +41,7 @@ i = 10 You can define it just like in Haskell. -``` erg +```python fib0 = 0 fib1 = 1 fibn = fib(n - 1) + fib(n - 2) @@ -49,7 +49,7 @@ fibn = fib(n - 1) + fib(n - 2) An anonymous function can be defined like this: -``` erg +```python i -> i + 1 assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4] ``` @@ -62,7 +62,7 @@ The Erg-specific operators are: It's like `ref` in Ocaml. -``` erg +```python i = !0 i.update! x -> x + 1 assert i == 1 @@ -72,13 +72,13 @@ assert i == 1 Subroutines with side effects are called procedures and are marked with `!`. -``` erg +```python print! 1 # 1 ``` ## generic function (polycorrelation) -``` erg +```python id|T|(x: T): T = x id(1): Int id("a"): Str @@ -88,7 +88,7 @@ id("a"): Str You can use the equivalent of records in ML-like languages ​​(or object literals in JS). -``` erg +```python p = {x = 1; y = 2} ``` @@ -96,7 +96,7 @@ p = {x = 1; y = 2} Ergs are owned by mutable objects (objects mutated with the `!` operator) and cannot be rewritten from multiple places. -``` erg +```python i = !0 j = i assert j == 0 @@ -109,13 +109,13 @@ Immutable objects, on the other hand, can be referenced from multiple places. Prefixing a variable with `.` makes it a public variable and allows it to be referenced from external modules. -``` erg +```python # foo.er .x = 1 y = 1 ``` -``` erg +```python foo = import "foo" assert foo.x == 1 foo.y # VisibilityError @@ -125,7 +125,7 @@ foo.y # VisibilityError ### variable pattern -``` erg +```python # basic assignments i = 1 # with type @@ -137,7 +137,7 @@ fn: Int -> Int = x -> x + 1 ### Literal patterns -``` erg +```python # if `i` cannot be determined to be 1 at compile time, TypeError occurs. # shorthand of `_: {1} = i` 1 = i @@ -154,7 +154,7 @@ fibn: Nat = fibn-1 + fibn-2 ### constant pattern -``` erg +```python PI = 3.141592653589793 E = 2.718281828459045 num = PI @@ -166,7 +166,7 @@ name = match num: ### discard (wildcard) pattern -``` erg +```python _ = 1 _: Int = 1 right(_, r) = r @@ -176,7 +176,7 @@ right(_, r) = r Used in combination with the tuple/array/record pattern described later. -``` erg +```python [i,...j] = [1, 2, 3, 4] assert j == [2, 3, 4] first|T|(fst: T, ...rest: T) = fst @@ -185,7 +185,7 @@ assert first(1, 2, 3) == 1 ### Tuple pattern -``` erg +```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) # If not nested, () can be omitted (1, 2 are treated as (1, 2)) @@ -194,14 +194,14 @@ m, n = 1, 2 ### array pattern -``` erg +```python length[] = 0 length[_, ...rest] = 1 + lengthrest ``` #### record pattern -``` erg +```python {sin; cos; tan; ...} = import "math" {*} = import "math" # import all @@ -213,7 +213,7 @@ age = match person: ### Data class pattern -``` erg +```python Point = Inherit {x = Int; y = Int} p = Point::{x = 1; y = 2} Point::{x; y} = p @@ -221,7 +221,7 @@ Point::{x; y} = p ## Comprehensions -``` erg +```python odds = [i | i <- 1..100; i % 2 == 0] ``` @@ -234,7 +234,7 @@ Erg does not support multiple/multilevel inheritance. They are similar to Rust traits, but in a more literal sense, allowing composition and decoupling, and treating attributes and 方法 as equals. Also, it does not involve implementation. -``` erg +```python XY = Trait {x = Int; y = Int} Z = Trait {z = Int} XYZ = XY and Z @@ -254,13 +254,13 @@ You can give implementations to classes and traits. A predicate expression can be type-restricted. -``` erg +```python Nat = {I: Int | I >= 0} ``` ## parametric type with value (dependent type) -``` erg +```python a: [Int; 3] b: [Int; 4] a + b: [Int; 7] diff --git a/doc/zh_CN/syntax/type/08_value.md b/doc/zh_CN/syntax/type/08_value.md index 21db678b..9f0bf89c 100644 --- a/doc/zh_CN/syntax/type/08_value.md +++ b/doc/zh_CN/syntax/type/08_value.md @@ -2,7 +2,7 @@ Value types are Erg built-in types that can be evaluated at compile time, specifically: -``` erg +```python Value = ( Int or Nat @@ -23,7 +23,7 @@ Value = ( Value-type objects, constants, and compile-time subroutines applied to them are called __constant expressions__. -``` erg +```python 1, 1.0, 1+2im, True, None, "aaa", [1, 2, 3], Fib(12) ``` diff --git a/doc/zh_CN/syntax/type/14_dependent.md b/doc/zh_CN/syntax/type/14_dependent.md index bf5ac404..56fe4de2 100644 --- a/doc/zh_CN/syntax/type/14_dependent.md +++ b/doc/zh_CN/syntax/type/14_dependent.md @@ -6,7 +6,7 @@ A dependent type is a type that takes a value as an argument. Ordinary polymorph 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 +```python a1 = [1, 2, 3] assert a1 in [Nat; 3] a2 = [4, 5, 6, 7] @@ -16,7 +16,7 @@ assert a1 + a2 in [Nat; 7] If the type object passed in the function argument is related to the return type, write: -``` erg +```python narray: |N: Nat| {N} -> [{N}; N] narray(N: Nat): [N; N] = [N; N] assert array(3) == [3, 3, 3] @@ -26,7 +26,7 @@ When defining a dependent type, all type arguments must be constants. Dependent types themselves exist in existing languages, but Erg has the feature of defining procedural 方法 on dependent types. -``` erg +```python x=1 f x = print! f::x, module::x @@ -42,7 +42,7 @@ T(1).x() # 1 Type arguments of mutable dependent types can be transitioned by method application. Transition specification is done with `~>`. -``` erg +```python # Note that `Id` is an immutable type and cannot be transitioned VM!(State: {"stopped", "running"}! := _, Id: Nat := _) = Class(..., Impl := Phantom! State) VM!(). @@ -66,7 +66,7 @@ vm.stop!() # TypeError: VM!(!"stopped", 1) doesn't have .stop!() You can also embed or inherit existing types to create dependent types. -``` erg +```python MyArray(T, N) = Inherit[T; N] # The type of self: Self(T, N) changes in conjunction with .array diff --git a/doc/zh_CN/syntax/type/18_mut.md b/doc/zh_CN/syntax/type/18_mut.md index 8ea1f9db..0377d83c 100644 --- a/doc/zh_CN/syntax/type/18_mut.md +++ b/doc/zh_CN/syntax/type/18_mut.md @@ -5,7 +5,7 @@ By default all types in Erg are immutable, i.e. their internal state cannot be updated. But you can of course also define mutable types. Variable types are declared with `!`. -``` erg +```python Person! = Class({name = Str; age = Nat!}) Person!. greet! ref! self = print! "Hello, my name is {self::name}. I am {self::age}." @@ -19,7 +19,7 @@ Mutable types can define procedural 方法 that rewrite instances, but having pr Destructive operations on mutable objects are primarily done via the `.update!` method. The `.update!` method is a higher-order procedure that updates `self` by applying the function `f`. -``` erg +```python i = !1 i.update! old -> old + 1 assert i == 2 @@ -27,7 +27,7 @@ assert i == 2 The `.set!` method simply discards the old content and replaces it with the new value. .set!x = .update!_ -> x. -``` erg +```python i = !1 i.set! 2 assert i == 2 @@ -35,14 +35,14 @@ assert i == 2 The `.freeze_map` method operates on values ​​unchanged. -``` erg +```python a = [1, 2, 3].into [Nat; !3] x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(Array) ``` In a polymorphic immutable type the type argument `T` of the type is implicitly assumed to be immutable. -``` erg +```python # ImmutType < Type KT: ImmutType = Class ... K!T: Type = Class ... @@ -53,7 +53,7 @@ In the standard library, variable `(...)!` types are often based on immutable `( Note that there are several types of object mutability. Below we will review the immutable/mutable semantics of the built-in collection types. -``` erg +```python # array type ## immutable types [T; N] # Cannot perform mutable operations @@ -72,7 +72,7 @@ For variable array types, just add `!` to the part you want to be variable, and These array types are syntactic sugar, the actual types are: -``` erg +```python # actually 4 types [T; N] = Array(T, N) [T; !N] = Array!(T, !N) @@ -85,7 +85,7 @@ These array types are syntactic sugar, the actual types are: This is what it means to be able to change the type. -``` erg +```python a = [1, 2, 3].into [!Nat; 3] a.map!(_ -> "a") a: [!Str; 3] @@ -93,7 +93,7 @@ a: [!Str; 3] The same is true for other collection types. -``` erg +```python # tuple type ## immutable types (T, U) # No change in number of elements, contents cannot be changed @@ -103,7 +103,7 @@ The same is true for other collection types. ... ``` -``` erg +```python # Set type ## immutable types {T; N} # number of immutable elements, contents cannot be changed @@ -114,7 +114,7 @@ The same is true for other collection types. ... ``` -``` erg +```python # Dictionary type ## immutable types {K: V} # immutable length, contents cannot be changed @@ -124,7 +124,7 @@ The same is true for other collection types. ... ``` -``` erg +```python # Record type ## immutable types {x = Int; y = Str} # content cannot be changed @@ -137,7 +137,7 @@ The same is true for other collection types. 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 +```python # Sieve type ## Enums {1, 2, 3} # one of 1, 2, 3, cannot be changed diff --git a/doc/zh_CN/syntax/type/19_bound.md b/doc/zh_CN/syntax/type/19_bound.md index 90411ac4..c3365d95 100644 --- a/doc/zh_CN/syntax/type/19_bound.md +++ b/doc/zh_CN/syntax/type/19_bound.md @@ -9,7 +9,7 @@ Guards are written after the return type. You can specify the condition that the variable satisfies with an expression (predicate expression) that returns `Bool`. Only [value objects](./08_value.md) and operators can be used. Compile-time functions may be supported in future versions. -``` erg +```python f a: [T; N] | T, N, N > 5 = ... g a: [T; N | N > 5] | T, N = ... Odd = {I: Int | I % 2 == 1} diff --git a/doc/zh_CN/syntax/type/advanced/GADTs.md b/doc/zh_CN/syntax/type/advanced/GADTs.md index ee5da587..4d6cc616 100644 --- a/doc/zh_CN/syntax/type/advanced/GADTs.md +++ b/doc/zh_CN/syntax/type/advanced/GADTs.md @@ -2,7 +2,7 @@ Erg can create Generalized Algebraic Data Types (GADTs) by classifying Or types. -``` erg +```python Nil T = Class(Impl := Phantom T) Cons T = Class {head = T; rest = List T}, Impl := Unpack List T: Type = Class(Nil T or Cons T) @@ -20,7 +20,7 @@ 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 +```python i = List.nil() _: List Int = cons 1, i ``` @@ -28,7 +28,7 @@ _: List Int = cons 1, i The `List T` defined here is GADTs, but it's a naive implementation and doesn't show the true value of GADTs. For example, the `.head` method above will throw a runtime error if the body is empty, but this check can be done at compile time. -``` erg +```python List: (Type, {"Empty", "Nonempty"}) -> Type List T, "Empty" = Class(Impl := Phantom T) List T, "Nonempty" = Class {head = T; rest = List(T, _)}, Impl := Unpack @@ -46,7 +46,7 @@ print! nil().head() # TypeError An example of GADTs that is often explained on the street is a list that can judge whether the contents are empty or not by type as above. Erg can be further refined to define a list with length. -``` erg +```python List: (Type, Nat) -> Type List T, 0 = Class(Impl := Phantom T) List T, N = Class {head = T; rest = List(T, N-1)}, Impl := Unpack diff --git a/doc/zh_CN/syntax/type/advanced/_rank2type.md b/doc/zh_CN/syntax/type/advanced/_rank2type.md index 11b4afcd..c46fc43b 100644 --- a/doc/zh_CN/syntax/type/advanced/_rank2type.md +++ b/doc/zh_CN/syntax/type/advanced/_rank2type.md @@ -6,7 +6,7 @@ Erg allows you to define functions that accept various types such as `id|T|(x: T So, can we define a function that accepts polycorrelations? For example, a function like this (note that this definition is erroneous): -``` erg +```python # I want tuple_map(i -> i * 2, (1, "a")) == (2, "aa") tuple_map|T|(f: T -> T, tup: (Int, Str)): (Int, Str) = (f(tup.0), f(tup.1)) ``` @@ -15,7 +15,7 @@ Note that `1` and `"a"` have different types, so the anonymous function is not m 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 +```python arr = [1, 2, 3] arr.map i -> i + 1 ``` @@ -25,7 +25,7 @@ arr.map i -> i + 1 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 +```python # tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) tuple_map f: (|T: Type| T -> T), tup: (Int, Str) = (f(tup.0), f(tup.1)) assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa") @@ -34,7 +34,7 @@ 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 +```python id x = x id: |T: Type| T -> T ``` @@ -43,7 +43,7 @@ A universal type has special rules for association with the function type constr Think about this in terms of simple one-argument functions. -``` erg +```python f1: (T -> T) -> Int | T # a function that takes any function and returns an Int f2: (|T: Type| T -> T) -> Int # Function that receives polycorrelation and returns Int f3: Int -> (|T: Type| T -> T) # A function that takes an Int and returns a closed universal function @@ -52,7 +52,7 @@ 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 +```python # id: |T: Type| T -> T id x = x # same type as `f1` @@ -67,7 +67,7 @@ take_i_and_return_arbit_f|T: Type|(_: Int): (T -> T) = id After applying it, you will notice the difference. -``` erg +```python _ = take_univq_f_and_return_i(x -> x, 1) # OK _ = take_univq_f_and_return_i(x: Int -> x, 1) #NG _ = take_univq_f_and_return_i(x: Str -> x, 1) # NG @@ -90,7 +90,7 @@ But the types of functions like `f2` are clearly different from normal types, an 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 +```python # K is a polynomial kind such as Option R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0) ``` @@ -99,7 +99,7 @@ Next, types with first-order universal quantification, such as `|T| T -> T`, or 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 +```python R1 = (|...| R0) or (R0 -> R1) or K(R1) or R0 R2 = (|...| R1) or (R1 -> R2) or K(R2) or R1 ... @@ -108,7 +108,7 @@ Rn = (|...| Rn-1) or (Rn-1 -> Rn) or K(Rn) or Rn-1 Let's look at some examples. -``` erg +```python (|T: Type| T -> T) -> (|U: Type| U -> U) => R1 -> R1 => R1 -> R2 @@ -122,7 +122,7 @@ Option(|T: Type| T -> T) By definition, `tuple_map` is a rank-2 type. -``` erg +```python tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) => (R1, R0) -> R0 @@ -133,7 +133,7 @@ tuple_map: 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 +```python # this is a rank-3 type function # |X, Y: Type|((|T: Type| T -> T), (X, Y)) -> (X, Y) generic_tuple_map|X, Y: Type| f: (|T: Type| T -> T), tup: (X, Y) = (f(tup.0), f(tup.1)) diff --git a/doc/zh_CN/syntax/type/advanced/default_param.md b/doc/zh_CN/syntax/type/advanced/default_param.md index d18a9e02..d7bf81ab 100644 --- a/doc/zh_CN/syntax/type/advanced/default_param.md +++ b/doc/zh_CN/syntax/type/advanced/default_param.md @@ -2,7 +2,7 @@ First, let's look at an example of using default arguments. -``` erg +```python f: (Int, Int, z := Int) -> Int f(x, y, z := 0) = x + y + z @@ -19,7 +19,7 @@ assert fold(g, [1, 2, 3]) == 8 Arguments after `:=` are default arguments. The subtyping rules are as follows. -``` erg +```python ((X, y := Y) -> Z) <: (X -> Z) ((X, y := Y, ...) -> Z) <: ((X, ...) -> Z) ``` diff --git a/doc/zh_CN/syntax/type/advanced/keyword_param.md b/doc/zh_CN/syntax/type/advanced/keyword_param.md index 45db64bc..789fbe7e 100644 --- a/doc/zh_CN/syntax/type/advanced/keyword_param.md +++ b/doc/zh_CN/syntax/type/advanced/keyword_param.md @@ -1,13 +1,13 @@ # Function type with keyword arguments -``` erg +```python h(f) = f(y: 1, x: 2) h: |T: Type|((y: Int, x: Int) -> T) -> T ``` The subtyping rules for functions with keyword arguments are as follows. -``` erg +```python ((x: T, y: U) -> V) <: ((T, U) -> V) # x, y are arbitrary keyword parameters ((y: U, x: T) -> V) <: ((x: T, y: U) -> V) ((x: T, y: U) -> V) <: ((y: U, x: T) -> V) @@ -18,7 +18,7 @@ But you can't do both at the same time. That is, you cannot cast `(x: T, y: U) -> V` to `(U, T) -> V`. Note that keyword arguments are attached only to top-level tuples, and not to arrays or nested tuples. -``` erg +```python Valid: [T, U] -> V Invalid: [x: T, y: U] -> V Valid: (x: T, ys: (U,)) -> V diff --git a/doc/zh_CN/syntax/type/advanced/kind.md b/doc/zh_CN/syntax/type/advanced/kind.md index 6e6b41c2..f9149482 100644 --- a/doc/zh_CN/syntax/type/advanced/kind.md +++ b/doc/zh_CN/syntax/type/advanced/kind.md @@ -9,7 +9,7 @@ Note that `->` itself, which is an anonymous function operator, can also be seen Also note that a kind that is not an atomic kind is not a type. Just as `-1` is a number but `-` is not, `Option Int` is a type but `Option` is not. `Option` etc. are sometimes called type constructors. -``` erg +```python assert not Option in Type assert Option in Type -> Type ``` @@ -17,7 +17,7 @@ assert Option in Type -> Type So code like the following will result in an error: In Erg, 方法 can only be defined in atomic kinds, and the name `self` cannot be used anywhere other than the first argument of a method. -``` erg +```python #K is an unary kind K: Type -> Type K T = Class... @@ -32,7 +32,7 @@ Examples of binary or higher kinds are `{T: U}`(: `(Type, Type) -> Type`), `(T, There is also a zero-term kind `() -> Type`. This is sometimes equated with an atomic kind in type theory, but is distinguished in Erg. An example is `Class`. -``` erg +```python Nil = Class() ``` @@ -40,7 +40,7 @@ Nil = Class() There is also a partial type relation, or rather a partial kind relation, between multinomial kinds. -``` erg +```python K T = ... L = Inherit K L<: K @@ -48,7 +48,7 @@ L<: K That is, for any `T`, if `L T <: K T`, then `L <: K`, and vice versa. -``` erg +```python ∀T. L T <: K T <=> L <: K ``` @@ -56,7 +56,7 @@ That is, for any `T`, if `L T <: K T`, then `L <: K`, and vice versa. There is also a higher-order kind. This is a kind of the same concept as a higher-order function, a kind that receives a kind itself. `(Type -> Type) -> Type` is a higher kind. Let's define an object that belongs to a higher kind. -``` erg +```python IntContainerOf K: Type -> Type = K Int assert IntContainerOf Option == Option Int assert IntContainerOf Result == Result Int @@ -69,26 +69,26 @@ The bound variables of a polynomial kind are usually denoted as K, L, ..., where In type theory, there is the concept of a record. This is almost the same as the Erg record [2](#2). -``` erg +```python # This is a record, and it corresponds to what is called a record in type theory {x = 1; y = 2} ``` When all record values ​​were types, it was a kind of type called a record type. -``` erg +```python assert {x = 1; y = 2} in {x = Int; y = Int} ``` A record type types a record. A good guesser might have thought that there should be a "record kind" to type the record type. Actually it exists. -``` erg +```python log Typeof {x = Int; y = Int} # {{x = Int; y = Int}} ``` A type like `{{x = Int; y = Int}}` is a record kind. This is not a special notation. It is simply an enumeration type that has only `{x = Int; y = Int}` as an element. -``` erg +```python Point = {x = Int; y = Int} Pointy = {Point} ``` @@ -96,7 +96,7 @@ Pointy = {Point} An important property of record kind is that if `T: |T|` and `U <: T` then `U: |T|`. This is also evident from the fact that enums are actually syntactic sugar for sieve types. -``` erg +```python # {c} == {X: T | X == c} for normal objects, but # Equality may not be defined for types, so |T| == {X | X <: T} {Point} == {P | P <: Point} @@ -105,7 +105,7 @@ This is also evident from the fact that enums are actually syntactic sugar for s `U <: T` in type constraints is actually syntactic sugar for `U: |T|`. A kind that is a set of such types is commonly called a set kind. Setkind also appears in the Iterator pattern. -``` erg +```python Iterable T = Trait { .Iterator = {Iterator} .iter = Self(T).() -> Self.Iterator T @@ -114,7 +114,7 @@ Iterable T = Trait { ## Type inference for polynomial kinds -``` erg +```python Container K: Type -> Type, T: Type = Patch K(T, T) Container (K). f self = ... diff --git a/doc/zh_CN/syntax/type/advanced/marker_trait.md b/doc/zh_CN/syntax/type/advanced/marker_trait.md index 17b8326b..bbf90ad4 100644 --- a/doc/zh_CN/syntax/type/advanced/marker_trait.md +++ b/doc/zh_CN/syntax/type/advanced/marker_trait.md @@ -6,15 +6,15 @@ It seems meaningless without the required attribute, but since the information t All marker traits are subsumed by the `Marker` trait. `Light` provided as standard is a kind of marker trait. -``` erg +```python Light = Subsume Marker ``` -``` erg +```python Person = Class {.name = Str; .age = Nat} and Light ``` -``` erg +```python M = Subsume Marker MarkedInt = Inherit Int, Impl := M @@ -26,6 +26,6 @@ assert i in M Marker classes can also be excluded with the `Excluding` argument. -``` erg +```python NInt = Inherit MarkedInt, Impl := N, Excluding: M ``` \ No newline at end of file diff --git a/doc/zh_CN/syntax/type/advanced/special.md b/doc/zh_CN/syntax/type/advanced/special.md index 8fa6825b..800e37bb 100644 --- a/doc/zh_CN/syntax/type/advanced/special.md +++ b/doc/zh_CN/syntax/type/advanced/special.md @@ -2,7 +2,7 @@ `Self` represents its own type. You can just use it as an alias, but note that the meaning changes in derived types (refers to the own type). -``` erg +```python @Inheritable C = Class() C. @@ -16,7 +16,7 @@ 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 +```python @Inheritable C = Class() @@ -33,7 +33,7 @@ classof D. new_c() # C `Self` and `Super` can be used as type variables in structured types and traits. This refers to classes that are subtypes of that type. That is, `Self` in type `T` means `Self <: T`. -``` erg +```python Add R = Trait { .AddO = Type .`_+_`: Self, R -> Self.AddO diff --git a/doc/zh_CN/syntax/type/advanced/typeof.md b/doc/zh_CN/syntax/type/advanced/typeof.md index ab16bb84..b320d7a0 100644 --- a/doc/zh_CN/syntax/type/advanced/typeof.md +++ b/doc/zh_CN/syntax/type/advanced/typeof.md @@ -2,7 +2,7 @@ `Typeof` is a function that can peek into Erg's type inference system, and its behavior is complex. -``` erg +```python assert Typeof(1) == {I: Int | I == 1} i: 1..3 or 5..10 = ... assert Typeof(i) == {I: Int | (I >= 1 and I <= 3) or (I >= 5 and I <= 10)} @@ -21,7 +21,7 @@ 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 +```python i: Int = ... assert Typeof(i) == {__valueclass_tag__ = Phantom Int} s: Str = ... @@ -38,7 +38,7 @@ Erg infers object types as sieve types as much as possible, and when that is not 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 +```python C = Class {i = Int} assert Structure(C) == {i = Int} D = Inherit C diff --git a/doc/zh_CN/syntax/type/advanced/variance.md b/doc/zh_CN/syntax/type/advanced/variance.md index 0c1d8f32..44b72b71 100644 --- a/doc/zh_CN/syntax/type/advanced/variance.md +++ b/doc/zh_CN/syntax/type/advanced/variance.md @@ -49,7 +49,7 @@ This is because `SharedCell! T!` is a shared reference. See [shared references]( A universal type variable can specify its upper and lower bounds. -``` erg +```python |A <: T| K(A) |B :> T| K(B) ``` @@ -59,14 +59,14 @@ In this case, `T` is also called the upper type for `A` and the lower type for ` Mutation specifications can also overlap. -``` erg +```python # U U} ``` Here is an example of code that uses a variable specification. -``` erg +```python show|S <: Show| s: S = log s Nil T = Class(Impl = Phantom T) @@ -90,7 +90,7 @@ For example, `List Int` can be upcast to `List Object` and `Obj -> Obj` can be u Now let's consider what happens if we omit the variable specification of the method. -``` erg +```python ... List T = Class {head = T; rest = Cons T} List(T). @@ -109,7 +109,7 @@ Similarly, a cast from `List T` to `List U` is possible subject to the constrain Now let's see what happens if we allow this upcast. Let's invert the denaturation designation. -``` erg +```python ... List T = Class {head = T; rest = Cons T} List(T). @@ -128,7 +128,7 @@ Mutations of user-defined types are immutable by default. However, you can also 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 +```python K T = Class(...) assert not K(Str) <= K(Object) assert not K(Str) >= K(Object) diff --git a/doc/zh_CN/syntax/type/advanced/widening.md b/doc/zh_CN/syntax/type/advanced/widening.md index 7d0a9b47..d29e27cf 100644 --- a/doc/zh_CN/syntax/type/advanced/widening.md +++ b/doc/zh_CN/syntax/type/advanced/widening.md @@ -2,7 +2,7 @@ For example, define the polycorrelation coefficient as follows. -``` erg +```python ids|T|(x: T, y: T) = x, y ``` @@ -10,7 +10,7 @@ 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 +```python assert ids(1, 2) == (1, 2) assert ids(1, 2.0) == (1.0, 2.0) ids(1, "a") #TypeError @@ -18,7 +18,7 @@ ids(1, "a") #TypeError Now, what about types that have different derived types? -``` erg +```python i: Int or Str j: Int or NoneType ids(i, j) # ? @@ -26,7 +26,7 @@ ids(i, j) # ? Before explaining this, we have to focus on the fact that Erg's type system doesn't actually look at (runtime) classes. -``` erg +```python 1: {__valueclass_tag__ = Phantom Int} 2: {__valueclass_tag__ = Phantom Int} 2.0: {__valueclass_tag__ = Phantom Ratio} @@ -43,7 +43,7 @@ Of course, the class of an object of type `Int` is defined as `Int`, but in this 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 +```python i: Int or Str j: Int or NoneType ids(i, j) # TypeError: types of i and j not matched @@ -67,7 +67,7 @@ ids(i, j) # OK Erg defaults to an error if return types do not match. -``` erg +```python parse_to_int s: Str = if not s.is_numeric(): do parse_to_int::return error("not numeric") @@ -81,7 +81,7 @@ parse_to_int s: Str = In order to solve this, it is necessary to explicitly specify the return type as Or type. -``` erg +```python parse_to_int(s: Str): Int or Error = if not s.is_numeric(): do parse_to_int::return error("not numeric") diff --git a/doc/zh_CN/tools/pack.md b/doc/zh_CN/tools/pack.md index ae02aa88..d2e2f561 100644 --- a/doc/zh_CN/tools/pack.md +++ b/doc/zh_CN/tools/pack.md @@ -34,7 +34,7 @@ Also see [package_system.md](../syntax/33_package_system.md) for the Erg package `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 +```python name = "example" # package name author = "John Smith" # package author name version="0.1.0" diff --git a/doc/zh_CN/tools/test.md b/doc/zh_CN/tools/test.md index 6e449ac8..5844047c 100644 --- a/doc/zh_CN/tools/test.md +++ b/doc/zh_CN/tools/test.md @@ -7,7 +7,7 @@ The erg command has a subcommand called test, which supports test implementation 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 +```python # tests/test1.er {add; ...} = import "foo" @@ -24,12 +24,12 @@ In Erg, `#` and `#[` are comment lines, but `##` and `#[[` are doc comments, and 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 +```python VMs =... ... #[[ execute commands. - ``` erg + ```python # VM in standard configuration {vm1; ...} = import "tests/mock" From 7f025c85b8c55eab37b003d5333cf9380ff34460 Mon Sep 17 00:00:00 2001 From: GreasySlug <9619abgoni@gmail.com> Date: Sun, 4 Sep 2022 14:30:49 +0900 Subject: [PATCH 11/42] Update to add badges in JA doc --- doc/JA/dev_guide/branches.md | 2 ++ doc/JA/dev_guide/build_features.md | 2 ++ doc/JA/dev_guide/directories.md | 2 ++ doc/JA/dev_guide/doc_guideline.md | 2 ++ doc/JA/dev_guide/env.md | 2 ++ doc/JA/dev_guide/faq_syntax.md | 2 ++ doc/JA/dev_guide/i18n_messages.md | 2 ++ doc/JA/dev_guide/index.md | 2 ++ doc/JA/dev_guide/rust_code_guideline.md | 2 ++ doc/JA/dev_guide/terms.md | 2 ++ doc/JA/dev_guide/unify_terms.md | 2 ++ doc/JA/faq_general.md | 2 ++ doc/JA/faq_technical.md | 2 ++ doc/JA/improved_points.md | 2 ++ doc/JA/index.md | 2 ++ doc/JA/migration_from_py.md | 2 ++ doc/JA/syntax/00_basic.md | 2 ++ doc/JA/syntax/01_literal.md | 2 ++ doc/JA/syntax/02_name.md | 2 ++ doc/JA/syntax/03_declaration.md | 2 ++ doc/JA/syntax/04_function.md | 2 ++ doc/JA/syntax/05_builtin_funcs.md | 2 ++ doc/JA/syntax/06_operator.md | 2 ++ doc/JA/syntax/07_side_effect.md | 2 ++ doc/JA/syntax/08_procedure.md | 2 ++ doc/JA/syntax/09_builtin_procs.md | 2 ++ doc/JA/syntax/10_array.md | 2 ++ doc/JA/syntax/11_tuple.md | 2 ++ doc/JA/syntax/12_dict.md | 2 ++ doc/JA/syntax/13_record.md | 2 ++ doc/JA/syntax/14_set.md | 2 ++ doc/JA/syntax/15_type.md | 2 ++ doc/JA/syntax/16_iterator.md | 2 ++ doc/JA/syntax/17_mutability.md | 2 ++ doc/JA/syntax/18_ownership.md | 2 ++ doc/JA/syntax/19_visibility.md | 2 ++ doc/JA/syntax/20_naming_rule.md | 2 ++ doc/JA/syntax/21_lambda.md | 2 ++ doc/JA/syntax/22_subroutine.md | 2 ++ doc/JA/syntax/23_closure.md | 2 ++ doc/JA/syntax/24_module.md | 2 ++ doc/JA/syntax/25_object_system.md | 2 ++ doc/JA/syntax/26_pattern_matching.md | 2 ++ doc/JA/syntax/27_comprehension.md | 2 ++ doc/JA/syntax/28_spread_syntax.md | 2 ++ doc/JA/syntax/29_decorator.md | 2 ++ doc/JA/syntax/30_error_handling.md | 2 ++ doc/JA/syntax/31_pipeline.md | 2 ++ doc/JA/syntax/32_integration_with_Python.md | 2 ++ doc/JA/syntax/33_package_system.md | 2 ++ doc/JA/syntax/34_generator.md | 2 ++ doc/JA/syntax/SUMMARY.md | 2 ++ doc/JA/syntax/container_ownership.md | 2 ++ doc/JA/syntax/indexes.md | 2 ++ doc/JA/syntax/quick_tour.md | 2 ++ doc/JA/syntax/type/01_type_system.md | 2 ++ doc/JA/syntax/type/02_basic.md | 2 ++ doc/JA/syntax/type/03_trait.md | 2 ++ doc/JA/syntax/type/04_class.md | 2 ++ doc/JA/syntax/type/05_inheritance.md | 2 ++ doc/JA/syntax/type/06_nst_vs_sst.md | 2 ++ doc/JA/syntax/type/07_patch.md | 2 ++ doc/JA/syntax/type/08_value.md | 2 ++ doc/JA/syntax/type/09_attributive.md | 2 ++ doc/JA/syntax/type/10_interval.md | 2 ++ doc/JA/syntax/type/11_enum.md | 2 ++ doc/JA/syntax/type/12_refinement.md | 2 ++ doc/JA/syntax/type/13_algebraic.md | 2 ++ doc/JA/syntax/type/14_dependent.md | 2 ++ doc/JA/syntax/type/15_quantified.md | 2 ++ doc/JA/syntax/type/16_subtyping.md | 2 ++ doc/JA/syntax/type/17_type_casting.md | 2 ++ doc/JA/syntax/type/18_mut.md | 2 ++ doc/JA/syntax/type/19_bound.md | 2 ++ doc/JA/syntax/type/advanced.md | 2 ++ doc/JA/syntax/type/advanced/GADTs.md | 2 ++ doc/JA/syntax/type/advanced/default_param.md | 2 ++ doc/JA/syntax/type/advanced/erasure.md | 2 ++ doc/JA/syntax/type/advanced/existential.md | 2 ++ doc/JA/syntax/type/advanced/keyword_param.md | 2 ++ doc/JA/syntax/type/advanced/kind.md | 2 ++ doc/JA/syntax/type/advanced/marker_trait.md | 2 ++ doc/JA/syntax/type/advanced/mut_struct.md | 2 ++ doc/JA/syntax/type/advanced/newtype.md | 2 ++ doc/JA/syntax/type/advanced/overloading.md | 2 ++ doc/JA/syntax/type/advanced/phantom.md | 2 ++ doc/JA/syntax/type/advanced/projection.md | 2 ++ doc/JA/syntax/type/advanced/quantified_dependent.md | 2 ++ doc/JA/syntax/type/advanced/shared.md | 2 ++ doc/JA/syntax/type/advanced/special.md | 2 ++ doc/JA/tips.md | 2 ++ 91 files changed, 182 insertions(+) diff --git a/doc/JA/dev_guide/branches.md b/doc/JA/dev_guide/branches.md index c8eeb9a1..10caf61c 100644 --- a/doc/JA/dev_guide/branches.md +++ b/doc/JA/dev_guide/branches.md @@ -1,5 +1,7 @@ # ブランチの命名と運用方針 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/branches.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/branches.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + * 基本的に開発は`main`ブランチ一本で行う(モノレポ開発)。どうしてもブランチを切らないと作業しにくい場合のみ`feature-*`ブランチか`issue-*`ブランチを作成する。 ## main diff --git a/doc/JA/dev_guide/build_features.md b/doc/JA/dev_guide/build_features.md index f437b1c8..66ec2b14 100644 --- a/doc/JA/dev_guide/build_features.md +++ b/doc/JA/dev_guide/build_features.md @@ -1,5 +1,7 @@ # `erg` build features +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/build_features.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/build_features.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## debug デバッグモードにする。これにより、Erg内部での挙動が逐次ログ表示される。 diff --git a/doc/JA/dev_guide/directories.md b/doc/JA/dev_guide/directories.md index 1eb0c60c..5501dc7a 100644 --- a/doc/JA/dev_guide/directories.md +++ b/doc/JA/dev_guide/directories.md @@ -1,5 +1,7 @@ # Ergリポジトリのディレクトリ構造 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/directories.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/directories.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ```console └─┬ assets: 画像など ├─ CODE_OF_CONDUCT: 行動規範 diff --git a/doc/JA/dev_guide/doc_guideline.md b/doc/JA/dev_guide/doc_guideline.md index abcc87a2..ed0c5594 100644 --- a/doc/JA/dev_guide/doc_guideline.md +++ b/doc/JA/dev_guide/doc_guideline.md @@ -1,5 +1,7 @@ # 書式 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/doc_guideline.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/doc_guideline.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 以下のルールに従っていないドキュメントはすべて修正の対象となる。 * コードコメント、または内部用のドキュメントは、である調で書く。 diff --git a/doc/JA/dev_guide/env.md b/doc/JA/dev_guide/env.md index c85aa280..2a53b714 100644 --- a/doc/JA/dev_guide/env.md +++ b/doc/JA/dev_guide/env.md @@ -1,5 +1,7 @@ # 開発環境 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/env.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/env.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## インストールが必要なもの * Rust (installed with rustup) diff --git a/doc/JA/dev_guide/faq_syntax.md b/doc/JA/dev_guide/faq_syntax.md index 7972ae30..9540920a 100644 --- a/doc/JA/dev_guide/faq_syntax.md +++ b/doc/JA/dev_guide/faq_syntax.md @@ -1,5 +1,7 @@ # Erg design's "Why" and Answers +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/faq_syntax.md%26commit_hash%3D7cace5de15829b4b228a13f8b67e5ee3bf99e4a8)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/faq_syntax.md&commit_hash=7cace5de15829b4b228a13f8b67e5ee3bf99e4a8) + ## なぜ所有権システムがあるのにGCも共存させているのですか? Ergが所有権システムを導入した動機は、Rustのような「GCに頼らないメモリ管理」のためではないからです。 diff --git a/doc/JA/dev_guide/i18n_messages.md b/doc/JA/dev_guide/i18n_messages.md index 675d3f3d..ce78e413 100644 --- a/doc/JA/dev_guide/i18n_messages.md +++ b/doc/JA/dev_guide/i18n_messages.md @@ -1,5 +1,7 @@ # Multilingualization of Messages +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/i18n_messages.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/i18n_messages.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Ergはメッセージ(スタート、オプション、ドキュメント、ヒント、警告、エラーメッセージなど)の多言語化を進めています。 このプロジェクトは、RustやErgの詳しい知識がなくても参加することができます。ぜひ協力をお願いします。 diff --git a/doc/JA/dev_guide/index.md b/doc/JA/dev_guide/index.md index e69de29b..0e41be9e 100644 --- a/doc/JA/dev_guide/index.md +++ b/doc/JA/dev_guide/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/index.md%26commit_hash%3D7d43acdf0e2b71528b038b9a8e70be6c93831f96)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/index.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96) + diff --git a/doc/JA/dev_guide/rust_code_guideline.md b/doc/JA/dev_guide/rust_code_guideline.md index cf090732..681ac8e3 100644 --- a/doc/JA/dev_guide/rust_code_guideline.md +++ b/doc/JA/dev_guide/rust_code_guideline.md @@ -1,5 +1,7 @@ # Rustコードに関するガイドライン +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/rust_code_guideline.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/rust_code_guideline.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## ローカルルール * デバッグ用の出力には`log!`を使用する(release時にも必要な出力処理は`println!`等を使用する)。 diff --git a/doc/JA/dev_guide/terms.md b/doc/JA/dev_guide/terms.md index fa079ffb..4e09f798 100644 --- a/doc/JA/dev_guide/terms.md +++ b/doc/JA/dev_guide/terms.md @@ -1,5 +1,7 @@ # 用語辞典 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/terms.md%26commit_hash%3D7d43acdf0e2b71528b038b9a8e70be6c93831f96)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/terms.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96) + ## 記号 ### ! diff --git a/doc/JA/dev_guide/unify_terms.md b/doc/JA/dev_guide/unify_terms.md index fde909fa..150675ed 100644 --- a/doc/JA/dev_guide/unify_terms.md +++ b/doc/JA/dev_guide/unify_terms.md @@ -1,5 +1,7 @@ # 用語の統一 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/unify_terms.md%26commit_hash%3D7d43acdf0e2b71528b038b9a8e70be6c93831f96)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/unify_terms.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96) + ## Accessibility, Visibility (参照性、可視性) Visibility(可視性)を使用する。 diff --git a/doc/JA/faq_general.md b/doc/JA/faq_general.md index 9d2b4fac..f950b405 100644 --- a/doc/JA/faq_general.md +++ b/doc/JA/faq_general.md @@ -1,5 +1,7 @@ # Erg FAQ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/faq_general.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_general.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + このFAQは一般のErg入門者向けです。 個別の(よくある)技術的な問題については[こちら](./faq_technical.md)を、文法の決定経緯(なぜこのような文法になったのか)などについては [こちら](./dev_guide/why.md)を参照してください。 diff --git a/doc/JA/faq_technical.md b/doc/JA/faq_technical.md index affbc713..d34e4ea3 100644 --- a/doc/JA/faq_technical.md +++ b/doc/JA/faq_technical.md @@ -1,5 +1,7 @@ # 技術的なFAQ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/faq_technical.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_technical.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 本項はErg言語を使用する上での技術的な質問に答えるものです。すなわち、WhatやWhichで始まる質問、Yes/Noで答えられる質問を載せています。 根本的な文法の決定経緯については[こちら](./dev_guide/faq_syntax.md)を、なぜこの言語を作ったのか、この機能はどのように実装されているのかなど、より大きな話題は[こちら](./dev_guide/../faq_general.md)を参照してください。 diff --git a/doc/JA/improved_points.md b/doc/JA/improved_points.md index eb3d7f51..1bf003ca 100644 --- a/doc/JA/improved_points.md +++ b/doc/JA/improved_points.md @@ -1,5 +1,7 @@ # Pythonから改良された点 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/improved_points.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/improved_points.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## 静的解析を行う(静的型チェック、変数・プロパティチェック) 静的型チェックの恩恵は今更強調するまでもないほどですが、変数・プロパティの存在チェックもかなり効いてくる部分です。 diff --git a/doc/JA/index.md b/doc/JA/index.md index db3516f8..fa32a045 100644 --- a/doc/JA/index.md +++ b/doc/JA/index.md @@ -1,5 +1,7 @@ # Index +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/index.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/index.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## [API/](./API/index.md) Ergの組み込みまたは標準ライブラリで提供されるサブルーチン、型、定数等の仕様が記述されている。 diff --git a/doc/JA/migration_from_py.md b/doc/JA/migration_from_py.md index 4ad1c57b..de939029 100644 --- a/doc/JA/migration_from_py.md +++ b/doc/JA/migration_from_py.md @@ -1,5 +1,7 @@ # PythonからErgへの移行に関してのTips +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/migration_from_py.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/migration_from_py.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## 文字列をint等に変換したい `Str`クラスの`parse`メソッドを使用してください。これは`Result`型を返します。 diff --git a/doc/JA/syntax/00_basic.md b/doc/JA/syntax/00_basic.md index 09c298a6..0580ca95 100644 --- a/doc/JA/syntax/00_basic.md +++ b/doc/JA/syntax/00_basic.md @@ -1,5 +1,7 @@ # 基本事項 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/00_basic.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + > __Warning__: 本ドキュメントは未完成です。校正(文体、正しいリンクが張られているか、など)がなされていません。また、Ergの文法はバージョン0.*の間に破壊的変更が加えられる可能性があり、それに伴うドキュメントの更新が追いついていない可能性があります。予めご了承ください。 > また、本ドキュメントの誤りを見つけた場合は、[こちらのフォーム](https://forms.gle/HtLYRfYzWCAaeTGb6)または[GitHubリポジトリ](https://github.com/mtshiba/TheErgBook/issues/new)から修正の提案をしていただけると幸いです。 diff --git a/doc/JA/syntax/01_literal.md b/doc/JA/syntax/01_literal.md index 456b3ff3..491c92c1 100644 --- a/doc/JA/syntax/01_literal.md +++ b/doc/JA/syntax/01_literal.md @@ -1,5 +1,7 @@ # Literal +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/01_literal.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/01_literal.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## 基本的なリテラル ### 整数リテラル(Int Literal) diff --git a/doc/JA/syntax/02_name.md b/doc/JA/syntax/02_name.md index bd18402f..b05c7f42 100644 --- a/doc/JA/syntax/02_name.md +++ b/doc/JA/syntax/02_name.md @@ -1,5 +1,7 @@ # 変数 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/02_name.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 変数は代数の一種です。Ergにおける代数―紛れがなければ単に変数と呼ばれることもあります―とは、オブジェクトを名前付けしてコード中の別の場所から利用できるようにする機能を指します。 変数は以下のように定義します。 diff --git a/doc/JA/syntax/03_declaration.md b/doc/JA/syntax/03_declaration.md index a0077a81..9de36bee 100644 --- a/doc/JA/syntax/03_declaration.md +++ b/doc/JA/syntax/03_declaration.md @@ -1,5 +1,7 @@ # Declaration(宣言) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/03_declaration.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/03_declaration.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 宣言は、使用する変数の型を指定する構文です。 宣言はコード中のどこでも可能ですが、宣言しただけでその変数を参照することはできません。必ず初期化する必要があります。 代入後の宣言では、代入されたオブジェクトと型が適合するかをチェック可能です。 diff --git a/doc/JA/syntax/04_function.md b/doc/JA/syntax/04_function.md index abad4e52..327e7106 100644 --- a/doc/JA/syntax/04_function.md +++ b/doc/JA/syntax/04_function.md @@ -1,5 +1,7 @@ # 関数 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/04_function.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/04_function.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 関数は「引数」を受け取ってそれを加工し、「戻り値」として返すブロックです。以下のように定義します。 ```erg diff --git a/doc/JA/syntax/05_builtin_funcs.md b/doc/JA/syntax/05_builtin_funcs.md index 279755ed..b37058b7 100644 --- a/doc/JA/syntax/05_builtin_funcs.md +++ b/doc/JA/syntax/05_builtin_funcs.md @@ -1,5 +1,7 @@ # 組み込み関数 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/05_builtin_funcs.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/05_builtin_funcs.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## if `if`は条件に応じて処理を変える関数です。 diff --git a/doc/JA/syntax/06_operator.md b/doc/JA/syntax/06_operator.md index f2e1e1de..13b612ae 100644 --- a/doc/JA/syntax/06_operator.md +++ b/doc/JA/syntax/06_operator.md @@ -1,5 +1,7 @@ # 演算子 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/06_operator.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/06_operator.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 演算子(オペレーター)は、演算を表す記号です。被演算子(オペランド)は演算子の(左)右にあるもので、Ergでは専らオブジェクトです。 演算子は関数の一種であり、したがってそれ自体も第一級オブジェクトで変数に束縛できます。束縛の際は``で囲む必要があります。 diff --git a/doc/JA/syntax/07_side_effect.md b/doc/JA/syntax/07_side_effect.md index ab542b48..2aa258c3 100644 --- a/doc/JA/syntax/07_side_effect.md +++ b/doc/JA/syntax/07_side_effect.md @@ -1,5 +1,7 @@ # 副作用とプロシージャ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/07_side_effect.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/07_side_effect.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + これまで`print!`の`!`の意味を説明せずにいましたが、いよいよその意味が明かされます。この!は、ズバリこのオブジェクトが「副作用」のある「プロシージャ」であることを示しています。プロシージャは関数に「副作用」という効果を与えたものです。 ```erg diff --git a/doc/JA/syntax/08_procedure.md b/doc/JA/syntax/08_procedure.md index 1cda8f4f..f3f649e7 100644 --- a/doc/JA/syntax/08_procedure.md +++ b/doc/JA/syntax/08_procedure.md @@ -1,5 +1,7 @@ # プロシージャ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/08_procedure.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/08_procedure.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + プロシージャは可変オブジェクトを取り扱う際に必要となりますが、可変オブジェクトを引数に持てばプロシージャであるとは限りません。 ```erg diff --git a/doc/JA/syntax/09_builtin_procs.md b/doc/JA/syntax/09_builtin_procs.md index 95dbdf96..12561eb0 100644 --- a/doc/JA/syntax/09_builtin_procs.md +++ b/doc/JA/syntax/09_builtin_procs.md @@ -1,5 +1,7 @@ # 組み込みプロシージャ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/09_builtin_procs.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/09_builtin_procs.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## id! オブジェクトのユニークな識別番号を返します。 diff --git a/doc/JA/syntax/10_array.md b/doc/JA/syntax/10_array.md index d8d16bb2..f605ea5a 100644 --- a/doc/JA/syntax/10_array.md +++ b/doc/JA/syntax/10_array.md @@ -1,5 +1,7 @@ # 配列 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/10_array.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/10_array.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 配列はもっとも基本的な __コレクション(集約)__ です。 コレクションとは、内部にオブジェクトを複数保持できるオブジェクトのことです。 diff --git a/doc/JA/syntax/11_tuple.md b/doc/JA/syntax/11_tuple.md index 3523e6a0..45b91beb 100644 --- a/doc/JA/syntax/11_tuple.md +++ b/doc/JA/syntax/11_tuple.md @@ -1,5 +1,7 @@ # タプル +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/11_tuple.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/11_tuple.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + タプルは配列と似ていますが、違う型のオブジェクトを保持できます。 このようなコレクションを非等質なコレクションと呼びます。対して等質なコレクションには配列、セットなどがあります。 diff --git a/doc/JA/syntax/12_dict.md b/doc/JA/syntax/12_dict.md index d921c6f2..92e0c303 100644 --- a/doc/JA/syntax/12_dict.md +++ b/doc/JA/syntax/12_dict.md @@ -1,5 +1,7 @@ # Dict +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/12_dict.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/12_dict.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Dictはキーと値のペアを持つコレクションです。 ```erg diff --git a/doc/JA/syntax/13_record.md b/doc/JA/syntax/13_record.md index 2ab07f4a..1aeb150b 100644 --- a/doc/JA/syntax/13_record.md +++ b/doc/JA/syntax/13_record.md @@ -1,5 +1,7 @@ # レコード +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/13_record.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/13_record.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + レコードは、キーでアクセスするDictとコンパイル時にアクセスが検査されるタプルの性質を併せ持つコレクションです。 JavaScriptをやったことがある方ならば、オブジェクトリテラル記法の(より強化された)ようなものと考えてください。 diff --git a/doc/JA/syntax/14_set.md b/doc/JA/syntax/14_set.md index 3dd485cc..467bed01 100644 --- a/doc/JA/syntax/14_set.md +++ b/doc/JA/syntax/14_set.md @@ -1,5 +1,7 @@ # セット(Set) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/14_set.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/14_set.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + セットは集合を表し、データ構造的には重複、順序のない配列です。 ```erg diff --git a/doc/JA/syntax/15_type.md b/doc/JA/syntax/15_type.md index 840b24fc..40df551e 100644 --- a/doc/JA/syntax/15_type.md +++ b/doc/JA/syntax/15_type.md @@ -1,5 +1,7 @@ # 型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/15_type.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/15_type.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 型はErgにおいて非常に重要な機能ですので、[専用のセクション](./type/01_type_system.md)を用意しています。そちらをご覧ください。

diff --git a/doc/JA/syntax/16_iterator.md b/doc/JA/syntax/16_iterator.md index 2800a5ae..dbc3beb7 100644 --- a/doc/JA/syntax/16_iterator.md +++ b/doc/JA/syntax/16_iterator.md @@ -1,5 +1,7 @@ # イテレータ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/16_iterator.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/16_iterator.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + イテレータは、コンテナの要素を取り出すためのオブジェクトです。 ```erg diff --git a/doc/JA/syntax/17_mutability.md b/doc/JA/syntax/17_mutability.md index 901fdd7c..fa0f76db 100644 --- a/doc/JA/syntax/17_mutability.md +++ b/doc/JA/syntax/17_mutability.md @@ -1,5 +1,7 @@ # Mutability +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/17_mutability.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/17_mutability.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + すでに見たように、Ergの変数は全て不変です。しかし、Ergのオブジェクトには可変性という概念があります。 以下のコードを例にします。 diff --git a/doc/JA/syntax/18_ownership.md b/doc/JA/syntax/18_ownership.md index 34e7be1c..b3a90356 100644 --- a/doc/JA/syntax/18_ownership.md +++ b/doc/JA/syntax/18_ownership.md @@ -1,5 +1,7 @@ # 所有権システム +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/18_ownership.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/18_ownership.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ErgはPythonをホスト言語にした言語であるため、メモリ管理の方法はPythonの処理系に依存しています。 しかし、意味論的にはErgのメモリ管理はPythonのそれとは別物です。顕著な違いは、所有権システムと循環参照の禁止に現れています。 diff --git a/doc/JA/syntax/19_visibility.md b/doc/JA/syntax/19_visibility.md index e28163df..79d3ea30 100644 --- a/doc/JA/syntax/19_visibility.md +++ b/doc/JA/syntax/19_visibility.md @@ -1,5 +1,7 @@ # 可視性(Visibility) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/19_visibility.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/19_visibility.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Ergの変数には __可視性__ という概念が存在します。 今まで見てきた変数は全て __プライベート変数(非公開変数)__ と呼ばれます。これは、外部から不可視の変数です。 例えば`foo`モジュールで定義したプライベート変数は、別のモジュールから参照できないのです。 diff --git a/doc/JA/syntax/20_naming_rule.md b/doc/JA/syntax/20_naming_rule.md index 82c33236..61b0aa3b 100644 --- a/doc/JA/syntax/20_naming_rule.md +++ b/doc/JA/syntax/20_naming_rule.md @@ -1,5 +1,7 @@ # 命名規則 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/20_naming_rule.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/20_naming_rule.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 変数を定数式として使いたい場合は、必ず大文字で始めます。二文字以降は小文字でもよいです。 ```erg diff --git a/doc/JA/syntax/21_lambda.md b/doc/JA/syntax/21_lambda.md index f99d9c25..0a947f4e 100644 --- a/doc/JA/syntax/21_lambda.md +++ b/doc/JA/syntax/21_lambda.md @@ -1,5 +1,7 @@ # 無名関数(anonymous function) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/21_lambda.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/21_lambda.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 無名関数は、関数オブジェクトを名付けずその場で生成するための文法です。 ```erg diff --git a/doc/JA/syntax/22_subroutine.md b/doc/JA/syntax/22_subroutine.md index b13a57d4..03345e9e 100644 --- a/doc/JA/syntax/22_subroutine.md +++ b/doc/JA/syntax/22_subroutine.md @@ -1,5 +1,7 @@ # Subroutine signatures +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/22_subroutine.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/22_subroutine.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## Func ```erg diff --git a/doc/JA/syntax/23_closure.md b/doc/JA/syntax/23_closure.md index 5d0408a6..621e3138 100644 --- a/doc/JA/syntax/23_closure.md +++ b/doc/JA/syntax/23_closure.md @@ -1,5 +1,7 @@ # クロージャ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/23_closure.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/23_closure.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Ergのサブルーチンには、外部変数を捕捉する「クロージャ」という機能があります。 ```erg diff --git a/doc/JA/syntax/24_module.md b/doc/JA/syntax/24_module.md index 9fc334f4..d51a0fc4 100644 --- a/doc/JA/syntax/24_module.md +++ b/doc/JA/syntax/24_module.md @@ -1,5 +1,7 @@ # モジュール +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/24_module.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/24_module.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Ergでは、ファイル自体を1つのレコードとみなすことができます。これをモジュールと呼びます。 ```erg: foo.er diff --git a/doc/JA/syntax/25_object_system.md b/doc/JA/syntax/25_object_system.md index b2a840e8..8c31c7ec 100644 --- a/doc/JA/syntax/25_object_system.md +++ b/doc/JA/syntax/25_object_system.md @@ -1,5 +1,7 @@ # Object(対象体) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/25_object_system.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/25_object_system.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 変数に代入できる全てのデータです。`Object`クラスの持つ属性は以下の通りです。 * `.__repr__`: オブジェクトの(リッチでない)文字列表現を返します diff --git a/doc/JA/syntax/26_pattern_matching.md b/doc/JA/syntax/26_pattern_matching.md index c86cc43f..fcca06cb 100644 --- a/doc/JA/syntax/26_pattern_matching.md +++ b/doc/JA/syntax/26_pattern_matching.md @@ -1,5 +1,7 @@ # パターンマッチ、論駁可能性 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/26_pattern_matching.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/26_pattern_matching.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## Ergで使用可能なパターン ### 変数パターン diff --git a/doc/JA/syntax/27_comprehension.md b/doc/JA/syntax/27_comprehension.md index 4448dfed..4f763522 100644 --- a/doc/JA/syntax/27_comprehension.md +++ b/doc/JA/syntax/27_comprehension.md @@ -1,5 +1,7 @@ # Comprehension(内包表記) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/27_comprehension.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/27_comprehension.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + `[expr | (name <- iterable)+ (predicate)*]`で配列、 `{expr | (name <- iterable)+ (predicate)*}`でセット、 `{key: value | (name <- iterable)+ (predicate)*}`でDictが作れます。 diff --git a/doc/JA/syntax/28_spread_syntax.md b/doc/JA/syntax/28_spread_syntax.md index 52c2c658..1dd6518e 100644 --- a/doc/JA/syntax/28_spread_syntax.md +++ b/doc/JA/syntax/28_spread_syntax.md @@ -1,5 +1,7 @@ # Spread assignment (展開代入) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/28_spread_syntax.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/28_spread_syntax.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 分解代入において、変数の前に`...`を置くと残りの要素を全てその変数に展開できます。これを展開代入と呼びます。 ```erg diff --git a/doc/JA/syntax/29_decorator.md b/doc/JA/syntax/29_decorator.md index 90fd1587..6e137b10 100644 --- a/doc/JA/syntax/29_decorator.md +++ b/doc/JA/syntax/29_decorator.md @@ -1,5 +1,7 @@ # デコレータ(修飾子) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/29_decorator.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/29_decorator.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + デコレータは型や関数に特定の状態や振る舞いを追加したり明示するために使われます。 デコレータの文法は以下の通りです。 diff --git a/doc/JA/syntax/30_error_handling.md b/doc/JA/syntax/30_error_handling.md index 841296fa..37213e51 100644 --- a/doc/JA/syntax/30_error_handling.md +++ b/doc/JA/syntax/30_error_handling.md @@ -1,5 +1,7 @@ # エラーハンドリングシステム +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/30_error_handling.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/30_error_handling.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 主にResult型を使用します。 ErgではError型オブジェクトを捨てる(トップレベルで対応しない)とエラーが発生します。 diff --git a/doc/JA/syntax/31_pipeline.md b/doc/JA/syntax/31_pipeline.md index f4b708cd..6910d321 100644 --- a/doc/JA/syntax/31_pipeline.md +++ b/doc/JA/syntax/31_pipeline.md @@ -1,5 +1,7 @@ # パイプライン演算子 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/31_pipeline.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/31_pipeline.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + パイプライン演算子は、次のように使います。 ```erg diff --git a/doc/JA/syntax/32_integration_with_Python.md b/doc/JA/syntax/32_integration_with_Python.md index 3d3b388a..3809a8db 100644 --- a/doc/JA/syntax/32_integration_with_Python.md +++ b/doc/JA/syntax/32_integration_with_Python.md @@ -1,5 +1,7 @@ # Pythonとの連携 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/32_integration_with_Python.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/32_integration_with_Python.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## Pythonへのexport Ergスクリプトをコンパイルすると.pycファイルが生成されますが、これは単純にPythonのモジュールとして読み込むことができます。 diff --git a/doc/JA/syntax/33_package_system.md b/doc/JA/syntax/33_package_system.md index 8ae76114..6b277ecf 100644 --- a/doc/JA/syntax/33_package_system.md +++ b/doc/JA/syntax/33_package_system.md @@ -1,5 +1,7 @@ # パッケージシステム +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/33_package_system.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/33_package_system.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Ergのパッケージはアプリケーションであるappパッケージとライブラリであるlibパッケージに大別できます。 appパッケージのエントリポイントは`src/app.er`です。`app.er`内に定義された`main`関数が実行されます。 libパッケージのエントリポイントは`src/lib.er`です。パッケージをインポートすることは`lib.er`をインポートすることと等価になります。 diff --git a/doc/JA/syntax/34_generator.md b/doc/JA/syntax/34_generator.md index eee9b31c..366f839d 100644 --- a/doc/JA/syntax/34_generator.md +++ b/doc/JA/syntax/34_generator.md @@ -1,5 +1,7 @@ # ジェネレータ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/34_generator.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/34_generator.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ジェネレータは、ブロック中で`yield!`プロシージャを使う特殊なプロシージャです。 ```erg diff --git a/doc/JA/syntax/SUMMARY.md b/doc/JA/syntax/SUMMARY.md index 774c354b..de5dfd3d 100644 --- a/doc/JA/syntax/SUMMARY.md +++ b/doc/JA/syntax/SUMMARY.md @@ -1,5 +1,7 @@ # Summary +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/SUMMARY.md%26commit_hash%3D2ce482b1c8407332b3b74f4c3e5596f373f9a657)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/SUMMARY.md&commit_hash=2ce482b1c8407332b3b74f4c3e5596f373f9a657) + - [Basics](./00_basic.md) - [Literal](./01_literal.md) - [Name](02_name.md) diff --git a/doc/JA/syntax/container_ownership.md b/doc/JA/syntax/container_ownership.md index f48b4aa3..6e58f3ca 100644 --- a/doc/JA/syntax/container_ownership.md +++ b/doc/JA/syntax/container_ownership.md @@ -1,5 +1,7 @@ # Subscript(添字アクセス) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/34_generator.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/34_generator.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + `[]`は通常のメソッドとは異なっています。 ```erg diff --git a/doc/JA/syntax/indexes.md b/doc/JA/syntax/indexes.md index 0db44b64..748cc676 100644 --- a/doc/JA/syntax/indexes.md +++ b/doc/JA/syntax/indexes.md @@ -1,5 +1,7 @@ # 索引 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/indexes.md%26commit_hash%3D592671af96ff3f517746841e55b8bc835b39af3a)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/indexes.md&commit_hash=592671af96ff3f517746841e55b8bc835b39af3a) + この索引にないAPIについては[こちら](../API/index.md)を参照してください。 用語の意味については[こちら](../dev_guide/terms.md)を参照。 diff --git a/doc/JA/syntax/quick_tour.md b/doc/JA/syntax/quick_tour.md index 66ddbdd3..0789e141 100644 --- a/doc/JA/syntax/quick_tour.md +++ b/doc/JA/syntax/quick_tour.md @@ -1,5 +1,7 @@ # Quick Tour +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/34_generator.md%26commit_hash%3D7d43acdf0e2b71528b038b9a8e70be6c93831f96)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/quick_tour.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96) + `syntax`以下のドキュメントは、概ねプログラミング初心者でも理解できることを目指して書かれています。 すでにPythonやRust, Haskellなどの言語を習得されている方にとっては、少し冗長であるかもしれません。 diff --git a/doc/JA/syntax/type/01_type_system.md b/doc/JA/syntax/type/01_type_system.md index f8c07359..cb8a9ed3 100644 --- a/doc/JA/syntax/type/01_type_system.md +++ b/doc/JA/syntax/type/01_type_system.md @@ -1,5 +1,7 @@ # Ergの型システム +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/01_type_system.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/01_type_system.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 以下では、Ergの型システムを概略的に説明します。詳細については他の項で解説します。 ## 定義方法 diff --git a/doc/JA/syntax/type/02_basic.md b/doc/JA/syntax/type/02_basic.md index 922b5a35..7f04a45e 100644 --- a/doc/JA/syntax/type/02_basic.md +++ b/doc/JA/syntax/type/02_basic.md @@ -1,5 +1,7 @@ # 型に関する基本的な文法 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/02_basic.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/02_basic.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## 型指定 Ergでは以下のように`:`の後に変数の型を指定します。代入と同時に行うこともできます。 diff --git a/doc/JA/syntax/type/03_trait.md b/doc/JA/syntax/type/03_trait.md index 5b234c07..949c6b90 100644 --- a/doc/JA/syntax/type/03_trait.md +++ b/doc/JA/syntax/type/03_trait.md @@ -1,5 +1,7 @@ # トレイト +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/03_trait.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/03_trait.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + トレイトは、レコード型に型属性の要求を追加した記名型です。 Pythonでいう抽象基底クラス(Abstract Base Class, ABC)に類似しますが、代数的演算を行えるという特徴があります。 diff --git a/doc/JA/syntax/type/04_class.md b/doc/JA/syntax/type/04_class.md index b0f2ea05..4edb9fe8 100644 --- a/doc/JA/syntax/type/04_class.md +++ b/doc/JA/syntax/type/04_class.md @@ -1,5 +1,7 @@ # Class +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/04_class.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/04_class.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Ergにおけるクラスは、大まかには自身の要素(インスタンス)を生成できる型と言えます。 以下は単純なクラスの例です。 diff --git a/doc/JA/syntax/type/05_inheritance.md b/doc/JA/syntax/type/05_inheritance.md index 82c2c6b8..e48ea9e9 100644 --- a/doc/JA/syntax/type/05_inheritance.md +++ b/doc/JA/syntax/type/05_inheritance.md @@ -1,5 +1,7 @@ # 継承(Inheritance) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/05_inheritance.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/05_inheritance.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 継承を使うと、既存のクラスに機能を加えたり特化したりした新しいクラスを定義できます。 継承はトレイトにおける包摂に似ています。継承してできたクラスは、もとのクラスのサブタイプになります。 diff --git a/doc/JA/syntax/type/06_nst_vs_sst.md b/doc/JA/syntax/type/06_nst_vs_sst.md index 4884f630..531bdeff 100644 --- a/doc/JA/syntax/type/06_nst_vs_sst.md +++ b/doc/JA/syntax/type/06_nst_vs_sst.md @@ -1,5 +1,7 @@ # 記名的部分型 vs. 構造的部分型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/06_nst_vs_sst.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/06_nst_vs_sst.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ```erg Months = 0..12 diff --git a/doc/JA/syntax/type/07_patch.md b/doc/JA/syntax/type/07_patch.md index f79c7f53..93044b91 100644 --- a/doc/JA/syntax/type/07_patch.md +++ b/doc/JA/syntax/type/07_patch.md @@ -1,5 +1,7 @@ # Patch +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/07_patch.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/07_patch.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Ergでは、既存の型・クラスに手を加えることはできません。 クラスにメソッドを追加で定義することはできず、特殊化(specialization, 多相に宣言された型を単相化し専用のメソッドを定義する機能。C++などが持つ)も行えません。 しかし、既存の型・クラスに機能を追加したいという状況は多々あり、これを実現するためにパッチという機能があります。 diff --git a/doc/JA/syntax/type/08_value.md b/doc/JA/syntax/type/08_value.md index 2e2fb77c..e8460dc0 100644 --- a/doc/JA/syntax/type/08_value.md +++ b/doc/JA/syntax/type/08_value.md @@ -1,5 +1,7 @@ # 値型(Value types) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/08_value.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/08_value.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 値型はErg組み込み型のうちコンパイル時評価が可能な型で、具体的には以下のものです。 ```erg diff --git a/doc/JA/syntax/type/09_attributive.md b/doc/JA/syntax/type/09_attributive.md index 96dce87e..b57a8f09 100644 --- a/doc/JA/syntax/type/09_attributive.md +++ b/doc/JA/syntax/type/09_attributive.md @@ -1,5 +1,7 @@ # 属性型(Attributive Type) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/09_attributive.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/09_attributive.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 属性型は、レコードおよびデータクラス、パッチ、モジュールなどが含まれる型です。 属性型に属する型は値型ではありません。 diff --git a/doc/JA/syntax/type/10_interval.md b/doc/JA/syntax/type/10_interval.md index 38d308ba..db263edb 100644 --- a/doc/JA/syntax/type/10_interval.md +++ b/doc/JA/syntax/type/10_interval.md @@ -1,5 +1,7 @@ # Interval Type +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/10_interval.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/10_interval.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + `Range`オブジェクトの最も基本的な使い方は、イテレータとしての使用です。 ```erg diff --git a/doc/JA/syntax/type/11_enum.md b/doc/JA/syntax/type/11_enum.md index bb040c5d..c3784ee0 100644 --- a/doc/JA/syntax/type/11_enum.md +++ b/doc/JA/syntax/type/11_enum.md @@ -1,5 +1,7 @@ # Enumerative Type(列挙型) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/11_enum.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/11_enum.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 列挙型(Enum type)はSetによって生成されます。 列挙型はそのままでも型指定で使えますが、クラス化したりパッチを定義することで更にメソッドを定義できます。 列挙型による部分型システムを列挙的部分型付けといいます。 diff --git a/doc/JA/syntax/type/12_refinement.md b/doc/JA/syntax/type/12_refinement.md index f87decec..e7b8c6db 100644 --- a/doc/JA/syntax/type/12_refinement.md +++ b/doc/JA/syntax/type/12_refinement.md @@ -1,5 +1,7 @@ # 篩型(Refinement Type) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/12_refinement.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/12_refinement.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Refinement type(篩型、ふるいがた)は、述語式によって制約付けられた型です。列挙型や区間型は篩型の一種です。 篩型の標準形は`{Elem: Type | (Pred)*}`です。これは、`Pred`を満たす`Elem`を要素とする型である、という意味です。 diff --git a/doc/JA/syntax/type/13_algebraic.md b/doc/JA/syntax/type/13_algebraic.md index 99246287..3713ef14 100644 --- a/doc/JA/syntax/type/13_algebraic.md +++ b/doc/JA/syntax/type/13_algebraic.md @@ -1,5 +1,7 @@ # Algebraic type (代数演算型) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/13_algebraic.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/13_algebraic.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 代数演算型は、型を代数のようにみなして演算することで生成される型のことです。 代数演算型が扱う演算は、Union, Intersection, Diff, Complementなどがあります。 通常のクラスはUnionのみが行えて、他の演算は型エラーになります。 diff --git a/doc/JA/syntax/type/14_dependent.md b/doc/JA/syntax/type/14_dependent.md index 754ae782..c3d064b9 100644 --- a/doc/JA/syntax/type/14_dependent.md +++ b/doc/JA/syntax/type/14_dependent.md @@ -1,5 +1,7 @@ # 依存型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/14_dependent.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/14_dependent.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 依存型はErgの最大の特徴とも言っても良い機能です。 依存型とは、値を引数に取る型です。通常の多相型は型のみを引数に取れますが、その制限を緩めたのが依存型といえます。 diff --git a/doc/JA/syntax/type/15_quantified.md b/doc/JA/syntax/type/15_quantified.md index 86bb9c6f..0e8acbc0 100644 --- a/doc/JA/syntax/type/15_quantified.md +++ b/doc/JA/syntax/type/15_quantified.md @@ -1,5 +1,7 @@ # 型変数(Type Variable)、量化型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/15_quantified.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/15_quantified.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 型変数はサブルーチン引数の型指定などに使用する変数で、その型が任意である(単相化しない)ことを示します。 まず、型変数を導入するモチベーションとして、入力をそのまま返す`id`関数について考えましょう。 diff --git a/doc/JA/syntax/type/16_subtyping.md b/doc/JA/syntax/type/16_subtyping.md index d7f33f84..c206533e 100644 --- a/doc/JA/syntax/type/16_subtyping.md +++ b/doc/JA/syntax/type/16_subtyping.md @@ -1,5 +1,7 @@ # 部分型付け +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/16_subtyping.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/16_subtyping.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Ergでは、クラス同士の包含関係は比較演算子`<`, `>`で判定可能です。 ```erg diff --git a/doc/JA/syntax/type/17_type_casting.md b/doc/JA/syntax/type/17_type_casting.md index 44cd1363..39a3c49c 100644 --- a/doc/JA/syntax/type/17_type_casting.md +++ b/doc/JA/syntax/type/17_type_casting.md @@ -1,5 +1,7 @@ # キャスト +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/17_type_casting.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/17_type_casting.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## アップキャスト Pythonはダックタイピングを採用する言語のため、キャストという概念はありません。アップキャストはする必要がなく、ダウンキャストも基本的にはありません。 diff --git a/doc/JA/syntax/type/18_mut.md b/doc/JA/syntax/type/18_mut.md index ec232cab..99adcb69 100644 --- a/doc/JA/syntax/type/18_mut.md +++ b/doc/JA/syntax/type/18_mut.md @@ -1,5 +1,7 @@ # 可変型(Mutable Type) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/18_mut.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/18_mut.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + > __Warning__: この項の情報は古く、一部に間違いを含みます。 Ergではデフォルトですべての型が不変型、すなわち内部状態を更新できないようになっています。 diff --git a/doc/JA/syntax/type/19_bound.md b/doc/JA/syntax/type/19_bound.md index 3024ebc8..fcab834b 100644 --- a/doc/JA/syntax/type/19_bound.md +++ b/doc/JA/syntax/type/19_bound.md @@ -1,5 +1,7 @@ # 型境界 (Type Bound) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/19_bound.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/19_bound.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 型境界は型指定に条件を加えるものである。これを実現する機能がガード(ガード節)である。 関数シグニチャ、無名関数シグニチャのほか、篩型でもこの機能を利用できる。 ガードは戻り値型の後に記述する。 diff --git a/doc/JA/syntax/type/advanced.md b/doc/JA/syntax/type/advanced.md index 57fa0935..38ee588e 100644 --- a/doc/JA/syntax/type/advanced.md +++ b/doc/JA/syntax/type/advanced.md @@ -1 +1,3 @@ 以降は更に高度な型システムを解説します。入門者の方はすべての項を読まなくても問題ありません。 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + diff --git a/doc/JA/syntax/type/advanced/GADTs.md b/doc/JA/syntax/type/advanced/GADTs.md index 2b8a8a7d..b8f2cba0 100644 --- a/doc/JA/syntax/type/advanced/GADTs.md +++ b/doc/JA/syntax/type/advanced/GADTs.md @@ -1,5 +1,7 @@ # 一般化代数的データ型(Generalized Algebraic Data Types, GADTs) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/GADTs.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/GADTs.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ErgはOr型をクラス化することで一般化代数的データ型(GADTs)を作成出来ます。 ```erg diff --git a/doc/JA/syntax/type/advanced/default_param.md b/doc/JA/syntax/type/advanced/default_param.md index e183cd97..95cd06dc 100644 --- a/doc/JA/syntax/type/advanced/default_param.md +++ b/doc/JA/syntax/type/advanced/default_param.md @@ -1,5 +1,7 @@ # デフォルト引数付きの関数型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/default_param.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/default_param.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + まず、デフォルト引数の使用例を見る。 ```erg diff --git a/doc/JA/syntax/type/advanced/erasure.md b/doc/JA/syntax/type/advanced/erasure.md index 08c0c66c..d3dc24a8 100644 --- a/doc/JA/syntax/type/advanced/erasure.md +++ b/doc/JA/syntax/type/advanced/erasure.md @@ -1,5 +1,7 @@ # 型消去(Type erasure) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/erasure.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/erasure.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 型消去とは、型引数に`_`を指定し、その情報をあえて捨てることです。型消去は多相型を持つ言語の多くが併せて持つ機能ですが、Ergの文法に即して言えば型引数消去といった方が正確でしょう。 もっともよく見られる型消去された型の例は`[T, _]`でしょう。配列はコンパイル時にその長さが分からない場合もあります。例えば、コマンドライン引数を指す`sys.argv`は`[Str, _]`型です。コマンドライン引数の長さをErgのコンパイラは知りようがないため、長さに関する情報は諦めなくてはならないのです。 diff --git a/doc/JA/syntax/type/advanced/existential.md b/doc/JA/syntax/type/advanced/existential.md index 4e433516..ca889d7a 100644 --- a/doc/JA/syntax/type/advanced/existential.md +++ b/doc/JA/syntax/type/advanced/existential.md @@ -1,5 +1,7 @@ # 存在型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/existential.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/existential.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ∀に対応する全称型があるならば、∃に対応する存在型があると考えるのが自然です。 存在型は難しいものではありません。そうと意識していないだけで、既にあなたは存在型を知っています。 diff --git a/doc/JA/syntax/type/advanced/keyword_param.md b/doc/JA/syntax/type/advanced/keyword_param.md index bc2ea537..1f36f639 100644 --- a/doc/JA/syntax/type/advanced/keyword_param.md +++ b/doc/JA/syntax/type/advanced/keyword_param.md @@ -1,5 +1,7 @@ # キーワード引数付き関数型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/keyword_param.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/keyword_param.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ```erg h(f) = f(y: 1, x: 2) h: |T: Type|((y: Int, x: Int) -> T) -> T diff --git a/doc/JA/syntax/type/advanced/kind.md b/doc/JA/syntax/type/advanced/kind.md index 38399fca..fbc01124 100644 --- a/doc/JA/syntax/type/advanced/kind.md +++ b/doc/JA/syntax/type/advanced/kind.md @@ -1,5 +1,7 @@ # カインド(Kind) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/kind.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/kind.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Ergでは全てが型付けられている。型自体も例外ではない。「型の型」を表すのが __カインド(種)__ である。例えば`1`が`Int`に属しているように、`Int`は`Type`に属している。`Type`は最もシンプルなカインドである __原子カインド(Atomic kind)__ である。型理論的の記法では、`Type`は`*`に対応する。 カインドという概念で実用上重要なのは1項以上のカインド(多項カインド)である。1項のカインドは、例えば`Option`などがそれに属する。1項カインドは`Type -> Type`と表される[1](#1)。`Array`や`Option`などの __コンテナ__ は特に型を引数に取る多項カインドのことなのである。 diff --git a/doc/JA/syntax/type/advanced/marker_trait.md b/doc/JA/syntax/type/advanced/marker_trait.md index be11716b..480cb0d4 100644 --- a/doc/JA/syntax/type/advanced/marker_trait.md +++ b/doc/JA/syntax/type/advanced/marker_trait.md @@ -1,5 +1,7 @@ # Marker Trait +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/marker_trait.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/marker_trait.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + マーカートレイトは、要求属性のないトレイトである。すなわち、メソッドを実装せずにImplすることができる。 要求属性がないと意味がないように思えるが、そのトレイトに属しているという情報が登録されるので、パッチメソッドを使ったり、コンパイラが特別扱いしたりできる。 diff --git a/doc/JA/syntax/type/advanced/mut_struct.md b/doc/JA/syntax/type/advanced/mut_struct.md index d1efe69b..e9b2d6ca 100644 --- a/doc/JA/syntax/type/advanced/mut_struct.md +++ b/doc/JA/syntax/type/advanced/mut_struct.md @@ -1,5 +1,7 @@ # 可変構造型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/mut_struct.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/mut_struct.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + `T!`型は任意の`T`型オブジェクトを入れられて差し替え可能なボックス型であると説明した。 ```erg diff --git a/doc/JA/syntax/type/advanced/newtype.md b/doc/JA/syntax/type/advanced/newtype.md index 6859b904..ed839cd4 100644 --- a/doc/JA/syntax/type/advanced/newtype.md +++ b/doc/JA/syntax/type/advanced/newtype.md @@ -1,5 +1,7 @@ # Newtype pattern +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/newtype.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/newtype.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ここでは、Rustでよく使われるnewtypeパターンのErg版を紹介します。 Ergはでは以下のように型のエイリアスを定義できますが、これはあくまで同じ型を指します。 diff --git a/doc/JA/syntax/type/advanced/overloading.md b/doc/JA/syntax/type/advanced/overloading.md index af0633ac..a7d1e3d3 100644 --- a/doc/JA/syntax/type/advanced/overloading.md +++ b/doc/JA/syntax/type/advanced/overloading.md @@ -1,5 +1,7 @@ # オーバーロード +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/overloading.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/overloading.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Ergでは __アドホック多相__ をサポートしない。すなわち、関数・カインドの多重定義(オーバーロード)ができない。が、トレイトクラスとパッチを組み合わせることでオーバーロードの挙動を再現できる。 トレイトクラスのかわりにトレイトを使用しても良いが、その場合`.add1`を実装している型全てが対象になってしまう。 diff --git a/doc/JA/syntax/type/advanced/phantom.md b/doc/JA/syntax/type/advanced/phantom.md index 6933bdf9..2a5f645d 100644 --- a/doc/JA/syntax/type/advanced/phantom.md +++ b/doc/JA/syntax/type/advanced/phantom.md @@ -1,5 +1,7 @@ # 幽霊型(Phantom class) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/phantom.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/phantom.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 幽霊型は、コンパイラに注釈を与えるためだけに存在するマーカートレイトである。 幽霊型の使い方として、リストの構成をみる。 diff --git a/doc/JA/syntax/type/advanced/projection.md b/doc/JA/syntax/type/advanced/projection.md index 404edff6..6618b02c 100644 --- a/doc/JA/syntax/type/advanced/projection.md +++ b/doc/JA/syntax/type/advanced/projection.md @@ -1,5 +1,7 @@ # Projection Type(射影型) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/projection.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/projection.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 射影型は、次のコードにおける`Self.AddO`のような型を表します。 ```erg diff --git a/doc/JA/syntax/type/advanced/quantified_dependent.md b/doc/JA/syntax/type/advanced/quantified_dependent.md index b778acf3..bbfccdc4 100644 --- a/doc/JA/syntax/type/advanced/quantified_dependent.md +++ b/doc/JA/syntax/type/advanced/quantified_dependent.md @@ -1,5 +1,7 @@ # 量化依存型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/quantified_dependent.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/quantified_dependent.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + Ergには量化型、依存型が存在します。すると当然、その二つを組み合わせた型を作ることができます。それが量化依存型です。 ```erg diff --git a/doc/JA/syntax/type/advanced/shared.md b/doc/JA/syntax/type/advanced/shared.md index ea2a8700..3f7624cc 100644 --- a/doc/JA/syntax/type/advanced/shared.md +++ b/doc/JA/syntax/type/advanced/shared.md @@ -1,5 +1,7 @@ # 共有参照(Shared Reference) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/shared.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/shared.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 共有参照は気をつけて扱わねばならない言語機能の一つです。 例えばTypeScriptでは以下のようなコードが型検査を通ってしまいます。 diff --git a/doc/JA/syntax/type/advanced/special.md b/doc/JA/syntax/type/advanced/special.md index 482ad174..6b3b423d 100644 --- a/doc/JA/syntax/type/advanced/special.md +++ b/doc/JA/syntax/type/advanced/special.md @@ -1,5 +1,7 @@ # 特殊型(Self, Super) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/special.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/special.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + `Self`は自身の型を表します。単にエイリアスとして使うことも出来ますが、派生型中では意味が変わる(自身の型を指す)ので注意してください。 ```erg diff --git a/doc/JA/tips.md b/doc/JA/tips.md index 85c326fd..5e185cc3 100644 --- a/doc/JA/tips.md +++ b/doc/JA/tips.md @@ -1,5 +1,7 @@ # Tips +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tips.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tips.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## エラーの表示言語を変えたい 各国語版のergをダウンロードしてください。 From 5ac1d4c9dd895118883aa8737b9f903bfe4f9b4c Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 14:00:50 +0800 Subject: [PATCH 12/42] python floder doc zh_CN translate --- doc/zh_CN/API/modules/external/alstruct.md | 4 +- doc/zh_CN/API/modules/unit.md | 24 +++--- doc/zh_CN/API/procs.md | 6 +- doc/zh_CN/API/special.md | 4 +- doc/zh_CN/API/types.md | 42 +++++----- doc/zh_CN/API/types/classes/Dict!.md | 2 +- doc/zh_CN/API/types/classes/Float.md | 6 +- doc/zh_CN/API/types/classes/Int.md | 2 +- doc/zh_CN/API/types/classes/Interval.md | 2 +- doc/zh_CN/API/types/classes/Never.md | 2 +- doc/zh_CN/API/types/classes/Pos.md | 2 +- doc/zh_CN/API/types/classes/Str.md | 4 +- doc/zh_CN/API/types/classes/Tuple.md | 2 +- doc/zh_CN/compiler/TODO_hint.md | 6 +- doc/zh_CN/compiler/TODO_recov_suggest.md | 2 +- doc/zh_CN/compiler/TODO_warn.md | 6 +- doc/zh_CN/compiler/abandoned.md | 2 +- doc/zh_CN/compiler/architecture.md | 16 ++-- doc/zh_CN/compiler/errors.md | 8 +- doc/zh_CN/compiler/hir.md | 2 +- doc/zh_CN/compiler/inference.md | 42 +++++----- doc/zh_CN/compiler/overview.md | 4 +- doc/zh_CN/compiler/parsing.md | 2 +- doc/zh_CN/compiler/refinement_subtyping.md | 4 +- doc/zh_CN/compiler/trait_method_resolving.md | 10 +-- doc/zh_CN/dev_guide/branches.md | 4 +- doc/zh_CN/dev_guide/build_features.md | 6 +- doc/zh_CN/dev_guide/doc_guideline.md | 6 +- doc/zh_CN/dev_guide/env.md | 2 +- doc/zh_CN/dev_guide/faq_syntax.md | 8 +- doc/zh_CN/dev_guide/i18n_messages.md | 10 +-- doc/zh_CN/dev_guide/rust_code_guideline.md | 6 +- doc/zh_CN/dev_guide/terms.md | 8 +- doc/zh_CN/dev_guide/unify_terms.md | 10 +-- doc/zh_CN/python/bytecode_instructions.md | 82 ++++++++++---------- doc/zh_CN/python/bytecode_specification.md | 73 +++++++++++++++++ doc/zh_CN/python/class_system.md | 38 ++++----- 37 files changed, 267 insertions(+), 192 deletions(-) diff --git a/doc/zh_CN/API/modules/external/alstruct.md b/doc/zh_CN/API/modules/external/alstruct.md index 8bdc85db..bfbf7a1b 100644 --- a/doc/zh_CN/API/modules/external/alstruct.md +++ b/doc/zh_CN/API/modules/external/alstruct.md @@ -18,7 +18,7 @@ assert Nat. ReturnTypeof(Mul) == Nat assert Nat.ReturnTypeof(Div) == Positive Ratio ``` -## 半群(一个二元运算的代数系统) +## 半群(一个二元运算的代数系统) ```python SemiGroup Op: Kind 2 = Op(Self, Self) @@ -48,7 +48,7 @@ Applicative = Subsume Functor, Additional: { } ``` -## 单子(交互式命令行工具以及面向对象的脚本技术) +## 单子(交互式命令行工具以及面向对象的脚本技术) ```python Monad = Subsume Applicative, Additional: { diff --git a/doc/zh_CN/API/modules/unit.md b/doc/zh_CN/API/modules/unit.md index d2172508..179b55f0 100644 --- a/doc/zh_CN/API/modules/unit.md +++ b/doc/zh_CN/API/modules/unit.md @@ -3,7 +3,7 @@ `unit` 模块是将数值计算中经常使用的单位定义为类型的模块。 Erg 数值类型包括 `Nat`、`Int`、`Ratio` 等。但是,这些类型没有关于“数字的含义”的信息,因此可以执行诸如添加米和码之类的无意义计算。 通过使用 `unit` 模块,您可以避免错误,例如将不同单位的数字传递给函数。 -这样的错误确实会发生,并且会导致诸如[由于错误的单位系统导致火星探测器丢失](http://www.sydrose.com/case100/287/)之类的严重错误。 +这样的错误确实会发生,并且会导致诸如[由于错误的单位系统导致火星探测器丢失](http://www.sydrose.com/case100/287/)之类的严重错误。 如果您希望代码在进行数值计算时更加健壮,您应该使用此模块。 ```python @@ -18,19 +18,19 @@ print! x + 2s # 类型错误: `+`(Meter, Sec) 未实现 ``` 对象`m`、`s`和`m/s`被称为单元对象。它本身具有1m、1s、1m/s的含义。 `m/s`可以说是结合m和s创建的单位对象。 -在单元中,以下单元被定义为类型。它被称为SI(国际单位制)。 +在单元中,以下单元被定义为类型。它被称为SI(国际单位制)。 -* 长度:Meter(单位常数:m) -* 质量:KiloGram(单位常数:kg,g = 0.001kg) -* 时间:Sec(分、时、日、年等有分、时、日、年等常量由秒生成) -* 电流:Amper(单位常数:a) -* 温度:Kelvin(单位常数:k。华氏、摄氏度类型也可用,可相互转换) -* 物质量:Mol(单位常数:mol) -* 发光强度:Candela(单位常数:cd) +* 长度:Meter(单位常数:m) +* 质量:KiloGram(单位常数:kg,g = 0.001kg) +* 时间:Sec(分、时、日、年等有分、时、日、年等常量由秒生成) +* 电流:Amper(单位常数:a) +* 温度:Kelvin(单位常数:k。华氏、摄氏度类型也可用,可相互转换) +* 物质量:Mol(单位常数:mol) +* 发光强度:Candela(单位常数:cd) 此外,还定义了`Unit1`、`UnitMul`和`UnitDiv`类型,可以通过组合基本类型来创建新的单元。 -例如`UnitDiv(Unit1, Sec)`,因为频率单位赫兹(hertz)被定义为振动周期(秒)的倒数。 -如果要将此类型视为有意义的类型(例如添加专用方法),则应创建 [patch](./../../syntax/type/07_patch.md)。 +例如`UnitDiv(Unit1, Sec)`,因为频率单位赫兹(hertz)被定义为振动周期(秒)的倒数。 +如果要将此类型视为有意义的类型(例如添加专用方法),则应创建 [patch](./../../syntax/type/07_patch.md)。 ```python Hertz = Patch UnitDiv(Unit1, Sec) @@ -69,4 +69,4 @@ SquareMeter = Patch UnitMul(Meter, Meter) * Peta = 1e+15 * Exa = 1e+18 -* 与名字的由来相反,Erg基本采用MKS单位制。如果需要 CGS 单位制的单位模块,请使用外部库[cgs](https://github.com/mtshiba/cgs)等)。 \ No newline at end of file +* 与名字的由来相反,Erg基本采用MKS单位制。如果需要 CGS 单位制的单位模块,请使用外部库[cgs](https://github.com/mtshiba/cgs)等)。 \ No newline at end of file diff --git a/doc/zh_CN/API/procs.md b/doc/zh_CN/API/procs.md index 14831c0c..e527f5fb 100644 --- a/doc/zh_CN/API/procs.md +++ b/doc/zh_CN/API/procs.md @@ -3,7 +3,7 @@ ## print! ```python -打印!(x)->无类型 +打印!(x)->无类型 ``` 使用换行符返回 x。 @@ -11,10 +11,10 @@ ## 调试&排除; ```python -调试!(x,类型=信息)-> NoneType +调试!(x,类型=信息)-> NoneType ``` -用换行符调试 x(文件名、行号、变量名一起显示)。 在发布模式中删除。 +用换行符调试 x(文件名、行号、变量名一起显示)。 在发布模式中删除。 支持表情符号的终端根据类型加前缀。 * type == Info: 💬 diff --git a/doc/zh_CN/API/special.md b/doc/zh_CN/API/special.md index 48d999e0..6de5fc48 100644 --- a/doc/zh_CN/API/special.md +++ b/doc/zh_CN/API/special.md @@ -1,6 +1,6 @@ # 特殊形式 -特殊形式是不能在 Erg 类型系统中表达的运算符、子程序(等等)。它被`包围,但实际上无法捕获。 +特殊形式是不能在 Erg 类型系统中表达的运算符、子程序(等等)。它被`包围,但实际上无法捕获。 此外,为方便起见,还出现了“Pattern”、“Body”和“Conv”等类型,但不存在此类类型。它的含义也取决于上下文。 ## `=`(pat: Pattern, body: Body) -> NoneType @@ -37,7 +37,7 @@ print! L # ```python i = j = 1 # SyntaxError: 不允许多次赋值 print!(x=1) # SyntaxError: cannot use `=` in function arguments -# 提示:您的意思是关键字参数(`x: 1`)吗? +# 提示:您的意思是关键字参数(`x: 1`)吗? if True, do: i = 0 # SyntaxError: 块不能被赋值表达式终止 ``` diff --git a/doc/zh_CN/API/types.md b/doc/zh_CN/API/types.md index 7737ec9f..68f525a0 100644 --- a/doc/zh_CN/API/types.md +++ b/doc/zh_CN/API/types.md @@ -6,15 +6,15 @@ ### 对象 -* `__dir__`:将对象的属性作为数组返回(dir函数) +* `__dir__`:将对象的属性作为数组返回(dir函数) * `__getattribute__`: 获取并返回一个属性 * `__hash__`:返回对象的哈希值 -* `__repr__`:对象的字符串表示(不存在丰富/默认实现) -* `__sizeof__`:返回对象的大小(包括在堆中分配的大小) +* `__repr__`:对象的字符串表示(不存在丰富/默认实现) +* `__sizeof__`:返回对象的大小(包括在堆中分配的大小) ### 显示 -* `__str__`:返回对象的字符串表示(丰富) +* `__str__`:返回对象的字符串表示(丰富) ### Fmt @@ -35,29 +35,29 @@ ## 对象系统 -Trait 类相当于 Python 中的 ABC(抽象基类,接口) +Trait 类相当于 Python 中的 ABC(抽象基类,接口) 实例属于1、True、“aaa”等。 类是 Int、Bool、Str 等。 ### 类型 -* `__父类__`:超类型(`__mro__` 是一个数组,但这个是一个 Set) +* `__父类__`:超类型(`__mro__` 是一个数组,但这个是一个 Set) * `__basicsize__`: * `__dictoffset__`:Evm 不支持 * `__flags__`: -* `__itemsize__`:实例的大小(如果不是类,则为 0) +* `__itemsize__`:实例的大小(如果不是类,则为 0) * `__weakrefoffset__`:Evm 不支持 * `__membercheck__`: 相当于`ismember(x, T)` -* `__subtypecheck__`:等价于`issubtype(U, T)`,别名`__subclasshook__`(兼容CPython) +* `__subtypecheck__`:等价于`issubtype(U, T)`,别名`__subclasshook__`(兼容CPython) ### 实例 -* `__class__`:返回创建实例的类(自动附加到使用 `.new` 创建的对象) +* `__class__`:返回创建实例的类(自动附加到使用 `.new` 创建的对象) ### Class -* `__mro__`:用于方法解析的类型数组(包括自身,始终以 Object 结尾) -* `__base__`:基本类型(`__mro__[1]` 如果有多个) +* `__mro__`:用于方法解析的类型数组(包括自身,始终以 Object 结尾) +* `__base__`:基本类型(`__mro__[1]` 如果有多个) * `__new__`: 实例化 * `__init__`: 初始化实例 * `__init_subclass__`: 初始化实例 @@ -76,9 +76,9 @@ Trait 类相当于 Python 中的 ABC(抽象基类,接口) ### 秩序 * `__lt__(self, rhs: Self) -> Bool`: 对象比较函数 (<) -* `__le__`:对象比较函数(<=),默认实现 -* `__gt__`:对象比较函数(>),默认实现 -* `__ge__`:对象比较函数(>=),默认实现 +* `__le__`:对象比较函数(<=),默认实现 +* `__gt__`:对象比较函数(>),默认实现 +* `__ge__`:对象比较函数(>=),默认实现 ### BinAdd @@ -98,7 +98,7 @@ Trait 类相当于 Python 中的 ABC(抽象基类,接口) ### BinMul <: Mul Self -* `__pow__`:实现 `**`(默认实现) +* `__pow__`:实现 `**`(默认实现) ### Div R, O @@ -112,7 +112,7 @@ Trait 类相当于 Python 中的 ABC(抽象基类,接口) ### Num (= Add and Sub and Mul and Eq) -例如,除了Complex,Vector、Matrix和Tensor都是Num(Matrix和Tensor中的*分别与dot和product相同) +例如,除了Complex,Vector、Matrix和Tensor都是Num(Matrix和Tensor中的*分别与dot和product相同) ### Complex (= Inherit(Object, Impl := Num)) @@ -167,7 +167,7 @@ Trait 类相当于 Python 中的 ABC(抽象基类,接口) ### 位 * `from_bytes`:从字节转换 -* `to_bytes`:转换为字节(指定长度和字节序(字节序)) +* `to_bytes`:转换为字节(指定长度和字节序(字节序)) * `bit_length`:返回位长度 ### 可迭代 T @@ -224,9 +224,9 @@ Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter(). ## Seq T = SizedIterable T 和 ... * `concat`: 合并两个 Seq -* `__getitem__`:等同于使用 `[]` 访问(否则会出现恐慌) +* `__getitem__`:等同于使用 `[]` 访问(否则会出现恐慌) * 与 `get`: __getitem__ 不同,它返回 Option -* `maketrans`:创建替换表(静态方法) +* `maketrans`:创建替换表(静态方法) * `replace`: 替换 * `translate`:根据替换表替换 * `insert`: 添加到 idx @@ -236,7 +236,7 @@ Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter(). * `push`:添加到末尾 * `pop`: 取尾巴 * `dedup`:删除连续值 -* `uniq`:删除重复元素(通过 sort |> dedup 实现,因此顺序可能会改变) +* `uniq`:删除重复元素(通过 sort |> dedup 实现,因此顺序可能会改变) * `swap`:交换元素 * `reverse`:反转元素 * `sort`: 排序元素 @@ -254,7 +254,7 @@ Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter(). * `push!`:添加到末尾 * `pop!`:拿尾巴 * `dedup!`:删除连续值 -* `uniq!`: 删除重复元素(通过排序实现!|> dedup!,因此顺序可能会改变) +* `uniq!`: 删除重复元素(通过排序实现!|> dedup!,因此顺序可能会改变) * `swap!`:交换元素 * `reverse!`:反转元素 * `set!` diff --git a/doc/zh_CN/API/types/classes/Dict!.md b/doc/zh_CN/API/types/classes/Dict!.md index 49d244a7..20e33c4c 100644 --- a/doc/zh_CN/API/types/classes/Dict!.md +++ b/doc/zh_CN/API/types/classes/Dict!.md @@ -1,6 +1,6 @@ # Dict! K, V -表示字典(哈希Map)的类型。 有一个语法糖叫做`{K: V}` +表示字典(哈希Map)的类型。 有一个语法糖叫做`{K: V}` ## 方法 diff --git a/doc/zh_CN/API/types/classes/Float.md b/doc/zh_CN/API/types/classes/Float.md index a71be823..06479f12 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 +表示实数(包含小数的数)的类型。符合IEEE 754的浮点数,在其他语言中一般是float的类型。 +Float的大小为8(1byte)~128(16byte)。如果只是Float,则表示`Float64`。 +Erg 中的 0.1 实际上属于 Ratio 类型,而不是 Float 类型。没有浮点类型字面量,它是由 `(Ratio object)f64` 生成的(例如 (1/2)f64, 15f64)。 f64 对应实数 1 ## 父类 diff --git a/doc/zh_CN/API/types/classes/Int.md b/doc/zh_CN/API/types/classes/Int.md index 3bd560e8..a3edd7a5 100644 --- a/doc/zh_CN/API/types/classes/Int.md +++ b/doc/zh_CN/API/types/classes/Int.md @@ -1,7 +1,7 @@ # Int 表示整数的类。 实例为 0、1、-1、300000 等。 -很多语言即使在表示自然数的时候也使用Int(类型等价于),但是Erg使用了使用更小的类型的原则, +很多语言即使在表示自然数的时候也使用Int(类型等价于),但是Erg使用了使用更小的类型的原则, 建议使用 Nat、NZInt、Interval 类型等。 Int是一种来自 Python 的类型,只有`Object`作为其超类型。 diff --git a/doc/zh_CN/API/types/classes/Interval.md b/doc/zh_CN/API/types/classes/Interval.md index 47aa17b3..68e69030 100644 --- a/doc/zh_CN/API/types/classes/Interval.md +++ b/doc/zh_CN/API/types/classes/Interval.md @@ -11,7 +11,7 @@ Winter = November..December or January..February ```python 0..1 # 整数范围 -0.0..1.0 # 真实(有理)范围 +0.0..1.0 # 真实(有理)范围 # 或 0/1..1/1 相同 ``` diff --git a/doc/zh_CN/API/types/classes/Never.md b/doc/zh_CN/API/types/classes/Never.md index fa6c413b..0336f19c 100644 --- a/doc/zh_CN/API/types/classes/Never.md +++ b/doc/zh_CN/API/types/classes/Never.md @@ -9,5 +9,5 @@ f(): Panic = exit 0 # OK g(): Never = panic() # TypeError ``` -`Never`/`Panic`的 OR 类型,例如`T 或 Never`可以转换为`T`。 这是因为`Never`在语义上是一个从不出现的选项(如果出现了,程序会立即停止)。 +`Never`/`Panic`的 OR 类型,例如`T 或 Never`可以转换为`T`。 这是因为`Never`在语义上是一个从不出现的选项(如果出现了,程序会立即停止)。 但是,在函数的返回值类型中使用时,`or Never`不能省略,因为它表示程序可能会终止。 \ 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 d28285f9..404b30ae 100644 --- a/doc/zh_CN/API/types/classes/Pos.md +++ b/doc/zh_CN/API/types/classes/Pos.md @@ -1,6 +1,6 @@ # Pos -Pos是一种表示正数(大于或等于1的整数)的类型。 +Pos是一种表示正数(大于或等于1的整数)的类型。 由于不包括0,因此具有消除被零除的可能性等优点。 ## 定义 diff --git a/doc/zh_CN/API/types/classes/Str.md b/doc/zh_CN/API/types/classes/Str.md index d87eff6d..269ea06a 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 _`) +(不变长度)表示字符串的类型。 简单的 `Str` 类型是删除了字符数的 `StrWithLen N` 类型(`Str = StrWithLen _`) ## 方法 * isnumeric -返回字符串是否为阿拉伯数字。 使用 `isunicodenumeric` 判断汉字数字和其他表示数字的字符(注意此行为与 Python 不同)。 \ No newline at end of file +返回字符串是否为阿拉伯数字。 使用 `isunicodenumeric` 判断汉字数字和其他表示数字的字符(注意此行为与 Python 不同)。 \ 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 49551099..6ee22bb4 100644 --- a/doc/zh_CN/API/types/classes/Tuple.md +++ b/doc/zh_CN/API/types/classes/Tuple.md @@ -6,7 +6,7 @@ * zip self, other - 组合两个有序集合(数组或元组) + 组合两个有序集合(数组或元组) ```python assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4) diff --git a/doc/zh_CN/compiler/TODO_hint.md b/doc/zh_CN/compiler/TODO_hint.md index 70ff02be..790ce1f7 100644 --- a/doc/zh_CN/compiler/TODO_hint.md +++ b/doc/zh_CN/compiler/TODO_hint.md @@ -1,4 +1,4 @@ -# 提示(未实现) +# 提示(未实现) -* `x 未定义`(x 已被`Del` 删除)=> `提示:在第 X 行删除` -*补丁方法重复:“提示:指定补丁(如`T.foo(1)`)或使用`Del`删除任何`.foo`” \ No newline at end of file +* `x 未定义`(x 已被`Del` 删除)=> `提示:在第 X 行删除` +*补丁方法重复:“提示:指定补丁(如`T.foo(1)`)或使用`Del`删除任何`.foo`” \ No newline at end of file diff --git a/doc/zh_CN/compiler/TODO_recov_suggest.md b/doc/zh_CN/compiler/TODO_recov_suggest.md index b324f0e1..93a193b1 100644 --- a/doc/zh_CN/compiler/TODO_recov_suggest.md +++ b/doc/zh_CN/compiler/TODO_recov_suggest.md @@ -1,4 +1,4 @@ -# 错误恢复建议(尚未实现) +# 错误恢复建议(尚未实现) * `1 or 2`, `1 and 2` => `{1, 2}`? * `U = Inherit T` => 非类类型不能被继承,或者`U = Class T`? diff --git a/doc/zh_CN/compiler/TODO_warn.md b/doc/zh_CN/compiler/TODO_warn.md index 8785ea6c..9f1fcf23 100644 --- a/doc/zh_CN/compiler/TODO_warn.md +++ b/doc/zh_CN/compiler/TODO_warn.md @@ -1,5 +1,5 @@ -# 警告(尚未实现) +# 警告(尚未实现) -* `t = {(record type)}` => `T = {(record type)}`?(只有定义为常量的类型才能用于类型说明) +* `t = {(record type)}` => `T = {(record type)}`?(只有定义为常量的类型才能用于类型说明) * `{I: Int | ...}!` => `{I: Int! | ...}` -* for/while 块中的`return x`(`x != ()`) => `f::return`(外部块)? \ No newline at end of file +* for/while 块中的`return x`(`x != ()`) => `f::return`(外部块)? \ No newline at end of file diff --git a/doc/zh_CN/compiler/abandoned.md b/doc/zh_CN/compiler/abandoned.md index 2aca11d1..dc120306 100644 --- a/doc/zh_CN/compiler/abandoned.md +++ b/doc/zh_CN/compiler/abandoned.md @@ -1,6 +1,6 @@ # 废弃/拒绝的语言规范 -## 重载(临时多态性) +## 重载(临时多态性) 被放弃了,因为它可以用参数+子类型多态来代替,并且与Python的语义不兼容。 有关详细信息,请参阅 [overload](../syntax/type/overloading.md) 文章。 diff --git a/doc/zh_CN/compiler/architecture.md b/doc/zh_CN/compiler/architecture.md index 1088dbce..f33fdfaf 100644 --- a/doc/zh_CN/compiler/architecture.md +++ b/doc/zh_CN/compiler/architecture.md @@ -2,7 +2,7 @@ ## 1. 扫描 Erg 脚本 (.er) 并生成 `TokenStream` (parser/lex.rs) -* parser/lexer/Lexer 生成`TokenStream`(这是一个Token的迭代器,TokenStream可以通过lexer.collect()生成) +* parser/lexer/Lexer 生成`TokenStream`(这是一个Token的迭代器,TokenStream可以通过lexer.collect()生成) * `Lexer` 由 `Lexer::new` 或 `Lexer::from_str` 构造,其中 `Lexer::new` 从文件或命令选项中读取代码。 * `Lexer` 可以作为迭代器按顺序生成令牌;如果您想一次获得 `TokenStream`,请使用 `Lexer::lex`。 * `Lexer` 输出 `LexError` 为错误,但 `LexError` 没有足够的信息显示自己。如果要显示错误,请使用 `LexerRunner` 转换错误。 @@ -17,26 +17,26 @@ ### 2.5 脱糖 `AST` * 扩展嵌套变量 (`Desugarer::desugar_nest_vars_pattern`) -* desugar 多模式定义语法(`Desugarer::desugar_multiple_pattern_def`) +* desugar 多模式定义语法(`Desugarer::desugar_multiple_pattern_def`) ## 3. 类型检查和推断,转换 `AST` -> `HIR` (compiler/lower.rs) * `HIR` 有每个变量的类型信息。它是用于“高级中间表示”的。 -* `HIR` 只保存变量的类型,但这已经足够了。在极端情况下,这是因为 Erg 只有转换(或运算符)应用程序的参数对象。 +* `HIR` 只保存变量的类型,但这已经足够了。在极端情况下,这是因为 Erg 只有转换(或运算符)应用程序的参数对象。 * `ASTLower` 可以用与`Parser` 和`Lexer` 相同的方式构造。 * 如果没有错误发生,`ASTLowerer::lower` 将输出 `HIR` 和 `CompileWarnings` 的元组。 * `ASTLowerer`归`Compiler`所有。与传统结构不同,`ASTLowerer`处理代码上下文并且不是一次性的。 -* 如果类型推断的结果不完整(如果存在未知类型变量),名称解析时会出错。 +* 如果类型推断的结果不完整(如果存在未知类型变量),名称解析时会出错。 -## 4. 检查副作用(compiler/effectcheck.rs) +## 4. 检查副作用(compiler/effectcheck.rs) -## 4. 检查所有权(compiler/memcheck.rs) +## 4. 检查所有权(compiler/memcheck.rs) -## 5. 从`HIR`(compiler/codegen.rs)生成字节码(`CodeObj`) +## 5. 从`HIR`(compiler/codegen.rs)生成字节码(`CodeObj`) * 根据表达式的类型信息,将执行量化子程序的名称解析。 -##(6.(未来计划)转换字节码 -> LLVM IR) +##(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 1ad6e9c8..722d1339 100644 --- a/doc/zh_CN/compiler/errors.md +++ b/doc/zh_CN/compiler/errors.md @@ -10,7 +10,7 @@ ## PurityError -当您在不允许副作用的范围内(函数、不可变类型等)编写导致副作用的代码时发生 +当您在不允许副作用的范围内(函数、不可变类型等)编写导致副作用的代码时发生 ## MoveError @@ -111,7 +111,7 @@ g() = f() ## SyntaxWarning -它在语法上很好,但是当我们检测到冗余或不常见的代码(不必要的 `()` 等)时就会发生这种情况 +它在语法上很好,但是当我们检测到冗余或不常见的代码(不必要的 `()` 等)时就会发生这种情况 ```python if (True): # SyntaxWarning: unnecessary parentheses @@ -121,11 +121,11 @@ if (True): # SyntaxWarning: unnecessary parentheses ## DeprecationWarning 在不推荐使用引用的对象时发生 -(开发人员在生成此警告时应始终提供替代方法作为提示) +(开发人员在生成此警告时应始终提供替代方法作为提示) ## FutureWarning 当您检测到将来可能导致问题的代码时发生 -此警告是由版本兼容性问题(包括库)以及语法和 API 的更改引起的 +此警告是由版本兼容性问题(包括库)以及语法和 API 的更改引起的 ## ImportWarning diff --git a/doc/zh_CN/compiler/hir.md b/doc/zh_CN/compiler/hir.md index 69f2b3f0..748cc4d6 100644 --- a/doc/zh_CN/compiler/hir.md +++ b/doc/zh_CN/compiler/hir.md @@ -2,7 +2,7 @@ HIR 是 Erg 编译器从 AST 生成的结构 此结构包含源代码中每个表达式的完整类型信息,并且在语法上已脱糖 -AST与源代码一一对应(纯文本),但是HIR去掉了不必要的代码信息,添加了省略的类型信息,所以HIR可以转换为源代码很难恢复 +AST与源代码一一对应(纯文本),但是HIR去掉了不必要的代码信息,添加了省略的类型信息,所以HIR可以转换为源代码很难恢复 让我们在下面的代码中查看 HIR 的示例 ```python diff --git a/doc/zh_CN/compiler/inference.md b/doc/zh_CN/compiler/inference.md index 290680b3..40aaf89b 100644 --- a/doc/zh_CN/compiler/inference.md +++ b/doc/zh_CN/compiler/inference.md @@ -20,18 +20,18 @@ v.push! 1 print! v ``` -Erg 的类型推断主要使用 Hindley-Milner 类型推断算法(尽管已经进行了各种扩展)。具体而言,类型推断是通过以下过程执行的。术语将在后面解释。 +Erg 的类型推断主要使用 Hindley-Milner 类型推断算法(尽管已经进行了各种扩展)。具体而言,类型推断是通过以下过程执行的。术语将在后面解释。 -1. 推断右值的类型(搜索) +1. 推断右值的类型(搜索) 2. 实例化结果类型 -3. 如果是调用,执行类型替换(substitute) +3. 如果是调用,执行类型替换(substitute) 4. 解决已经单态化的特征 -5. 如果有类型变量值,求值/归约(eval) -6. 删除链接类型变量(deref) +5. 如果有类型变量值,求值/归约(eval) +6. 删除链接类型变量(deref) 7. 传播可变依赖方法的变化 -8. 如果有左值并且是Callable,则泛化参数类型(generalize) -9. 如果有左值,对(返回值)类型进行泛化(generalize) -10. 如果是赋值,则在符号表(`Context`)中注册类型信息(更新) +8. 如果有左值并且是Callable,则泛化参数类型(generalize) +9. 如果有左值,对(返回值)类型进行泛化(generalize) +10. 如果是赋值,则在符号表(`Context`)中注册类型信息(更新) 具体操作如下。 @@ -40,7 +40,7 @@ Erg 的类型推断主要使用 Hindley-Milner 类型推断算法(尽管已经 获取 UnaryOp 类型: getArray 类型:`['T; 0]` 实例化:`[?T; 0]` - (替代,评估被省略) + (替代,评估被省略) 更新:`Γ: {v: [?T; 0]!}` 表达式 返回`NoneType`:OK @@ -49,7 +49,7 @@ Erg 的类型推断主要使用 Hindley-Milner 类型推断算法(尽管已经 搜索:`Γ Array!(?T, 0).push!({1})` 得到:`= Array!('T ~> 'T, 'N ~> 'N+1).push!('T) => NoneType` 实例化:`Array!(?T, ?N).push!(?T) => NoneType` - 替代(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!(Nat) => NoneType` + 替代(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!(Nat) => NoneType` 评估: `Array!(Nat, 0 ~> 1).push!({1}) => NoneType` 更新:`Γ:{v:[Nat; 1]!}` 表达式 返回`NoneType`:OK @@ -74,31 +74,31 @@ pub enum Type { } ``` -类型变量可以通过将实体类型保存在外部字典中来实现,并且类型变量本身只有它的键。但是,据说使用 `RcCell` 的实现通常更有效(需要验证,[来源](https://mobile.twitter.com/bd_gfngfn/status/1296719625086877696?s=21))。 +类型变量可以通过将实体类型保存在外部字典中来实现,并且类型变量本身只有它的键。但是,据说使用 `RcCell` 的实现通常更有效(需要验证,[来源](https://mobile.twitter.com/bd_gfngfn/status/1296719625086877696?s=21))。 类型变量首先被初始化为 `Type::Var(RcCell::new(None))`。 当分析代码并确定类型时,会重写此类型变量。 -如果内容直到最后都保持为 None ,它将是一个无法确定为具体类型的类型变量(当场)。例如,具有 `id x = x` 的 `x` 类型。 -我将这种状态下的类型变量称为 __Unbound 类型变量__(我不知道确切的术语)。另一方面,我们将分配了某种具体类型的变量称为 __Linked 类型变量__。 +如果内容直到最后都保持为 None ,它将是一个无法确定为具体类型的类型变量(当场)。例如,具有 `id x = x` 的 `x` 类型。 +我将这种状态下的类型变量称为 __Unbound 类型变量__(我不知道确切的术语)。另一方面,我们将分配了某种具体类型的变量称为 __Linked 类型变量__。 -两者都是自由类型变量(该术语显然以“自由变量”命名)。这些是编译器用于推理的类型变量。它之所以有这样一个特殊的名字,是因为它不同于程序员指定类型的类型变量,例如 `id: 'T -> 'T` 中的 `'T`。 +两者都是自由类型变量(该术语显然以“自由变量”命名)。这些是编译器用于推理的类型变量。它之所以有这样一个特殊的名字,是因为它不同于程序员指定类型的类型变量,例如 `id: 'T -> 'T` 中的 `'T`。 未绑定类型变量表示为`?T`、`?U`。在类型论的上下文中,经常使用 α 和 β,但这一种是用来简化输入的。 请注意,这是出于一般讨论目的而采用的表示法,实际上并未使用字符串标识符实现。 进入类型环境时,未绑定的类型变量 `Type::Var` 被替换为 `Type::MonoQuantVar`。这称为 __quantified 类型变量__。这类似于程序员指定的类型变量,例如“T”。内容只是一个字符串,并没有像自由类型变量那样链接到具体类型的工具。 -用量化类型变量替换未绑定类型变量的操作称为__generalization__(或泛化)。如果将其保留为未绑定类型变量,则类型将通过一次调用固定(例如,调用 `id True` 后,`id 1` 的返回类型将是 `Bool`),所以它必须是概括的。 +用量化类型变量替换未绑定类型变量的操作称为__generalization__(或泛化)。如果将其保留为未绑定类型变量,则类型将通过一次调用固定(例如,调用 `id True` 后,`id 1` 的返回类型将是 `Bool`),所以它必须是概括的。 以这种方式,在类型环境中注册了包含量化类型变量的通用定义。 ## 概括、类型方案、具体化 让我们将未绑定类型变量 `?T` 泛化为 `gen` 的操作表示。令生成的广义类型变量为 `|T: Type| T`。 -在类型论中,量化类型,例如多相关类型 `α->α`,通过在它们前面加上 `∀α.` 来区分(像 ∀ 这样的符号称为(通用)量词。)。 -这样的表示(例如`∀α.α->α`)称为类型方案。 Erg 中的类型方案表示为 `|T: Type| T -> T`。 +在类型论中,量化类型,例如多相关类型 `α->α`,通过在它们前面加上 `∀α.` 来区分(像 ∀ 这样的符号称为(通用)量词。)。 +这样的表示(例如`∀α.α->α`)称为类型方案。 Erg 中的类型方案表示为 `|T: Type| T -> T`。 类型方案通常不被认为是一流的类型。以这种方式配置类型系统可以防止类型推断起作用。但是,在尔格中,在一定条件下可以算是一流的类型。有关详细信息,请参阅 [rank2 类型](../syntax/type/advanced/rank2type.md)。 -现在,当在使用它的类型推断(例如,`id 1`,`id True`)中使用获得的类型方案(例如`'T -> 'T(id's type scheme)`)时,必须释放generalize。这种逆变换称为 __instantiation__。我们将调用操作`inst`。 +现在,当在使用它的类型推断(例如,`id 1`,`id True`)中使用获得的类型方案(例如`'T -> 'T(id's type scheme)`)时,必须释放generalize。这种逆变换称为 __instantiation__。我们将调用操作`inst`。 ```python gen ?T = 'T @@ -125,7 +125,7 @@ subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y ## 半统一(semi-unification) -统一的一种变体称为半统一(__Semi-unification__)。 这是更新类型变量约束以满足子类型关系的操作。 +统一的一种变体称为半统一(__Semi-unification__)。 这是更新类型变量约束以满足子类型关系的操作。 在某些情况下,类型变量可能是统一的,也可能不是统一的,因此称为“半”统一。 例如,在参数分配期间会发生半统一。 @@ -193,7 +193,7 @@ x: ?T -> y(: inst 'T) ``` -请注意,实例化必须创建一个与任何已经存在的(自由)类型变量不同的(自由)类型变量(概括类似)。 这样的类型变量称为新类型变量。 +请注意,实例化必须创建一个与任何已经存在的(自由)类型变量不同的(自由)类型变量(概括类似)。 这样的类型变量称为新类型变量。 ```python x: ?T -> @@ -371,7 +371,7 @@ f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) = id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>) ``` -如果已经分配了返回类型,则与结果类型统一(`?U<2> --> ?T<2>`)。 +如果已经分配了返回类型,则与结果类型统一(`?U<2> --> ?T<2>`)。 ```python # ?U<2> --> ?T<2> diff --git a/doc/zh_CN/compiler/overview.md b/doc/zh_CN/compiler/overview.md index f20356f1..e5e5c7f8 100644 --- a/doc/zh_CN/compiler/overview.md +++ b/doc/zh_CN/compiler/overview.md @@ -4,7 +4,7 @@ ## 1. 词法分析 -* `Lexer` 进行词法分析。 `Lexer::next`(`Lexer`被实现为一个迭代器)负责词法分析的主要逻辑。 `Token` 作为解析的结果输出。 +* `Lexer` 进行词法分析。 `Lexer::next`(`Lexer`被实现为一个迭代器)负责词法分析的主要逻辑。 `Token` 作为解析的结果输出。 ## 2. 解析 @@ -16,7 +16,7 @@ ## 4. 类型检查/类型推断 -* `ASTLowerer` 进行打字。类型检查主要由 `Context` 完成。尤其重要的是 `Context::supertype_of`(确定子类型关系)、`Context::unify/sub_unify`(统一/半统一类型变量)、`Context::init_builtin_*`(定义内置 API)。 `HIR` 作为分析结果输出。 +* `ASTLowerer` 进行打字。类型检查主要由 `Context` 完成。尤其重要的是 `Context::supertype_of`(确定子类型关系)、`Context::unify/sub_unify`(统一/半统一类型变量)、`Context::init_builtin_*`(定义内置 API)。 `HIR` 作为分析结果输出。 ## 5. 副作用检查 diff --git a/doc/zh_CN/compiler/parsing.md b/doc/zh_CN/compiler/parsing.md index 9e4a544f..c790e086 100644 --- a/doc/zh_CN/compiler/parsing.md +++ b/doc/zh_CN/compiler/parsing.md @@ -17,7 +17,7 @@ f(1,) == f(1) ## 左值,右值 在 Erg 中,左侧的值并不像 `=` 的左侧那么简单。 -事实上,`=` 左侧有一个右值(非常令人困惑),而 `=` 右侧有一个左值。 +事实上,`=` 左侧有一个右值(非常令人困惑),而 `=` 右侧有一个左值。 右值中甚至可以有左值。 ```python diff --git a/doc/zh_CN/compiler/refinement_subtyping.md b/doc/zh_CN/compiler/refinement_subtyping.md index 3bacb6bb..631a9da8 100644 --- a/doc/zh_CN/compiler/refinement_subtyping.md +++ b/doc/zh_CN/compiler/refinement_subtyping.md @@ -23,7 +23,7 @@ Erg 通过将 Enum 和 Interval 类型转换为筛选类型来实现类型确定 ## 筛型检测 -描述了一种用于确定筛类型 A 是否是另一筛类型 B 的子类型的算法。正式地,(所有)子类型定义如下: +描述了一种用于确定筛类型 A 是否是另一筛类型 B 的子类型的算法。正式地,(所有)子类型定义如下: ```console A <: B <=> ∀a∈A; a∈B @@ -31,7 +31,7 @@ A <: B <=> ∀a∈A; a∈B 具体而言,应用以下推理规则。假定布尔表达式是简化的。 -* 间隔规则(从类型定义自动完成) +* 间隔规则(从类型定义自动完成) * `Nat` => `{I: Int | I >= 0}` * 围捕规则 * `{I: Int | I < n}` => `{I: Int | I <= n-1}` diff --git a/doc/zh_CN/compiler/trait_method_resolving.md b/doc/zh_CN/compiler/trait_method_resolving.md index 8dd3a966..66574713 100644 --- a/doc/zh_CN/compiler/trait_method_resolving.md +++ b/doc/zh_CN/compiler/trait_method_resolving.md @@ -9,8 +9,8 @@ ``` `.times` 是一种 `NatImpl` 补丁方法。 -由于`1`是`Int`的一个实例,首先通过跟踪`Int`的MRO(方法解析顺序)来搜索它。 -Erg 在 `Int` 的 MRO 中有 `Int`、`Object`。它来自 Python(Python 中的`int.__mro__ == [int, object]`)。 +由于`1`是`Int`的一个实例,首先通过跟踪`Int`的MRO(方法解析顺序)来搜索它。 +Erg 在 `Int` 的 MRO 中有 `Int`、`Object`。它来自 Python(Python 中的`int.__mro__ == [int, object]`)。 `.times` 方法在它们中都不存在。现在让我们探索那个子类型。 ~ @@ -43,7 +43,7 @@ provided_method_table = { ##筛型确定 检查候选类型是否与 `1` 的类型 `{1}` 兼容。与“{1}”兼容的筛子类型有“{0, 1}”、“0..9”等。 -有限元代数类型,例如 `0..1 或 3..4`、`-1..2 和 0..3`,在声明为基本类型(即 {0, 1, 3, 4}`,`{0, 1, 2}`)。 +有限元代数类型,例如 `0..1 或 3..4`、`-1..2 和 0..3`,在声明为基本类型(即 {0, 1, 3, 4}`,`{0, 1, 2}`)。 在这种情况下,`Nat` 是 `0.._ == {I: Int | I >= 0}`,所以 `{1}` 与 `Nat` 兼容。 ## 确定记录类型 @@ -55,7 +55,7 @@ provided_method_table = { 所以`Nat`适合。但是,如果 `Foo` 也匹配,则由 `Nat` 和 `Foo` 之间的包含关系决定。 即,选择子类型方法。 -如果两者之间没有包含关系,则会发生编译错误(这是一种安全措施,防止违背程序员的意图执行方法)。 +如果两者之间没有包含关系,则会发生编译错误(这是一种安全措施,防止违背程序员的意图执行方法)。 要消除错误,您需要明确指定补丁。 ```python @@ -88,7 +88,7 @@ provided_method_table = { ``` `FnType(T)` 检查匹配类型。 在这种情况下,`FnType(T)` 补丁类型是 `Type -> Type`。 -这匹配 `Int -> Int`。 如果合适,进行单态化和替换(取 `T -> T` 和 `Int -> Int`、`{T => Int}` 的差异)。 +这匹配 `Int -> Int`。 如果合适,进行单态化和替换(取 `T -> T` 和 `Int -> Int`、`{T => Int}` 的差异)。 ```python assert FnType(Int).type == Int diff --git a/doc/zh_CN/dev_guide/branches.md b/doc/zh_CN/dev_guide/branches.md index 84853cb8..c4380f04 100644 --- a/doc/zh_CN/dev_guide/branches.md +++ b/doc/zh_CN/dev_guide/branches.md @@ -7,7 +7,7 @@ * 编译成功 -## beta(目前不创建) +## beta(目前不创建) * 最新的 Beta 版本 * 必须满足以下条件 @@ -30,6 +30,6 @@ ## fix-* -* 修复特定错误的分支(如果该问题是一个错误,则代替`issue-*`创建)。 +* 修复特定错误的分支(如果该问题是一个错误,则代替`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 5a4aebdc..0de6c136 100644 --- a/doc/zh_CN/dev_guide/build_features.md +++ b/doc/zh_CN/dev_guide/build_features.md @@ -8,14 +8,14 @@ ## japanese 将系统语言设置为日语。 -Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为日语。 +Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为日语。 ## simplified_chinese 将系统语言设置为简体中文。 -Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为简体中文。 +Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为简体中文。 ## traditional_chinese 将系统语言设置为繁体中文。 -Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为繁体中文。 \ No newline at end of file +Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为繁体中文。 \ 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 b5a1babc..56899909 100644 --- a/doc/zh_CN/dev_guide/doc_guideline.md +++ b/doc/zh_CN/dev_guide/doc_guideline.md @@ -3,10 +3,10 @@ 任何不符合以下规则的文件都将得到更正。 * 以某种语气写代码注释或内部文档。 -* 向外部(普通用户)展示的文档应该越来越多地编写。 +* 向外部(普通用户)展示的文档应该越来越多地编写。 * 始终包含定义、含义或文档中首次出现的术语的链接。 -* 仅对理解正文所必需的补充句子使用括号作为附加条件,对于理解正文不是必需的句子使用脚注[1]( #1)。 -* 如果文档内容过时,按照【此方法】更新(https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)。 +* 仅对理解正文所必需的补充句子使用括号作为附加条件,对于理解正文不是必需的句子使用脚注[1]( #1)。 +* 如果文档内容过时,按照【此方法】更新(https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)。 --- diff --git a/doc/zh_CN/dev_guide/env.md b/doc/zh_CN/dev_guide/env.md index 9f6d9264..3c98f96d 100644 --- a/doc/zh_CN/dev_guide/env.md +++ b/doc/zh_CN/dev_guide/env.md @@ -2,7 +2,7 @@ ## 你需要安装什么 -* Rust(与 rustup 一起安装) +* Rust(与 rustup 一起安装) * 版本 >= 1.63.0 * 2021年版 diff --git a/doc/zh_CN/dev_guide/faq_syntax.md b/doc/zh_CN/dev_guide/faq_syntax.md index 1e54da09..9ff0b713 100644 --- a/doc/zh_CN/dev_guide/faq_syntax.md +++ b/doc/zh_CN/dev_guide/faq_syntax.md @@ -2,7 +2,7 @@ ## 当我们有所有权系统时,为什么要与 GC 共存? -因为 Erg 推出所有权系统的动机并不是为了 Rust 那样的“不依赖 GC 的内存管理”。最初,由于 Erg 是一种语言,目前使用 Python VM,因此最终仍使用 GC。Erg 引入产权系统的目标是“可变状态的局部化”。在 Erg 中,可变对象具有所有权概念。这是根据共享可变状态容易成为 bug 的温床,甚至是类型安全性的侵犯(详见)来判断的。 +因为 Erg 推出所有权系统的动机并不是为了 Rust 那样的“不依赖 GC 的内存管理”。最初,由于 Erg 是一种语言,目前使用 Python VM,因此最终仍使用 GC。Erg 引入产权系统的目标是“可变状态的局部化”。在 Erg 中,可变对象具有所有权概念。这是根据共享可变状态容易成为 bug 的温床,甚至是类型安全性的侵犯(详见)来判断的。 ## 为什么类型参数周围的括号不是 <> 或 []? @@ -67,7 +67,7 @@ try!: 在引入 Python 函数时,缺省情况下,所有函数都被视为包含异常,返回类型为。如果你知道不调度异常,请在中指明。 -此外,Erg 没有引入异常机制的另一个原因是它计划引入并行编程的功能。这是因为异常机制与并行执行不兼容(例如,如果并行执行导致多个异常,则很难处理)。 +此外,Erg 没有引入异常机制的另一个原因是它计划引入并行编程的功能。这是因为异常机制与并行执行不兼容(例如,如果并行执行导致多个异常,则很难处理)。 ## Erg 似乎消除了 Python 被认为是坏做法的功能,但为什么没有取消继承? @@ -93,13 +93,13 @@ A:没有那个计划。最重要的原因是,如果允许定义自己的运 ## 为什么 Erg 取消了 += 这样的扩展赋值运算符? -首先,Erg 中没有变量的可变性。也就是不能重新赋值。一旦对象与一个变量关联,它将一直绑定到该变量,直到它脱离作用域并被释放。在 Erg 中,可变性是指对象的可变性。明白了这个,故事就简单了。例如,表示,但由于变量是不可重新赋值的,因此这种语法是非法的。还有一个 Erg 的设计原则是运算符没有副作用。Python 通常也是如此,但对于某些对象(如 Dict),扩展赋值运算符会更改对象的内部状态。这算不上是一个很漂亮的设计。因此,扩展赋值运算符被完全废弃。 +首先,Erg 中没有变量的可变性。也就是不能重新赋值。一旦对象与一个变量关联,它将一直绑定到该变量,直到它脱离作用域并被释放。在 Erg 中,可变性是指对象的可变性。明白了这个,故事就简单了。例如,表示,但由于变量是不可重新赋值的,因此这种语法是非法的。还有一个 Erg 的设计原则是运算符没有副作用。Python 通常也是如此,但对于某些对象(如 Dict),扩展赋值运算符会更改对象的内部状态。这算不上是一个很漂亮的设计。因此,扩展赋值运算符被完全废弃。 ## 为什么 Erg 在语法上特别对待有副作用的过程? 副作用的局部化是代码维护的一个关键因素。 -但是,确实也不是没有方法可以不在语言上特殊对待副作用。例如,可以用代数效果(类型系统上的功能)替代过程。但这样的合一并不总是正确的。例如,Haskell 没有对字符串进行特殊处理,只是一个字符数组,但这种抽象是错误的。 +但是,确实也不是没有方法可以不在语言上特殊对待副作用。例如,可以用代数效果(类型系统上的功能)替代过程。但这样的合一并不总是正确的。例如,Haskell 没有对字符串进行特殊处理,只是一个字符数组,但这种抽象是错误的。 什么情况下,可以说合一化是错的?一个指标是“是否会因其合一而难以看到错误信息”。Erg 设计师发现,将副作用特殊处理会使错误消息更容易阅读。 diff --git a/doc/zh_CN/dev_guide/i18n_messages.md b/doc/zh_CN/dev_guide/i18n_messages.md index b3869922..7a2fdbb5 100644 --- a/doc/zh_CN/dev_guide/i18n_messages.md +++ b/doc/zh_CN/dev_guide/i18n_messages.md @@ -1,12 +1,12 @@ # 多语言错误信息 -Erg 正在推动消息(开始、选项、文档、提示、警告、错误消息等)的多语言化。如果你不熟悉 Rust 或 Erg,也可以参与此项目。请务必配合。 +Erg 正在推动消息(开始、选项、文档、提示、警告、错误消息等)的多语言化。如果你不熟悉 Rust 或 Erg,也可以参与此项目。请务必配合。 以下是多语种方法的说明。 ## 查找`switch_lang!` -在 Erg 源代码中找到(使用 grep 或编辑器的搜索功能)。我们应该能找到下面这样的东西。 +在 Erg 源代码中找到(使用 grep 或编辑器的搜索功能)。我们应该能找到下面这样的东西。 ```rust switch_lang!( @@ -19,7 +19,7 @@ switch_lang!( ## 添加消息 -请在查看其他语言内容的同时添加翻译消息。最后不要忘记逗号(,)。 +请在查看其他语言内容的同时添加翻译消息。最后不要忘记逗号(,)。 ```rust switch_lang!( @@ -31,7 +31,7 @@ switch_lang!( 另外,英语是默认设置,一定要排在最后。 -`{name}`部分是 Rust 的格式化功能,允许你将变量的内容(`name`)嵌入到字符串中。 +`{name}`部分是 Rust 的格式化功能,允许你将变量的内容(`name`)嵌入到字符串中。 ## 构建 @@ -47,7 +47,7 @@ Q:像这样的指定是什么意思?A:{RED} 及更高版本将显示为红 Q:如果想添加自己的语言,该如何替换部分?答:目前支持以下语言。 -* "english"(默认设置) +* "english"(默认设置) * "japanese" (日语) * "simplified_chinese" (简体中文) * "traditional_chinese" (繁体中文) diff --git a/doc/zh_CN/dev_guide/rust_code_guideline.md b/doc/zh_CN/dev_guide/rust_code_guideline.md index 49db6c84..0c15a9f7 100644 --- a/doc/zh_CN/dev_guide/rust_code_guideline.md +++ b/doc/zh_CN/dev_guide/rust_code_guideline.md @@ -2,14 +2,14 @@ ## 本地规则 -* 使用 `log!` 进行调试输出(使用 `println!` 等进行输出处理,这也是发布所必需的)。 -* 未使用或内部变量/方法(私有且仅用于特定功能)必须以 `_` 为前缀。如果要避免与保留字冲突,请在末尾添加一个`_`。 +* 使用 `log!` 进行调试输出(使用 `println!` 等进行输出处理,这也是发布所必需的)。 +* 未使用或内部变量/方法(私有且仅用于特定功能)必须以 `_` 为前缀。如果要避免与保留字冲突,请在末尾添加一个`_`。 ## 推荐代码 * 定义和使用特定领域的枚举而不是数字枚举或布尔值。 * 将访问修饰符保持在最低限度。即使在发布时也要优先使用 `pub(mod)` 或 `pub(crate)`。 -* 将 for 表达式中的可迭代对象显式转换为迭代器(`for i in x.iter()` 而不是 `for i in x`)。 +* 将 for 表达式中的可迭代对象显式转换为迭代器(`for i in x.iter()` 而不是 `for i in x`)。 * 懒惰的评价。例如,如果 `default` 不是文字,请使用 `unwrap_or_else` 而不是 `unwrap_or`。 ## 不鼓励使用代码 diff --git a/doc/zh_CN/dev_guide/terms.md b/doc/zh_CN/dev_guide/terms.md index 2b6d9fc0..8dc55e6e 100644 --- a/doc/zh_CN/dev_guide/terms.md +++ b/doc/zh_CN/dev_guide/terms.md @@ -234,7 +234,7 @@ ### [Assertion] -检查(通常在运行时)代码中的条件是否为真。 这是使用 `assert` 函数等来完成的。 +检查(通常在运行时)代码中的条件是否为真。 这是使用 `assert` 函数等来完成的。 ```python sum = !0 @@ -266,7 +266,7 @@ assert sum == 55 ### [依赖类型](../syntax/type/dependent_type.md) -参数是值的类型(习惯上说,不是类型)。 +参数是值的类型(习惯上说,不是类型)。 ### 不可变 -> [不可变] @@ -338,7 +338,7 @@ Ergs 通过缩进表示块。这称为越位规则。 ### [可见性] -标识符是否可以被外部引用(超出范围,或在另一个模块或包中)的属性。 +标识符是否可以被外部引用(超出范围,或在另一个模块或包中)的属性。 ### [类型] @@ -700,7 +700,7 @@ f x = ... ### [派生类型](../syntax/type/variances.md/# 用户定义的类型变体) -### [模式(匹配)](../syntax/26_pattern_matching.md) +### [模式(匹配)](../syntax/26_pattern_matching.md) ### [包](../syntax/33_package_system.md) diff --git a/doc/zh_CN/dev_guide/unify_terms.md b/doc/zh_CN/dev_guide/unify_terms.md index 0aa3be7d..2c8e49f5 100644 --- a/doc/zh_CN/dev_guide/unify_terms.md +++ b/doc/zh_CN/dev_guide/unify_terms.md @@ -20,13 +20,13 @@ 就其本义而言, -* 符号:在源代码中实心编写的字符(符号、控制字符等除外),不是字符串对象(未包含在“”中)。符号在 Ruby、Lisp 等中作为原始类型存在,但在 Erg 中它们不被视为对象。 -* 标识符:(并且可以)引用某个对象的符号,而不是保留字。例如,在 Python 中 class 和 def 不能用作标识符。由于 Erg 没有保留字,所以除了某些符号外,所有符号都可以用作标识符。 +* 符号:在源代码中实心编写的字符(符号、控制字符等除外),不是字符串对象(未包含在“”中)。符号在 Ruby、Lisp 等中作为原始类型存在,但在 Erg 中它们不被视为对象。 +* 标识符:(并且可以)引用某个对象的符号,而不是保留字。例如,在 Python 中 class 和 def 不能用作标识符。由于 Erg 没有保留字,所以除了某些符号外,所有符号都可以用作标识符。 * 名称:与标识符的含义几乎相同。它有时与 Erg 中的代数同义使用。 -* 代数名称:相当于尔格中的标识符。在 C 中,函数名称是标识符,而不是代数名称。 “代数”指的是语言特性本身,它允许您使用 `=`(变量赋值运算符)或 `=`(常量赋值运算符)来分配对象。 +* 代数名称:相当于尔格中的标识符。在 C 中,函数名称是标识符,而不是代数名称。 “代数”指的是语言特性本身,它允许您使用 `=`(变量赋值运算符)或 `=`(常量赋值运算符)来分配对象。 ```python -代数名称<:(名称==标识符)​​<:符号 +代数名称<:(名称==标识符)​​<:符号 变量 + 常数 == 代数 ``` @@ -48,7 +48,7 @@ Erg 中不使用代数名称和名称,使用统一标识符。 ## 数组列表 -使用数组。 Erg 数组(通常)在内存中是连续的。 +使用数组。 Erg 数组(通常)在内存中是连续的。 List 是指所谓的链表,或者说列表作为 Python 数据类型。 ## lambda 函数、lambda 表达式、匿名函数 diff --git a/doc/zh_CN/python/bytecode_instructions.md b/doc/zh_CN/python/bytecode_instructions.md index e0427708..c93ec1eb 100644 --- a/doc/zh_CN/python/bytecode_instructions.md +++ b/doc/zh_CN/python/bytecode_instructions.md @@ -1,16 +1,16 @@ -# Python Bytecode Instructions +# Python 字节码指令 -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). +Python 字节码变量操作命令通过 名称索引(名称索引)访问。 这是为了在 Python 中实现动态变量访问(可以使用 eval 等作为字符串访问)。 +一条指令为 2 个字节,指令和参数以 little endian 形式存储。 +不带参数的指令也使用 2 个字节(参数部分为 0)。 -## STORE_NAME(namei) +## STORE_NAME(名称索引) ```python globals[namei] = stack.pop() ``` -## LOAD_NAME(namei) +## LOAD_NAME(名称索引) ```python stack.push(globals[namei]) @@ -18,22 +18,22 @@ stack.push(globals[namei]) Only called at top level. -## LOAD_GLOBAL(namei) +## LOAD_GLOBAL(名称索引) ```python stack.push(globals[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) +用于加载内部作用域顶层的STORE_NAME,但顶层的`名称索引`不一定与某个作用域的代码对象中的名称索引相同(名称相同,名称索引不一定) -## LOAD_CONST(namei) +## LOAD_CONST(名称索引) ```python stack.push(consts[namei]) ``` -Load constants in the constant table. -Currently (Python 3.9), in CPython, each lambda function is MAKE_FUNCTION with the name "\" +在常量表中加载常量。 +目前(Python 3.9),在 CPython 中,每个 lambda 函数都是 MAKE_FUNCTION,名称为“\” ```console >>> dis.dis("[1,2,3].map(lambda x: x+1)") @@ -49,66 +49,68 @@ Currently (Python 3.9), in CPython, each lambda function is MAKE_FUNCTION with t 18 RETURN_VALUE ``` -## STORE_FAST(namei) +## STORE_FAST(名称索引) 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? +可能对应于顶层的 STORE_NAME +假定未引用(或单个)变量由此存储 +全局空间有自己的指令是为了优化吗? -## LOAD_FAST(namei) +## LOAD_FAST(名称索引) +```python stack.push(fastlocals[namei]) -fastlocals are varnames? +``` +fastlocals 是变量名吗? -## LOAD_CLOSURE(namei) +## LOAD_CLOSURE(名称索引) ```python cell = freevars[namei] stack. push(cell) ``` -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 +然后调用 BUILD_TUPLE +它只在闭包内被调用,并且 cellvars 应该在闭包内存储引用。 +与 LOAD_DEREF 不同,每个单元格(填充有引用的容器)都被推入堆栈 -## STORE_DEREF(namei) +## STORE_DEREF(名称索引) ```python cell = freevars[namei] cell.set(stack.pop()) ``` -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 +在内部范围内没有引用的变量是 STORE_FAST,但引用的变量是 STORE_DEREF +在 Python 中,引用计数在该指令内递增和递减 -## LOAD_DEREF(namei) +## LOAD_DEREF(名称索引) ```python cell = freevars[namei] stack.push(cell.get()) ``` -## name list +## 名称列表 -### 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 +fast_locals 对应的函数内部变量名称列表 +即使名称中有同名的变量,它们也基本不一样(新创建的和外部变量不能从那个范围访问) +即没有在范围内定义的外部引用的变量进入 varnames -### 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 variables +## 自由变量 -Compatible with freevars -Variables captured by the closure. It behaves statically within the same function instance. +与免费变量兼容 +闭包捕获的变量。它在同一个函数实例中静态地运行。 -## cell variables +## 单元格变量 -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 +对应于 cellvars +在函数内捕获到内部闭包函数的变量。 由于制作了副本,因此原始变量保持原样。 \ No newline at end of file diff --git a/doc/zh_CN/python/bytecode_specification.md b/doc/zh_CN/python/bytecode_specification.md index 9cf67b88..86fd9c27 100644 --- a/doc/zh_CN/python/bytecode_specification.md +++ b/doc/zh_CN/python/bytecode_specification.md @@ -69,3 +69,76 @@ * 0 byte: 0xDA (means 'Z') * 1~4 byte: length of string * 5~ byte: payload + + +# Python 字节码规范 + +## 格式 + +* 0~3 byte(u32):幻数(详见common/bytecode.rs) +* 4~7 byte(u32): 0 padding +* 8~12 byte(u32): 时间戳 +* 13~ byte(PyCodeObject): 代码对象 + +## PyCode 对象 + +* 0 byte(u8): '0xe3' (前缀,这意味着代码的'c') +* 01~04 byte(u32): args个数(co_argcount) +* 05~08 byte(u32): position-only args 的数量 (co_posonlyargcount) +* 09~12 byte(u32):仅关键字参数的数量(co_kwonlyargcount) +* 13~16 byte(u32): 本地数 (co_nlocals) +* 17~20 byte(u32): 栈大小(co_stacksize) +* 21~24 byte(u32):标志(co_flags)() +* ? byte:字节码指令,以'0x53'、'0x0'结尾(83, 0):RETURN_VALUE(co_code) +* ? byte(PyTuple):代码中使用的常量(co_consts) +* ? byte(PyTuple):代码中使用的名称(co_names) +* ? byte(PyTuple):代码中定义的变量名,包括params (PyTuple) (co_varnames) +* ? byte(PyTuple):从外部范围捕获的变量(co_freevars) +* ? byte(PyTuple):内部闭包中使用的变量(co_cellvars) +* ? byte(PyUnicode 或 PyShortAscii):文件名,它是从哪里加载的(co_filename) +* ? byte(PyUnicode or PyShortAscii): 代码本身的名字,默认是\ (co_name) +* ?~?+3 byte(u32): 第一行数 (co_firstlineno) +* ? byte(bytes):行表,用 PyStringObject? (co_lnotab) + +## PyTupleObject + +* 0 byte: 0x29 (意思是:')') +* 01~04 byte(u32): 元组项数 +* ? byte(PyObject):项目 + +## PyString 对象 + +* 如果我使用 ascii 以外的字符,它会变成 PyUnicode 吗? +* “あ”、“𠮷”和“α”是 PyUnicode(不再使用?) + +* 0 byte:0x73(表示's') +* 1~4 byte:字符串长度 +* 5~ byte:有效载荷 + +## PyUnicode 对象 + +* 0 byte:0x75(表示“u”) +* 1~4 byte:字符串长度 +* 5~ byte:有效载荷 + +## PyShortAsciiObject + +* 这叫短,但是即使超过100个字符,仍然会保持在短的状态 +* 或者更确切地说,没有不短的 ascii(短数据类型吗?) + +* 0 byte:0xFA(表示“z”) +* 1~4 byte:字符串长度 +* 5~ byte:有效载荷 + +## PyInternedObject + +* 实习对象注册在专用地图中,可以与is进行比较 +* 例如字符串,无论其长度如何,都可以在恒定时间内进行比较 + +* 0 byte:0x74(表示't') + +## PyShortAsciiInternedObject + +* 0 byte:0xDA(表示“Z”) +* 1~4 byte:字符串长度 +* 5~ byte:有效载荷 \ No newline at end of file diff --git a/doc/zh_CN/python/class_system.md b/doc/zh_CN/python/class_system.md index 270fa188..68383b60 100644 --- a/doc/zh_CN/python/class_system.md +++ b/doc/zh_CN/python/class_system.md @@ -1,10 +1,10 @@ -# Python class system (compare with Erg) +# Python 类系统(与 Erg 比较) ## 方法 -方法 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.) +方法可以被前向引用,但这不是一种特殊的技术。 +这是因为动态检查方法的存在。 +(在 Erg 中,方法存在是静态检查的。对于前向引用,函数必须是常量。) ```python >>> class C: @@ -14,10 +14,10 @@ This is because the existence of a method is dynamically checked. ... def g(self, x): return self.f(x - 1) ``` -## 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. +一些被覆盖的方法 m 被简单地覆盖,就像变量重新分配一样。 +在父类中引用 m 的方法将在子类中引用被覆盖的 m。 ```python >>> class C: @@ -31,7 +31,7 @@ A method that refers to m in the parent class will refer to the overridden m in 2 ``` -So, even if it is overridden by mistake obviously, it will not be an error until runtime. +因此,即使它显然被错误地覆盖,直到运行时才会出错。 ```python >>>> class C: @@ -45,11 +45,11 @@ So, even if it is overridden by mistake obviously, it will not be an error until Traceback (most recent call last): File "", line 1, in ", line 3, in g -TypeError: can only concatenate str (not "int") to str +类型错误:只能将str(不是“int”)连接到str ``` -Erg statically checks for consistency with the parent class. -The `Override` decorator must be given when overriding, and the type of the overriding function must be a subtype of the type of the function being overridden. +Erg 静态检查与父类的一致性。 +重写时必须给出“Override”装饰器,并且重写函数的类型必须是被重写函数类型的子类型。 ```python >>> C = Class() @@ -59,15 +59,15 @@ The `Override` decorator must be given when overriding, and the type of the over >>> D = Inherit C ... .f self = "a" ... -Error[#XX]: File "", line 5, in D -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). +错误[#XX]:文件“”,第 5 行,在 D 中 +要覆盖 f,必须添加 `Override` 装饰器,其类型必须是 `Self.() -> Nat` 或其子类型 +f(self) 已在 C 中定义。要覆盖 f,必须添加 `Override` 装饰器,其类型必须为 `Self. 要覆盖,必须给它一个 `Override` 装饰器,并且它的类型必须是 `Self.() -> Nat` 或 that.f(self) 的子类型。 ``` -## 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 中,大多数操作都是方法调用。 如果对象所属的类在调用时没有附加方法,就是这样。 ```python def f(x): @@ -78,7 +78,7 @@ class C: c = C() f(c) -f(1) # TypeError +f(1) # 类型错误 ``` ```python @@ -90,5 +90,5 @@ 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 +f(1) # 类型错误:f 将具有方法 `.m` 的类型作为参数,但传递了 Nat ``` From d8a3521c663446df55d5b3b464aebbd3196aabae Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 14:22:45 +0800 Subject: [PATCH 13/42] translate save --- doc/zh_CN/syntax/type/advanced/GADTs.md | 22 ++--- doc/zh_CN/syntax/type/advanced/_rank2type.md | 72 ++++++++-------- .../syntax/type/advanced/default_param.md | 12 +-- doc/zh_CN/syntax/type/advanced/erasure.md | 28 +++---- doc/zh_CN/syntax/type/advanced/existential.md | 28 +++---- .../syntax/type/advanced/keyword_param.md | 16 ++-- doc/zh_CN/syntax/type/advanced/kind.md | 84 +++++++++---------- .../syntax/type/advanced/marker_trait.md | 12 +-- doc/zh_CN/syntax/type/advanced/mut_struct.md | 24 +++--- doc/zh_CN/syntax/type/advanced/newtype.md | 22 ++--- doc/zh_CN/syntax/type/advanced/overloading.md | 43 +++++----- doc/zh_CN/syntax/type/advanced/phantom.md | 31 ++++--- doc/zh_CN/syntax/type/advanced/projection.md | 8 +- .../type/advanced/quantified_dependent.md | 16 ++-- 14 files changed, 208 insertions(+), 210 deletions(-) diff --git a/doc/zh_CN/syntax/type/advanced/GADTs.md b/doc/zh_CN/syntax/type/advanced/GADTs.md index 4d6cc616..8210a9dd 100644 --- a/doc/zh_CN/syntax/type/advanced/GADTs.md +++ b/doc/zh_CN/syntax/type/advanced/GADTs.md @@ -1,6 +1,6 @@ -# Generalized Algebraic Data Types (GADTs) +# 广义代数数据类型 (GADT) -Erg can create Generalized Algebraic Data Types (GADTs) by classifying Or types. +Erg 可以通过对 Or 类型进行分类来创建广义代数数据类型 (GADT)。 ```python Nil T = Class(Impl := Phantom T) @@ -15,18 +15,18 @@ List. {nil; cons; ...} = List print! cons(1, cons(2, nil())).head() # 1 -print! nil.head() # RuntimeError: "empty list" +print! nil.head() # 运行时错误:“空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. +我们说 `List.nil|T|() = ...` 而不是 `List(T).nil() = ...` 的原因是我们在使用它时不需要指定类型。 ```python i = List.nil() _: List Int = cons 1, i ``` -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. +这里定义的 `List T` 是 GADTs,但它是一个幼稚的实现,并没有显示 GADTs 的真正价值。 +例如,上面的 .head 方法会在 body 为空时抛出运行时错误,但是这个检查可以在编译时进行。 ```python List: (Type, {"Empty", "Nonempty"}) -> Type @@ -40,11 +40,11 @@ List(T, "Nonempty"). {nil; cons; ...} = List print! cons(1, cons(2, nil())).head() # 1 -print! nil().head() # TypeError +print! nil().head() # 类型错误 ``` -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. +街上经常解释的 GADT 的一个例子是一个列表,可以像上面那样通过类型来判断内容是否为空。 +Erg 可以进一步细化以定义一个有长度的列表。 ```python List: (Type, Nat) -> Type @@ -60,7 +60,7 @@ List(_, N | N >= 2). {nil; cons; ...} = List print! cons(1, cons(2, nil)).pair() # [1, 2] -print! cons(1, nil).pair() # TypeError +print! cons(1, nil).pair() # 类型错误 print! cons(1, nil).head() # 1 -print! nil. head() # TypeError +print! nil. head() # 类型错误 ``` \ No newline at end of file diff --git a/doc/zh_CN/syntax/type/advanced/_rank2type.md b/doc/zh_CN/syntax/type/advanced/_rank2type.md index c46fc43b..40723063 100644 --- a/doc/zh_CN/syntax/type/advanced/_rank2type.md +++ b/doc/zh_CN/syntax/type/advanced/_rank2type.md @@ -1,29 +1,29 @@ -# rank-2 polymorphism +# rank-2 多态性 -> __Warning__: This document is out of date and contains errors in general. +> __Warning__:本文档已过时,一般包含错误。 -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 允许您定义接受各种类型的函数,例如 `id|T|(x: T): T = x`,即多相关。 +那么,我们可以定义一个接受多相关的函数吗? +比如这样的函数(注意这个定义是错误的): ```python -# I want tuple_map(i -> i * 2, (1, "a")) == (2, "aa") +# 我想要 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. +注意 `1` 和 `"a"` 有不同的类型,所以匿名函数一次不是单态的。 需要单相两次。 +这样的函数不能在我们目前讨论的类型范围内定义。 这是因为类型变量没有范围的概念。 +让我们暂时离开类型,看看值级别的范围概念。 ```python arr = [1, 2, 3] arr.map i -> i + 1 ``` -`arr` and `i` in the code above are variables in different scopes. Therefore, each life span is different (`i` is shorter). +上面代码中的 `arr` 和 `i` 是不同作用域的变量。 因此,每个寿命都是不同的(`i` 更短)。 -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. +到目前为止,所有类型变量的类型都具有相同的生命周期。 换句话说,‘T’、‘X’和‘Y’必须同时确定,之后保持不变。 +反之,如果我们可以将 `T` 视为“内部作用域”中的类型变量,我们可以组成一个 `tuple_map` 函数。 __Rank 2 type__ 就是为此目的而准备的。 ```python # tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) @@ -31,26 +31,26 @@ 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. +`{(type) | 形式的类型 (类型变量列表)}` 被称为通用类型(详见[通用类型](./../quantified.md))。 +目前我们看到的`id`函数是一个典型的通用函数=多相关函数。 ```python id x = x id: |T: Type| T -> T ``` -A universal type has special rules for association with the function type constructor `->`, and the semantics of the type are completely different depending on the way of association. +通用类型与函数类型构造函数`->`的关联有特殊的规则,根据关联的方式,类型的语义是完全不同的。 -Think about this in terms of simple one-argument functions. +用简单的单参数函数来考虑这一点。 ```python -f1: (T -> T) -> Int | T # a function that takes any function and returns an Int -f2: (|T: Type| T -> T) -> Int # Function that receives polycorrelation and returns Int -f3: Int -> (|T: Type| T -> T) # A function that takes an Int and returns a closed universal function -f4: |T: Type|(Int -> (T -> T)) # Same as above (preferred) +f1: (T -> T) -> 整数 | T # 接受任何函数并返回 Int 的函数 +f2: (|T: Type| T -> T) -> Int # 接收多相关并返回 Int 的函数 +f3: Int -> (|T: Type| T -> T) # 一个函数,接受一个 Int 并返回一个封闭的通用函数 +f4: |T: Type|(Int -> (T -> T)) # 同上(首选) ``` -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. +`f1` 和 `f2` 不同,而 `f3` 和 `f4` 相同,这似乎很奇怪。 让我们实际构造一个这种类型的函数。 ```python # id: |T: Type| T -> T @@ -83,21 +83,21 @@ 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. +开放的多相关函数类型具体称为 __任意函数类型__。 任意函数类型有无数种可能性:`Int -> Int`、`Str -> Str`、`Bool -> Bool`、`|T: Type| T -> T`, ... 是。 +另一方面,只有一个封闭的(返回与参数相同类型的对象)多态类型`|T:Type| T -> T`。 这种类型被专门称为 __多态函数类型__。 +也就是说,`f1`可以通过`x: Int -> x+1`、`x: Bool -> not x`、`x -> x`等=`f1`是一个多相关数是的, 但是您只能将 `x -> x` 等传递给 `f2` = `f2` 不是 __多元相关__。 +但是像`f2`这样的函数类型明显不同于普通类型,我们需要新的概念来处理它们。 那是类型的“等级”。 -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". +关于rank的定义,没有量化的类型,如`Int`、`Str`、`Bool`、`T`、`Int -> Int`、`Option Int`等,都被视为“rank” 0”。 ```python -# K is a polynomial kind such as Option +# K 是多项式类型,例如 Option R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0) ``` -Next, types with first-order universal quantification, such as `|T| T -> T`, or types that include them in the return value type are “rank 1”. -In addition, types with second-order universal quantification (types that have rank 1 types as arguments such as `(|T| T -> T) -> Int`) or types that include them in the return type are called "rank 2 ”. -The above is repeated to define the “Rank N” type. Also, the rank-N types include all types with a rank of N or less. Therefore, a type with mixed ranks has the same rank as the highest among them. +接下来,具有一阶全称的类型,例如`|T| T -> T`,或者在返回值类型中包含它们的类型是“rank 1”。 +此外,具有二阶全称量化的类型(具有 rank 1 类型作为参数的类型,例如 `(|T| T -> T) -> Int`)或将它们包含在返回类型中的类型称为“rank 2 ”。 +重复上述以定义“Rank N”类型。 此外,秩-N 类型包括秩为N 或更少的所有类型。 因此,混合等级的类型与其中最高的等级相同。 ```python R1 = (|...| R0) or (R0 -> R1) or K(R1) or R0 @@ -106,7 +106,7 @@ R2 = (|...| R1) or (R1 -> R2) or K(R2) or R1 Rn = (|...| Rn-1) or (Rn-1 -> Rn) or K(Rn) or Rn-1 ``` -Let's look at some examples. +让我们看看例子: ```python (|T: Type| T -> T) -> (|U: Type| U -> U) @@ -120,7 +120,7 @@ Option(|T: Type| T -> T) => R1 ``` -By definition, `tuple_map` is a rank-2 type. +根据定义,`tuple_map` 是 rank-2 类型。 ```python tuple_map: @@ -130,13 +130,13 @@ tuple_map: => R2 ``` -Erg can handle types up to rank 2 (because rank N types include all types with rank N or less, to be exact, all Erg types are rank 2 types). Attempting to construct a function of more types is an error. -For example, all functions that handle polycorrelations as they are require specification of other argument types. Also, such a function is not configurable. +Erg 最多可以处理 rank 2 的类型(因为 rank N 类型包括所有 rank N 或更少的类型,确切地说,所有 Erg 类型都是 rank 2 类型)。 试图构造更多类型的函数是错误的。 +例如,所有处理多相关的函数都需要指定其他参数类型。 而且,这样的功能是不可配置的。 ```python -# this is a rank-3 type function +# 这是一个 rank-3 类型的函数 # |X, Y: Type|((|T: Type| T -> T), (X, Y)) -> (X, Y) generic_tuple_map|X, Y: Type| f: (|T: Type| T -> T), tup: (X, Y) = (f(tup.0), f(tup.1)) ``` -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 +众所周知,具有 3 级或更高等级的类型在理论上无法通过类型推断来确定。 然而,大多数实际需求可以被等级 2 类型覆盖。 \ No newline at end of file diff --git a/doc/zh_CN/syntax/type/advanced/default_param.md b/doc/zh_CN/syntax/type/advanced/default_param.md index d7bf81ab..34b2a88d 100644 --- a/doc/zh_CN/syntax/type/advanced/default_param.md +++ b/doc/zh_CN/syntax/type/advanced/default_param.md @@ -1,6 +1,6 @@ -# Function type with default arguments +# 带默认参数的函数类型 -First, let's look at an example of using default arguments. +首先,让我们看一个使用默认参数的示例。 ```python f: (Int, Int, z := Int) -> Int @@ -16,13 +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. +`:=` 之后的参数是默认参数。 +子类型规则如下: ```python ((X, y := Y) -> Z) <: (X -> Z) ((X, y := Y, ...) -> Z) <: ((X, ...) -> Z) ``` -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 +第一个意味着可以用没有默认参数的函数来识别具有默认参数的函数。 +第二个意味着可以省略任何默认参数。 \ 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 d9d418d2..3c751caf 100644 --- a/doc/zh_CN/syntax/type/advanced/erasure.md +++ b/doc/zh_CN/syntax/type/advanced/erasure.md @@ -1,43 +1,43 @@ -# Type erasure +# 类型擦除 -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. +类型擦除是将类型参数设置为 `_` 并故意丢弃其信息的过程。类型擦除是许多多态语言的特性,但在 Erg 的语法上下文中,将其称为类型参数擦除更为准确。 -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 方法 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. +类型擦除的最常见示例是 `[T, _]`。数组在编译时并不总是知道它们的长度。例如,引用命令行参数的 `sys.argv` 的类型为 `[Str, _]`。由于 Erg 的编译器无法知道命令行参数的长度,因此必须放弃有关其长度的信息。 +然而,一个已经被类型擦除的类型变成了一个未被擦除的类型的超类型(例如`[T; N] <: [T; _]`),所以它可以接受更多的对象。 +类型的对象`[T; N]` 当然可以使用 `[T; _]`,但使用后会删除`N`信息。如果长度没有改变,那么可以使用`[T; N]` 在签名中。如果长度保持不变,则必须由签名指示。 ```python -# Functions that are guaranteed to not change the length of the array (e.g., sort) -f: [T; N] -> [T; N] # functions that do not (f: [T; N]) -# functions that do not (e.g. filter) +# 保证不改变数组长度的函数(例如,排序) +f: [T; N] -> [T; N] # 没有的函数 (f: [T; N]) +# 没有的功能(例如过滤器) g: [T; n] -> [T; _] ``` -If you use `_` in the type specification itself, the type is upcast to `Object`. -For non-type type arguments (Int, Bool, etc.), the parameter with `_` will be undefined. +如果您在类型规范本身中使用 `_`,则类型将向上转换为 `Object`。 +对于非类型类型参数(Int、Bool 等),带有 `_` 的参数将是未定义的。 ```python i: _ # i: Object [_; _] == [Object; _] == Array ``` -Type erasure is not the same as omitting a type specification. Once the type argument information has been erased, it will not be returned unless you assert it again. +类型擦除与省略类型说明不同。 一旦类型参数信息被删除,除非您再次声明它,否则它不会被返回。 ```python implicit = (1..5).iter().map(i -> i * 2).to_arr() explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat)) ``` -In Rust, this corresponds to the following code. +在 Rust 中,这对应于以下代码: ```rust let partial = (1..6).iter().map(|i| i * 2).collect::>(); ``` -Erg does not allow partial omission of types, but uses higher-order kind polymorphism instead. +Erg 不允许部分省略类型,而是使用高阶种类多态性。 ```python -# collect is a higher-order Kind method that takes Kind +# collect 是采用 Kind 的高阶 Kind 方法 hk = (1..5).iter().map(i -> i * 2).collect(Array) hk: Array(Int) ``` diff --git a/doc/zh_CN/syntax/type/advanced/existential.md b/doc/zh_CN/syntax/type/advanced/existential.md index 34c385fa..f28b67ed 100644 --- a/doc/zh_CN/syntax/type/advanced/existential.md +++ b/doc/zh_CN/syntax/type/advanced/existential.md @@ -1,23 +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. +如果存在对应于∀的for-all类型,那么很自然地假设存在对应于∃的存在类型。 +存在类型并不难。 你已经知道存在类型,只是没有意识到它本身。 ```python T: Trait f x: T = ... ``` -The trait `T` above is used as the existential type. -In contrast, `T` in the lower case is only a trait, and `X` is an for-all type. +上面的 trait `T` 被用作存在类型。 +相比之下,小写的`T`只是一个特征,`X`是一个for-all类型。 ```python f|X <: T| x: X = ... ``` -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. +事实上,existential 类型被 for-all 类型所取代。 那么为什么会有存在类型这样的东西呢? +首先,正如我们在上面看到的,存在类型不涉及类型变量,这简化了类型规范。 +此外,由于可以删除类型变量,因此如果它是一个全推定类型,则可以构造一个等级为 2 或更高的类型。 ```python show_map f: (|T| T -> T), arr: [Show; _] = @@ -27,15 +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. +但是,如您所见,existential 类型忘记或扩展了原始类型,因此如果您不想扩展返回类型,则必须使用 for-all 类型。 +相反,仅作为参数且与返回值无关的类型可以写为存在类型。 ```python -# id(1): I want it to be Int +# id(1): 我希望它是 Int id|T|(x: T): T = x -# |S <: Show|(s: S) -> () is redundant +# |S <: Show|(s: S) -> () 是多余的 show(s: Show): () = log s ``` -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. +顺便说一句,类不称为存在类型。 一个类不被称为存在类型,因为它的元素对象是预定义的。 +存在类型是指满足某种特征的任何类型,它不是知道实际分配了什么类型的地方。 \ No newline at end of file diff --git a/doc/zh_CN/syntax/type/advanced/keyword_param.md b/doc/zh_CN/syntax/type/advanced/keyword_param.md index 789fbe7e..0989b952 100644 --- a/doc/zh_CN/syntax/type/advanced/keyword_param.md +++ b/doc/zh_CN/syntax/type/advanced/keyword_param.md @@ -1,22 +1,22 @@ -# Function type with keyword arguments +# 带有关键字参数的函数类型 ```python h(f) = f(y: 1, x: 2) -h: |T: Type|((y: Int, x: Int) -> T) -> T +h: |T: type|((y: Int, x: Int) -> T) -> T ``` -The subtyping rules for functions with keyword arguments are as follows. +带有关键字参数的函数的子类型化规则如下。 ```python -((x: T, y: U) -> V) <: ((T, U) -> V) # x, y are arbitrary keyword parameters +((x: T, y: U) -> V) <: ((T, U) -> V) # x, y 为任意关键字参数 ((y: U, x: T) -> V) <: ((x: T, y: U) -> V) ((x: T, y: U) -> V) <: ((y: U, x: T) -> V) ``` -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. +这意味着可以删除或替换关键字参数。 +但是你不能同时做这两件事。 +也就是说,您不能将 `(x: T, y: U) -> V` 转换为 `(U, T) -> V`。 +请注意,关键字参数仅附加到顶级元组,而不附加到数组或嵌套元组。 ```python Valid: [T, U] -> V diff --git a/doc/zh_CN/syntax/type/advanced/kind.md b/doc/zh_CN/syntax/type/advanced/kind.md index f9149482..41fa24fe 100644 --- a/doc/zh_CN/syntax/type/advanced/kind.md +++ b/doc/zh_CN/syntax/type/advanced/kind.md @@ -1,44 +1,44 @@ # 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 `*`. +一切都在 Erg 中输入。类型本身也不例外。 __kind__ 表示“类型的类型”。例如,`Int` 属于 `Type`,就像 `1` 属于 `Int`。 `Type` 是最简单的一种,__atomic kind__。在类型论符号中,`Type` 对应于 `*`。 -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. +在Kind的概念中,实际上重要的是一种或多种Kind(多项式Kind)。单项类型,例如`Option`,属于它。一元Kind表示为 `Type -> Type` [1](#1)。诸如 `Array` 或 `Option` 之类的 __container__ 特别是一种以类型作为参数的多项式类型。 +正如符号 `Type -> Type` 所表明的,`Option` 实际上是一个接收类型 `T` 并返回类型 `Option T` 的函数。但是,由于这个函数不是通常意义上的函数,所以通常称为一元类。 -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型。 -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. +另请注意,不是原子Kind的Kind不是类型。正如 `-1` 是一个数字但 `-` 不是,`Option Int` 是一个类型但 `Option` 不是。 `Option` 等有时被称为类型构造函数。 ```python assert not Option in Type assert Option in Type -> Type ``` -So code like the following will result in an error: -In Erg, 方法 can only be defined in atomic kinds, and the name `self` cannot be used anywhere other than the first argument of a method. +所以像下面这样的代码会报错: +在 Erg 中,方法只能在原子类型中定义,并且名称 `self` 不能在方法的第一个参数以外的任何地方使用。 ```python -#K is an unary kind +#K 是一元类型 K: Type -> Type K T = Class... K. - foo x = ... # OK, this is like a so-called static method - bar self, x = ... # TypeError: cannot define a method to a non-type object +foo x = ... # OK,这就像是所谓的静态方法 + bar self, x = ... # 类型错误: 无法为非类型对象定义方法 K(T). baz self, x = ... # OK ``` -Examples of binary or higher kinds are `{T: U}`(: `(Type, Type) -> Type`), `(T, U, V)`(: `(Type, Type, Type) - > Type`), ... and so on. +二进制或更高类型的示例是 `{T: U}`(: `(Type, Type) -> Type`), `(T, U, V)`(: `(Type, Type, Type) - > Type `), ... 等等。 -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`. +还有一个零项类型`() -> Type`。 这有时等同于类型论中的原子类型,但在 Erg 中有所区别。 一个例子是`类`。 ```python Nil = Class() ``` -## Containment of kind +## 收容类 -There is also a partial type relation, or rather a partial kind relation, between multinomial kinds. +多项类型之间也存在部分类型关系,或者更确切地说是部分类型关系。 ```python K T = ... @@ -46,15 +46,15 @@ L = Inherit K L<: K ``` -That is, for any `T`, if `L T <: K T`, then `L <: K`, and vice versa. +也就是说,对于任何 `T`,如果 `L T <: K T`,则 `L <: K`,反之亦然。 ```python ∀T. L T <: K T <=> L <: K ``` -## higher 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. +还有一种高阶Kind。 这是一种与高阶函数相同的概念,一种自身接收一种类型。 `(Type -> Type) -> Type` 是一种更高的Kind。 让我们定义一个属于更高Kind的对象。 ```python IntContainerOf K: Type -> Type = K Int @@ -63,47 +63,46 @@ assert IntContainerOf Result == Result Int assert IntContainerOf in (Type -> Type) -> Type ``` -The bound variables of a polynomial kind are usually denoted as K, L, ..., where K is K for Kind. +多项式类型的有界变量通常表示为 K, L, ...,其中 K 是 Kind 的 K -## set kind +## 设置Kind -In type theory, there is the concept of a record. This is almost the same as the Erg record [2](#2). +在类型论中,有记录的概念。 这与 Erg 记录 [2](#2) 几乎相同。 ```python -# This is a record, and it corresponds to what is called a record in type theory +# 这是一条记录,对应于类型论中所谓的记录 {x = 1; y = 2} ``` -When all record values ​​were types, it was a kind of type called a record type. +当所有的记录值都是类型时,它是一种类型,称为记录类型。 ```python assert {x = 1; y = 2} in {x = Int; y = Int} ``` -A record type types a record. A good guesser might have thought that there should be a "record kind" to type the record type. Actually it exists. +记录类型键入记录。 一个好的猜测者可能认为应该有一个“记录类型”来键入记录类型。 实际上它是存在的。 ```python log Typeof {x = Int; y = Int} # {{x = Int; y = Int}} ``` -A type like `{{x = Int; y = Int}}` is a record kind. This is not a special notation. It is simply an enumeration type that has only `{x = Int; y = Int}` as an element. +像 `{{x = Int; 这样的类型 y = Int}}` 是一种记录类型。 这不是一个特殊的符号。 它只是一个枚举类型,只有 `{x = Int; y = Int}` 作为一个元素。 ```python Point = {x = Int; y = Int} Pointy = {Point} ``` -An important property of record kind is that if `T: |T|` and `U <: T` then `U: |T|`. -This is also evident from the fact that enums are actually syntactic sugar for sieve types. +记录类型的一个重要属性是,如果 `T: |T|` 和 `U <: T` 则 `U: |T|`。 +从枚举实际上是筛子类型的语法糖这一事实也可以看出这一点。 ```python -# {c} == {X: T | X == c} for normal objects, but -# Equality may not be defined for types, so |T| == {X | X <: T} +# {c} == {X: T | X == c} 对于普通对象,但是不能为类型定义相等性,所以 |T| == {X | X <: T} {Point} == {P | P <: Point} ``` -`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. +类型约束中的 `U <: T` 实际上是 `U: |T|` 的语法糖。 +作为此类类型的集合的种类通常称为集合种类。 Setkind 也出现在迭代器模式中。 ```python Iterable T = Trait { @@ -112,7 +111,7 @@ Iterable T = Trait { } ``` -## Type inference for polynomial kinds +## 多项式类型的类型推断 ```python Container K: Type -> Type, T: Type = Patch K(T, T) @@ -128,22 +127,21 @@ Fn2 T, U: Type = Patch T -> U Fn2(T, U). f self = ... -(Int -> Int).f() # which one is selected? +(Int -> Int).f() # 选择了哪一个? ``` +在上面的示例中,方法 `f` 会选择哪个补丁? +天真,似乎选择了`Fn T`,但是`Fn2 T,U`也是可以的,`Option T`原样包含`T`,所以任何类型都适用,`Container K,T`也匹配`->(Int, Int)`,即 `Container(`->`, Int)` 为 `Int -> Int`。因此,上述所有四个修复程序都是可能的选择。 -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 修补程序 above are possible options. +在这种情况下,根据以下优先标准选择修复程序。 -In this case, 修补程序 are selected according to the following priority criteria. - -* 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. +* 任何 `K(T)`(例如 `T or NoneType`)优先匹配 `Type -> Type` 而不是 `Type`。 +* 任何 `K(T, U)`(例如 `T -> U`)优先匹配 `(Type, Type) -> Type` 而不是 `Type`。 +* 类似的标准适用于种类 3 或更多。 +* 选择需要较少类型变量来替换的那个。例如,`Int -> Int` 是 `T -> T` 而不是 `K(T, T)`(替换类型变量:K, T)或 `T -> U`(替换类型变量:T, U )。(替换类型变量:T)优先匹配。 +* 如果更换的次数也相同,则报错为不可选择。 --- -1 In type theory notation, `*=>*` [↩](#f1) +1 在类型理论符号中,`*=>*` [↩](#f1) -2 There are subtle differences such as visibility. [↩](#f2) \ No newline at end of file +2 可见性等细微差别。[↩](#f2) \ No newline at end of file diff --git a/doc/zh_CN/syntax/type/advanced/marker_trait.md b/doc/zh_CN/syntax/type/advanced/marker_trait.md index bbf90ad4..67227598 100644 --- a/doc/zh_CN/syntax/type/advanced/marker_trait.md +++ b/doc/zh_CN/syntax/type/advanced/marker_trait.md @@ -1,10 +1,10 @@ -# Marker 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. +标记特征是没有必需属性的特征。 也就是说,您可以在不实现任何方法的情况下实现 Impl。 +没有 required 属性似乎没有意义,但由于注册了它属于 trait 的信息,因此可以使用 patch 方法或由编译器进行特殊处理。 -All marker traits are subsumed by the `Marker` trait. -`Light` provided as standard is a kind of marker trait. +所有标记特征都包含在“标记”特征中。 +作为标准提供的“光”是一种标记特征。 ```python Light = Subsume Marker @@ -24,7 +24,7 @@ assert i + 1 == 2 assert i in M ``` -Marker classes can also be excluded with the `Excluding` argument. +标记类也可以使用 `Excluding` 参数排除。 ```python NInt = Inherit MarkedInt, Impl := N, Excluding: M diff --git a/doc/zh_CN/syntax/type/advanced/mut_struct.md b/doc/zh_CN/syntax/type/advanced/mut_struct.md index b23de3c9..871c8754 100644 --- a/doc/zh_CN/syntax/type/advanced/mut_struct.md +++ b/doc/zh_CN/syntax/type/advanced/mut_struct.md @@ -1,23 +1,23 @@ -# Mutable Structure Type +# 可变结构类型 -The ``T!`` type is described as a box type that can be replaced by any ``T`` type object. +`T!` 类型被描述为可以被任何 `T` 类型对象替换的盒子类型。 ```python Particle!State: {"base", "excited"}! = Class(... Impl := Phantom State) Particle! - # This method moves the State from "base" to "excited". + # 此方法将状态从“base”移动到“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. +`T!` 类型可以替换数据,但不能改变其结构。 +更像是一个真实程序的行为,它不能改变它的大小(在堆上)。 这样的类型称为不可变结构(mutable)类型。 -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. +事实上,有些数据结构不能用不变的结构类型来表示。 +例如,可变长度数组。 `[T; N]!`类型可以包含任何`[T; N]`,但不能被`[T; N+1]` 等等。 -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. +这是通过可变结构(可变)类型实现的。 ```python v = [Str; !0].new() @@ -25,10 +25,10 @@ v.push! "Hello" 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. +对于可变结构类型,可变类型参数用 `!` 标记。 在上述情况下,类型 `[Str; !0]` 可以更改为 `[Str; !1]` 等等。 即,可以改变长度。 +顺便说一句,`[T; !N]` 类型是 `ArrayWithLength!(T, !N)` 类型的糖衣语法。 -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. +可变结构类型当然可以是用户定义的。 但是请注意,在构造方法方面与不变结构类型存在一些差异。 ```python 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 067a04d6..7100c029 100644 --- a/doc/zh_CN/syntax/type/advanced/newtype.md +++ b/doc/zh_CN/syntax/type/advanced/newtype.md @@ -1,24 +1,24 @@ -# Newtype pattern +# 新类型模式 -Here is the Erg version of the newtype pattern commonly used in Rust. +这是 Rust 中常用的 newtype 模式的 Erg 版本。 -Erg allows type aliases to be defined as follows, but they only refer to the same type. +Erg 允许定义类型别名如下,但它们只引用相同的类型。 ```python -UserId = Int +UserID = Int ``` -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. +因此,例如,如果你有一个规范,类型为 `UserId` 的数字必须是一个正的 8 位数字,你可以输入 `10` 或 `-1`,因为它与类型 `Int` 相同 . 如果设置为 `Nat`,则可以拒绝 `-1`,但 8 位数字的性质不能仅用 Erg 的类型系统来表达。 -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. +此外,例如,在设计数据库系统时,假设有几种类型的 ID:用户 ID、产品 ID、产品 ID 和用户 ID。 如果 ID 类型的数量增加,例如用户 ID、产品 ID、订单 ID 等,可能会出现将不同类型的 ID 传递给不同函数的 bug。 即使用户 ID 和产品 ID 在结构上相同,但它们在语义上是不同的。 -The newtype pattern is a good design pattern for such cases. +对于这种情况,newtype 模式是一个很好的设计模式。 ```python UserId = Class {id = Nat} UserId. new id: Nat = - assert id.dights().len() == 8, else: "UserId must be a positive number with length 8" + assert id.dights().len() == 8, else: "UserId 必须是长度为 8 的正数" UserId::__new__ {id;} i = UserId.new(10000000) @@ -26,6 +26,6 @@ print! i # <__main__.UserId object> i + UserId.new(10000001) # TypeError: + is not implemented between `UserId` and `UserId ``` -The constructor guarantees the pre-condition of an 8-digit number. -The `UserId` loses all the 方法 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 方法 is desirable, so choose the appropriate method depending on the situation. +构造函数保证 8 位数字的前置条件。 +`UserId` 失去了 `Nat` 拥有的所有方法,所以每次都必须重新定义必要的操作。 +如果重新定义的成本不值得,最好使用继承。 另一方面,在某些情况下,方法丢失是可取的,因此请根据情况选择适当的方法。 diff --git a/doc/zh_CN/syntax/type/advanced/overloading.md b/doc/zh_CN/syntax/type/advanced/overloading.md index 99740240..3d75b07e 100644 --- a/doc/zh_CN/syntax/type/advanced/overloading.md +++ b/doc/zh_CN/syntax/type/advanced/overloading.md @@ -1,7 +1,7 @@ -# 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 不支持 __ad hoc 多态性__。 也就是说,函数和种类(重载)的多重定义是不可能的。 但是,您可以通过使用特征和补丁的组合来重现重载行为。 +您可以使用特征而不是特征类,但随后将涵盖所有实现 `.add1` 的类型。 ```python Add1 = Trait { @@ -19,10 +19,10 @@ assert add1(1) == 2 assert add1(1.0) == 2.0 ``` -Such a polymorphism by accepting all subtypes of a type is called __subtyping polymorphism__. +这种接受一个类型的所有子类型的多态称为__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. +如果每种类型的过程完全相同,则可以编写如下。 当行为从类到类(但返回类型相同)时,使用上述内容。 +使用类型参数的多态称为 __parametric polymorphism__。 参数多态性通常与子类型结合使用,如下所示,在这种情况下,它是参数和子类型多态性的组合。 ```python add1|T <: Int or Str| x: T = x + 1 @@ -30,7 +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. +此外,可以使用默认参数重现具有不同数量参数的类型的重载。 ```python C = Class {.x = Int; .y = Int} @@ -40,12 +40,13 @@ C. assert C.new(0, 0) == C.new(0) ``` -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. +综上所述,Erg 禁止重载,采用子类型加参数多态,原因如下。 + +首先,重载函数分布在它们的定义中。 这使得在发生错误时很难报告错误的原因。 +此外,导入子程序可能会改变已定义子程序的行为。 -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. ```python {id; ...} = import "foo" @@ -54,21 +55,21 @@ id x: Int = x ... id x: Ratio = x ... -id "str" # TypeError: id is not implemented for Str -# But... But... where did this error come from? +id "str" # 类型错误:没有为 Str 实现 id +# 但是……但是……这个错误是从哪里来的? ``` -Second, it is incompatible with default arguments. When a function with default arguments is overloaded, there is a problem with which one takes precedence. +其次,它与默认参数不兼容。 当具有默认参数的函数被重载时,会出现一个优先级的问题。 ```python f x: Int = ... f(x: Int, y := 0) = ... -f(1) # which is chosen? +f(1) # 选择哪个? ``` -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. +此外,它与声明不兼容。 +声明 `f: Num -> Num` 不能指定它引用的定义。 这是因为 `Int -> Ratio` 和 `Ratio -> Int` 不包含在内。 ```python f: Num -> Num @@ -76,14 +77,14 @@ f(x: Int): Ratio = ... f(x: Ratio): Int = ... ``` -And the grammar is inconsistent: Erg prohibits variable reassignment, but the overloaded grammar looks like reassignment. -Nor can it be replaced by an anonymous function. +并且语法不一致:Erg禁止变量重新赋值,但是重载的语法看起来像重新赋值。 +也不能用匿名函数代替。 ```python -# same as `f = x -> body` +# 同 `f = x -> body` f x = body -# same as... what? +# 一样……什么? f x: Int = x f x: Ratio = x ``` diff --git a/doc/zh_CN/syntax/type/advanced/phantom.md b/doc/zh_CN/syntax/type/advanced/phantom.md index 6caca4a7..84efb272 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 +# 幻影(phantom)类 -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. +幻像类型是标记特征,其存在仅用于向编译器提供注释。 +作为幻像类型的一种用法,让我们看一下列表的结构。 ```python Nil = Class() @@ -9,27 +9,26 @@ List T, 0 = Inherit Nil List T, N: Nat = Class {head = T; rest = List(T, N-1)} ``` -This code results in an error. +此代码导致错误。 ```python 3 | List T, 0 = Inherit Nil ^^^ -TypeConstructionError: since Nil does not have a parameter T, it is not possible to construct List(T, 0) with Nil -hint: use 'Phantom' trait to consume T +类型构造错误:由于Nil没有参数T,所以无法用Nil构造List(T, 0) +提示:使用 'Phantom' 特质消耗 T ``` -This error is a complaint that `T` cannot be type inferred when `List(_, 0).new Nil.new()` is used. -In such a case, whatever the `T` type is, it must be consumed on the right-hand side. A type of size zero, such as a tuple of length zero, is convenient because it has no runtime overhead. - +此错误是在使用 `List(_, 0).new Nil.new()` 时无法推断 `T` 的抱怨。 +在这种情况下,无论 `T` 类型是什么,它都必须在右侧使用。 大小为零的类型(例如长度为零的元组)很方便,因为它没有运行时开销。 ```python Nil T = Class((T; 0)) List T, 0 = Inherit Nil T List T, N: Nat = Class {head = T; rest = List(T, N-1)} ``` -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. +在这种情况下,幻影类型正是您所需要的。 幻像类型是大小为 0 的广义类型。 ```python Nil T = Class(Impl := Phantom T) @@ -40,10 +39,10 @@ nil = Nil(Int).new() assert nil.__size__ == 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`. +`Phantom` 拥有`T` 类型。 但实际上 `Phantom T` 类型的大小是 0 并且不包含 `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. +此外,`Phantom` 可以使用除其类型之外的任意类型参数。 在下面的示例中,`Phantom` 包含一个名为 `State` 的类型参数,它是 `Str` 的子类型对象。 +同样,`State` 是一个假的类型变量,不会出现在对象的实体中。 ```python VM! State: {"stopped", "running"}! = Class(... State) @@ -53,5 +52,5 @@ VM!("stopped"). self::set_phantom!("running")) ``` -The `state` is updated via the `update_phantom!` or `set_phantom!` 方法. -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!`. +`state` 是通过 `update_phantom!` 或 `set_phantom!` 方法更新的。 +这是标准补丁为`Phantom!`(`Phantom`的变量版本)提供的方法,其用法与变量`update!`和`set!`相同。 \ No newline at end of file diff --git a/doc/zh_CN/syntax/type/advanced/projection.md b/doc/zh_CN/syntax/type/advanced/projection.md index 57668930..9ecaf889 100644 --- a/doc/zh_CN/syntax/type/advanced/projection.md +++ b/doc/zh_CN/syntax/type/advanced/projection.md @@ -1,6 +1,6 @@ -# Projection Type +# 投影类型 -A projection type represents a type such as ``Self.AddO`` in the following code. +投影类型表示如下代码中的“Self.AddO”等类型。 ```python Add R = Trait { @@ -13,8 +13,8 @@ AddForInt. AddO = Int ``` -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`. +类型“Add(R)”可以说是定义了与某个对象的加法的类型。 由于方法应该是一个类型属性,`+` 类型声明应该写在缩进下面。 +`Add` 类型的场景是声明 `.AddO = Type`,而 `.AddO` 类型的实体是一个投影类型,由一个作为 ` 子类型的类型持有 添加`。 例如,`Int.AddO = Int`、`Odd.AddO = Even`。 ```python 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 ab5bc0f2..c96caca5 100644 --- a/doc/zh_CN/syntax/type/advanced/quantified_dependent.md +++ b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md @@ -1,15 +1,15 @@ -# 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 有量化和依赖类型。 那么很自然地,就可以创建一个将两者结合起来的类型。 那是量化的依赖类型。 ```python -NonNullStr = |N: Nat| StrWithLen N | N ! = 0 # same as {S | N: Nat; S: StrWithLen N; N ! = 0} -NonEmptyArray = |N: Nat| [_; N | N > 0] # same as {A | N: Nat; A: Array(_, N); N > 0} +NonNullStr = |N: Nat| StrWithLen N | N ! = 0 # 同 {S | N: Nat; S: StrWithLen N; N ! = 0} +NonEmptyArray = |N: Nat| [_; N | N > 0] # 同 {A | N: Nat; A: Array(_, N); N > 0} ``` -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. +量化依赖类型的标准形式是“K(A, ... | Pred)”。 `K` 是类型构造函数,`A, B` 是类型参数,`Pred` 是条件表达式。 -Quantified dependent types as left-hand side values can only define 方法 in the same module as the original type. +作为左值的量化依赖类型只能在与原始类型相同的模块中定义方法。 ```python K A: Nat = Class ... @@ -19,9 +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 (`||`). +作为右值的量化依赖类型需要在类型变量列表 (`||`) 中声明要使用的类型变量。 ```python -# T is a concrete type +# T 是具体类型 a: |N: Nat| [T; N | N > 1] ``` From 438bcb89ea692f219b30f3a3ba107888b23eae98 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 16:25:35 +0800 Subject: [PATCH 14/42] trifle --- doc/EN/syntax/indexes.md | 132 ++++++++++++++++++------------------ doc/zh_CN/syntax/indexes.md | 130 +++++++++++++++++------------------ 2 files changed, 131 insertions(+), 131 deletions(-) diff --git a/doc/EN/syntax/indexes.md b/doc/EN/syntax/indexes.md index 9a530a07..5d3d19df 100644 --- a/doc/EN/syntax/indexes.md +++ b/doc/EN/syntax/indexes.md @@ -8,7 +8,7 @@ See [here](../dev_guide/terms.md) for terminology. * ! * !-type → [mutable type](./type/mut.md) * [#](./00_basic.md/#comment) -*$ +* $ * % * & * && @@ -62,130 +62,130 @@ See [here](../dev_guide/terms.md) for terminology. ### A -* [algebraic type] -* [And] -* [and] -* [assert] -* [attribute] +* algebraic type +* And +* and +* assert +* attribute -###B +### B -* [Base] -* [Bool] +* Base +* Bool ### C -* [Class] +* Class -###D +### D -*Deprecated -* [distinct] +* Deprecated +* distinct -###E +### E -* [enum type] -*[Eq] -*[Erg] +* enum type +* Eq +* Erg -###F +### F -*[for] +* for -###G +### G -###H +### H ### I -* [if] -* [import] -* [in] -* [Int] +* if +* import +* in +* Int -###J +### J -###K +### K ### L * let-polymorphism → [rank 1 polymorphism] -* [log] +* log -###M +### M -* [match] +* match -###N +### N -*[Nat] +* Nat * Never -*None -*None -*[Not] -* [not] +* None +* None +* Not +* not -###O +### O -* [Option] -* [Or] -* [or] -*[Ord] +* Option +* Or +* or +* Ord -###P +### P * panic * [print!](./../API/procs.md#print) -* [Python] +* Python -###Q +### Q ### R * ref -*ref! -* [Result] -*[rootobj] +* ref! +* Result +* rootobj -###S +### S -*self +* self * [Self](./type/special.md) * [side-effect](./07_side_effect.md) -*[Str] +* Str -###T +### T * Traits -* [True] -* [Type] -* [type] +* True +* Type +* type -###U +### U -###V +### V ### W -* [while!] +* while! -###X +### X -###Y +### Y -###Z +### Z ## A line -* [Assertion] +* Assertion * value object * [Attachment patch](./29_decorator.md#attach) * Ad-hoc polymorphism → [No overloading](./type/overloading.md) -* Attribute → [Attribute] +* Attribute → Attribute * arity * [dependent type](./type/dependent_type.md) -* immutable → [immutable] -* Argument → [Argument] +* immutable → immutable +* Argument → Argument * instance * [instant block](./00_basic.md# expression separator) * index @@ -198,7 +198,7 @@ See [here](../dev_guide/terms.md) for terminology. * Override * [No overloading](./type/overloading.md) * Offside rule → [indent](./00_basic.md#indent) -* [object] +* object * Object-orientation * Operand → [operand](./06_operator.md) * operator → [operator](./06_operator.md) @@ -416,7 +416,7 @@ See [here](../dev_guide/terms.md) for terminology. * [anonymous function](./21_lambda.md) * mutable → [mutable] * [Move] -* methods +* 方法 * Metacharacter * [module](./24_module.md) * [String] → [Str] diff --git a/doc/zh_CN/syntax/indexes.md b/doc/zh_CN/syntax/indexes.md index 37c89de9..5d3d19df 100644 --- a/doc/zh_CN/syntax/indexes.md +++ b/doc/zh_CN/syntax/indexes.md @@ -8,7 +8,7 @@ See [here](../dev_guide/terms.md) for terminology. * ! * !-type → [mutable type](./type/mut.md) * [#](./00_basic.md/#comment) -*$ +* $ * % * & * && @@ -62,130 +62,130 @@ See [here](../dev_guide/terms.md) for terminology. ### A -* [algebraic type] -* [And] -* [and] -* [assert] -* [attribute] +* algebraic type +* And +* and +* assert +* attribute -###B +### B -* [Base] -* [Bool] +* Base +* Bool ### C -* [Class] +* Class -###D +### D -*Deprecated -* [distinct] +* Deprecated +* distinct -###E +### E -* [enum type] -*[Eq] -*[Erg] +* enum type +* Eq +* Erg -###F +### F -*[for] +* for -###G +### G -###H +### H ### I -* [if] -* [import] -* [in] -* [Int] +* if +* import +* in +* Int -###J +### J -###K +### K ### L * let-polymorphism → [rank 1 polymorphism] -* [log] +* log -###M +### M -* [match] +* match -###N +### N -*[Nat] +* Nat * Never -*None -*None -*[Not] -* [not] +* None +* None +* Not +* not -###O +### O -* [Option] -* [Or] -* [or] -*[Ord] +* Option +* Or +* or +* Ord -###P +### P * panic * [print!](./../API/procs.md#print) -* [Python] +* Python -###Q +### Q ### R * ref -*ref! -* [Result] -*[rootobj] +* ref! +* Result +* rootobj -###S +### S -*self +* self * [Self](./type/special.md) * [side-effect](./07_side_effect.md) -*[Str] +* Str -###T +### T * Traits -* [True] -* [Type] -* [type] +* True +* Type +* type -###U +### U -###V +### V ### W -* [while!] +* while! -###X +### X -###Y +### Y -###Z +### Z ## A line -* [Assertion] +* Assertion * value object * [Attachment patch](./29_decorator.md#attach) * Ad-hoc polymorphism → [No overloading](./type/overloading.md) -* Attribute → [Attribute] +* Attribute → Attribute * arity * [dependent type](./type/dependent_type.md) -* immutable → [immutable] -* Argument → [Argument] +* immutable → immutable +* Argument → Argument * instance * [instant block](./00_basic.md# expression separator) * index @@ -198,7 +198,7 @@ See [here](../dev_guide/terms.md) for terminology. * Override * [No overloading](./type/overloading.md) * Offside rule → [indent](./00_basic.md#indent) -* [object] +* object * Object-orientation * Operand → [operand](./06_operator.md) * operator → [operator](./06_operator.md) From 7a489e9d84bda88cc9f2b0811870ded967f59567 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 18:31:32 +0800 Subject: [PATCH 15/42] translate save --- doc/zh_CN/syntax/00_basic.md | 2 +- doc/zh_CN/syntax/01_literal.md | 2 +- doc/zh_CN/syntax/02_name.md | 2 +- doc/zh_CN/syntax/03_declaration.md | 2 +- doc/zh_CN/syntax/04_function.md | 2 +- doc/zh_CN/syntax/05_builtin_funcs.md | 2 +- doc/zh_CN/syntax/06_operator.md | 2 +- doc/zh_CN/syntax/07_side_effect.md | 2 +- doc/zh_CN/syntax/08_procedure.md | 2 +- doc/zh_CN/syntax/09_builtin_procs.md | 2 +- doc/zh_CN/syntax/10_array.md | 2 +- doc/zh_CN/syntax/11_tuple.md | 2 +- doc/zh_CN/syntax/12_dict.md | 2 +- doc/zh_CN/syntax/13_record.md | 2 +- doc/zh_CN/syntax/14_set.md | 2 +- doc/zh_CN/syntax/15_type.md | 2 +- doc/zh_CN/syntax/16_iterator.md | 2 +- doc/zh_CN/syntax/17_mutability.md | 2 +- doc/zh_CN/syntax/18_ownership.md | 2 +- doc/zh_CN/syntax/19_visibility.md | 2 +- doc/zh_CN/syntax/20_naming_rule.md | 2 +- doc/zh_CN/syntax/21_lambda.md | 2 +- doc/zh_CN/syntax/22_subroutine.md | 2 +- doc/zh_CN/syntax/23_closure.md | 2 +- doc/zh_CN/syntax/24_module.md | 2 +- doc/zh_CN/syntax/25_object_system.md | 2 +- doc/zh_CN/syntax/26_pattern_matching.md | 2 +- doc/zh_CN/syntax/27_comprehension.md | 2 +- doc/zh_CN/syntax/28_spread_syntax.md | 2 +- doc/zh_CN/syntax/29_decorator.md | 2 +- doc/zh_CN/syntax/30_error_handling.md | 2 +- doc/zh_CN/syntax/31_pipeline.md | 2 +- .../syntax/32_integration_with_Python.md | 2 +- doc/zh_CN/syntax/33_package_system.md | 2 +- doc/zh_CN/syntax/34_generator.md | 2 +- doc/zh_CN/syntax/type/01_type_system.md | 136 ++++++++-------- doc/zh_CN/syntax/type/02_basic.md | 84 +++++----- doc/zh_CN/syntax/type/03_trait.md | 78 ++++----- doc/zh_CN/syntax/type/04_class.md | 152 +++++++++--------- doc/zh_CN/syntax/type/05_inheritance.md | 149 +++++++++-------- doc/zh_CN/syntax/type/06_nst_vs_sst.md | 14 +- doc/zh_CN/syntax/type/07_patch.md | 90 +++++------ doc/zh_CN/syntax/type/08_value.md | 14 +- doc/zh_CN/syntax/type/09_attributive.md | 12 +- doc/zh_CN/syntax/type/10_interval.md | 22 +-- doc/zh_CN/syntax/type/11_enum.md | 32 ++-- doc/zh_CN/syntax/type/12_refinement.md | 46 +++--- doc/zh_CN/syntax/type/13_algebraic.md | 36 ++--- doc/zh_CN/syntax/type/advanced/shared.md | 38 ++--- doc/zh_CN/syntax/type/advanced/special.md | 10 +- doc/zh_CN/syntax/type/advanced/typeof.md | 30 ++-- doc/zh_CN/syntax/type/advanced/variance.md | 121 +++++++------- doc/zh_CN/syntax/type/advanced/widening.md | 64 ++++---- 53 files changed, 598 insertions(+), 600 deletions(-) diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md index 651caf2f..a1383dfd 100644 --- a/doc/zh_CN/syntax/00_basic.md +++ b/doc/zh_CN/syntax/00_basic.md @@ -144,5 +144,5 @@ x \ ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/01_literal.md b/doc/zh_CN/syntax/01_literal.md index 3411024d..8c85b141 100644 --- a/doc/zh_CN/syntax/01_literal.md +++ b/doc/zh_CN/syntax/01_literal.md @@ -145,5 +145,5 @@ assert 1m / 1s == 1 (m/s) ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/02_name.md b/doc/zh_CN/syntax/02_name.md index 63138c32..750cbfa8 100644 --- a/doc/zh_CN/syntax/02_name.md +++ b/doc/zh_CN/syntax/02_name.md @@ -160,5 +160,5 @@ print! C # ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/03_declaration.md b/doc/zh_CN/syntax/03_declaration.md index 1548c120..5c9e8924 100644 --- a/doc/zh_CN/syntax/03_declaration.md +++ b/doc/zh_CN/syntax/03_declaration.md @@ -43,5 +43,5 @@ C.f(a: Int, b: Int): Int = ... # TypeError: `.f` must be type of `(x: Int, y: In ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md index 36292785..962c90e0 100644 --- a/doc/zh_CN/syntax/04_function.md +++ b/doc/zh_CN/syntax/04_function.md @@ -286,5 +286,5 @@ 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 12aa1eeb..e696d9bb 100644 --- a/doc/zh_CN/syntax/05_builtin_funcs.md +++ b/doc/zh_CN/syntax/05_builtin_funcs.md @@ -45,5 +45,5 @@ match_s(ss: Iterator(Str), pat: Pattern): Option Str = ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/06_operator.md b/doc/zh_CN/syntax/06_operator.md index 087f6862..f4a25d01 100644 --- a/doc/zh_CN/syntax/06_operator.md +++ b/doc/zh_CN/syntax/06_operator.md @@ -25,5 +25,5 @@ function = `->` # SyntaxError: cannot bind `->` operator, this is a special form ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/07_side_effect.md b/doc/zh_CN/syntax/07_side_effect.md index 579898c1..e0604cbe 100644 --- a/doc/zh_CN/syntax/07_side_effect.md +++ b/doc/zh_CN/syntax/07_side_effect.md @@ -117,5 +117,5 @@ print! "this will be printed immediately" 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 a46e863a..3b4def38 100644 --- a/doc/zh_CN/syntax/08_procedure.md +++ b/doc/zh_CN/syntax/08_procedure.md @@ -8,5 +8,5 @@ peek_str s: Str! = log s ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/09_builtin_procs.md b/doc/zh_CN/syntax/09_builtin_procs.md index eff9af73..dd51f978 100644 --- a/doc/zh_CN/syntax/09_builtin_procs.md +++ b/doc/zh_CN/syntax/09_builtin_procs.md @@ -10,5 +10,5 @@ Although in pure Erg semantics no difference can be found between objects with t ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/10_array.md b/doc/zh_CN/syntax/10_array.md index fd42f8a3..d55c2135 100644 --- a/doc/zh_CN/syntax/10_array.md +++ b/doc/zh_CN/syntax/10_array.md @@ -48,5 +48,5 @@ print! Typeof l[1..2] # [Int; 4] ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/11_tuple.md b/doc/zh_CN/syntax/11_tuple.md index 403833b5..f232038e 100644 --- a/doc/zh_CN/syntax/11_tuple.md +++ b/doc/zh_CN/syntax/11_tuple.md @@ -113,5 +113,5 @@ f(0) ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/12_dict.md b/doc/zh_CN/syntax/12_dict.md index 3c03c35f..9f0b6929 100644 --- a/doc/zh_CN/syntax/12_dict.md +++ b/doc/zh_CN/syntax/12_dict.md @@ -63,5 +63,5 @@ valid2: {Int: Int or Str} = {1: "a", 2: 2} ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/13_record.md b/doc/zh_CN/syntax/13_record.md index 48a325dc..d5b2570f 100644 --- a/doc/zh_CN/syntax/13_record.md +++ b/doc/zh_CN/syntax/13_record.md @@ -195,5 +195,5 @@ john + 1 ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/14_set.md b/doc/zh_CN/syntax/14_set.md index 3bace4d6..ffbea36f 100644 --- a/doc/zh_CN/syntax/14_set.md +++ b/doc/zh_CN/syntax/14_set.md @@ -42,5 +42,5 @@ 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 8430dc74..76f0cee9 100644 --- a/doc/zh_CN/syntax/15_type.md +++ b/doc/zh_CN/syntax/15_type.md @@ -3,5 +3,5 @@ Types are a very important feature in Erg, so we have a [dedicated section](./type/01_type_system.md). Please see there.

- 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 2cd6802c..89ab4879 100644 --- a/doc/zh_CN/syntax/16_iterator.md +++ b/doc/zh_CN/syntax/16_iterator.md @@ -85,5 +85,5 @@ Types such as `Iterable` that provide an interface for handling traits (in this 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 47484bfa..f61711b9 100644 --- a/doc/zh_CN/syntax/17_mutability.md +++ b/doc/zh_CN/syntax/17_mutability.md @@ -99,5 +99,5 @@ In C, types and functions cannot be assigned to variables; int and main are iden 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 6c724767..492fa6bd 100644 --- a/doc/zh_CN/syntax/18_ownership.md +++ b/doc/zh_CN/syntax/18_ownership.md @@ -106,5 +106,5 @@ However, such restrictions are a natural specification in languages ​​withou 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 3e89fe62..d03d4caf 100644 --- a/doc/zh_CN/syntax/19_visibility.md +++ b/doc/zh_CN/syntax/19_visibility.md @@ -187,5 +187,5 @@ _ = 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 625b4017..89117377 100644 --- a/doc/zh_CN/syntax/20_naming_rule.md +++ b/doc/zh_CN/syntax/20_naming_rule.md @@ -46,5 +46,5 @@ Furthermore, literal identifiers can contain both symbols and spaces, so strings ```

- 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 9a534f48..94aeb3a4 100644 --- a/doc/zh_CN/syntax/21_lambda.md +++ b/doc/zh_CN/syntax/21_lambda.md @@ -91,5 +91,5 @@ 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 0cfbb3a4..2371fd32 100644 --- a/doc/zh_CN/syntax/22_subroutine.md +++ b/doc/zh_CN/syntax/22_subroutine.md @@ -58,5 +58,5 @@ and(x, y, z) = x and y and z ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/23_closure.md b/doc/zh_CN/syntax/23_closure.md index 06128bf3..151fa2cb 100644 --- a/doc/zh_CN/syntax/23_closure.md +++ b/doc/zh_CN/syntax/23_closure.md @@ -92,5 +92,5 @@ assert sum == 45 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 ac801d3b..63c58bf3 100644 --- a/doc/zh_CN/syntax/24_module.md +++ b/doc/zh_CN/syntax/24_module.md @@ -38,5 +38,5 @@ Since module types are also record types, deconstruction assignment is possible. ```

- 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 05d6ae68..bed6a89d 100644 --- a/doc/zh_CN/syntax/25_object_system.md +++ b/doc/zh_CN/syntax/25_object_system.md @@ -78,5 +78,5 @@ 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 c48c07c7..ac48c1e4 100644 --- a/doc/zh_CN/syntax/26_pattern_matching.md +++ b/doc/zh_CN/syntax/26_pattern_matching.md @@ -189,5 +189,5 @@ There is no set pattern. Because the set has no way to uniquely retrieve the ele 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 24c903e0..d734d27b 100644 --- a/doc/zh_CN/syntax/27_comprehension.md +++ b/doc/zh_CN/syntax/27_comprehension.md @@ -61,5 +61,5 @@ 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 5f8f760a..a736a5a5 100644 --- a/doc/zh_CN/syntax/28_spread_syntax.md +++ b/doc/zh_CN/syntax/28_spread_syntax.md @@ -38,5 +38,5 @@ 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 243fe7f0..5417f3f3 100644 --- a/doc/zh_CN/syntax/29_decorator.md +++ b/doc/zh_CN/syntax/29_decorator.md @@ -116,5 +116,5 @@ Indicates that the variable specification is obsolete and deprecated. 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 c52d5cbf..2e403ea7 100644 --- a/doc/zh_CN/syntax/30_error_handling.md +++ b/doc/zh_CN/syntax/30_error_handling.md @@ -105,5 +105,5 @@ 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 09596b06..4978f417 100644 --- a/doc/zh_CN/syntax/31_pipeline.md +++ b/doc/zh_CN/syntax/31_pipeline.md @@ -28,5 +28,5 @@ __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 945379a2..021ce6dc 100644 --- a/doc/zh_CN/syntax/32_integration_with_Python.md +++ b/doc/zh_CN/syntax/32_integration_with_Python.md @@ -78,5 +78,5 @@ declare|S: Subroutine| sub!: S, T = 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 23e5aff5..9d885e0e 100644 --- a/doc/zh_CN/syntax/33_package_system.md +++ b/doc/zh_CN/syntax/33_package_system.md @@ -79,5 +79,5 @@ baz = import "baz" ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/34_generator.md b/doc/zh_CN/syntax/34_generator.md index 12eba58e..8e927025 100644 --- a/doc/zh_CN/syntax/34_generator.md +++ b/doc/zh_CN/syntax/34_generator.md @@ -31,5 +31,5 @@ make_g: () => Generator! ```

- Previous | Next + 上一页 | Next

diff --git a/doc/zh_CN/syntax/type/01_type_system.md b/doc/zh_CN/syntax/type/01_type_system.md index a7b7be64..b5aa76e2 100644 --- a/doc/zh_CN/syntax/type/01_type_system.md +++ b/doc/zh_CN/syntax/type/01_type_system.md @@ -1,68 +1,68 @@ -# 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 的独特功能之一是(普通)变量、函数(子例程)和类型(Kind)定义之间的语法没有太大区别。 所有都是根据普通变量和函数定义的语法定义的。 ```python f i: Int = i + 1 -f # +f # <函数 f> f(1) # 2 -f.method self = ... # SyntaxError: cannot define a method to a subroutine +f.method self = ... # 语法错误:无法为子例程定义方法 T I: Int = {...} T # -T(1) # Type T(1) +T(1) # 类型 T(1) T.method self = ... D = Class {private = Int; .public = Int} -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 +D # <类 'D'> +o1 = {private = 1; .public = 2} # o1 是一个不属于任何类的对象 +o2 = D.new {private = 1; .public = 2} # o2 是 D 的一个实例 +o2 = D.new {.public = 2} # 初始化错误:类 'D' 需要属性 'private'(: Int) 但未定义 ``` ## Classification -All objects in Erg are strongly typed. -The top-level type is `{=}`, which implements `__repr__`, `__hash__`, `clone`, etc. (not required 方法, 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). +Erg 中的所有对象都是强类型的。 +顶层类型是`{=}`,实现了`__repr__`、`__hash__`、`clone`等(不是必须的方法,这些属性不能被覆盖)。 +Erg 的类型系统包含结构子类型 (SST)。 该系统类型化的类型称为结构类型。 +结构类型主要分为三种:Attributive(属性类型)、Refinement(细化类型)和Algebraic(代数类型)。 | | Record | Enum | Interval | Union | Intersection | Diff | | --------- | ----------- | ---------- | -------------- | ----------- | ------------ | ------------ | | kind | Attributive | Refinement | Refinement | Algebraic | Algebraic | Algebraic | | generator | record | set | range operator | or operator | and operator | not operator | -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. +也可以使用名义子类型(NST),将 SST 类型转换为 NST 类型称为类型的名义化。 结果类型称为名义类型。 +在 Erg 中,名义类型是类和特征。 当我们简单地说类/特征时,我们通常指的是记录类/特征。 | | 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`). +整个名义类型的类型(`NominalType`)和整个结构类型的类型(`StructuralType`)是整个类型(`Type`)的类型的子类型。 -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). +Erg 可以将参数(类型参数)传递给类型定义。带有类型参数的 `Option`、`Array` 等称为多项式类型。这些本身不是类型,但它们通过应用参数成为类型。诸如 `Int`、`Str` 等没有参数的类型称为简单类型(标量类型)。 -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. +一个类型可以看成一个集合,并且存在包含关系。例如,“Num”包含“Add”、“Sub”等,“Int”包含“Nat”。 +所有类的上类是`Object == Class {:}`,所有类型的下类是`Never == Class {}`。这在下面描述。 -## Types +## 类型 -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. +像 `Array T` 这样的类型可以看作是 `Type -> Type` 类型的函数,它以 `T` 类型为参数并返回 `Array T` 类型(在类型论中也称为 Kind)。像 `Array T` 这样的类型专门称为多态类型,而 `Array` 本身称为一元 Kind。 -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. +已知参数和返回类型的函数的类型表示为`(T, U) -> V`。如果要指定同一类型的整个双参数函数,可以使用 `|T| (T, T) -> T`,如果要指定整个 N 参数函数,可以使用 `Func N`。但是,`Func N` 类型没有关于参数数量或其类型的信息,因此所有返回值在调用时都是`Obj` 类型。 -The `Proc` type is denoted as `() => Int` and so on. Also, the name of the `Proc` type instance must end with `!` at the end. +`Proc` 类型表示为 `() => Int` 等等。此外,`Proc` 类型实例的名称必须以 `!` 结尾。 -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. +`Method` 类型是一个函数/过程,其第一个参数是它所属的对象 `self`(通过引用)。对于依赖类型,也可以在应用方法后指定自己的类型。这是 `T!(!N)` 类型和 `T!(N ~> N-1)。 () => Int` 等等。 -Erg's array (Array) is what Python calls a list. `[Int; 3]` is an array class that contains three objects of type `Int`. +Erg 的数组(Array)就是 Python 所说的列表。 `[诠释; 3]`是一个数组类,包含三个`Int`类型的对象。 -> __Note__: `(Type; N)` is both a type and a value, so it can be used like this. +> __Note__: `(Type; N)` 既是类型又是值,所以可以这样使用。 > > ```python. > Types = (Int, Str, Bool) @@ -83,37 +83,37 @@ 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 `!`. +以 `!` 结尾的类型可以重写内部结构。 例如,`[T; !N]` 类是一个动态数组。 +要从“T”类型的对象创建“T!”类型的对象,请使用一元运算符“!”。 ```python i: Int! = !1 i.update! i -> i + 1 assert i == 2 arr = [1, 2, 3] -arr.push! 4 # ImplError: +arr.push! 4 # 导入错误 mut_arr = [1, 2, 3].into [Int; !3] mut_arr.push4 assert mut_arr == [1, 2, 3, 4]. ``` -## Type Definitions +## 类型定义 -Types are defined as follows. +类型定义如下。 ```python 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 +## 数据类型 -As mentioned earlier, a "type" in Erg roughly means a set of objects. +如前所述,Erg 中的“类型”大致表示一组对象。 -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. +下面是 `Add` 类型的定义,需要 `+`(中间运算符)。 `R, O` 是所谓的类型参数,可以是真正的类型(类),例如 `Int` 或 `Str`。 在其他语言中,类型参数被赋予特殊的符号(泛型、模板等),但在 Erg 中,它们可以像普通参数一样定义。 +类型参数也可以用于类型对象以外的类型。 例如数组类型`[Int; 3]` 是 `Array Int, 3` 的语法糖。 如果类型实现重叠,用户必须明确选择一个。 ```python Add R = Trait { @@ -122,7 +122,7 @@ Add R = Trait { } ``` -.`_+_` is an abbreviation for Add.`_+_`. The prefix operator .`+_` is a method of type `Num`. +.`_+_`是Add.`_+_`的缩写。 前缀运算符 .`+_` 是 `Num` 类型的方法。 ```python Num = Add and Sub and Mul and Eq @@ -132,7 +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). +多态类型可以像函数一样对待。 通过将它们指定为 `Mul Int、Str` 等,它们可以是单态的(在许多情况下,它们是用实际参数推断出来的,而没有指定它们)。 ```python 1 + 1 @@ -141,49 +141,49 @@ Nat.`_+_` 1, 1 Int.`_+_` 1, 1 ``` -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. +前四行返回相同的结果(准确地说,底部的返回 `Int`),但通常使用顶部的。 +`Ratio.`_+_`(1, 1)` 将返回 `2.0` 而不会出错。 +这是因为 `Int <: Ratio`,所以 `1` 向下转换为 `Ratio`。 +但这不是演员。 ```python i = 1 -if i: # TypeError: i: Int cannot be cast to Bool, use Int.is_zero() instead. +if i: # 类型错误:i:Int 不能转换为 Bool,请改用 Int.is_zero()。 log "a" log "b" ``` -This is because `Bool <: Int` (`True == 1`, `False == 0`). Casts to subtypes generally require validation. +这是因为 `Bool <: Int` (`True == 1`, `False == 0`)。转换为子类型通常需要验证。 -## Type Inference System +## 类型推理系统 -Erg uses static duck typing, so there is little need to explicitly specify the type. +Erg 使用静态鸭子类型,因此几乎不需要显式指定类型。 ```python f x, y = x + y ``` -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 方法. In namespaces that have access to that type, objects that satisfy the request can use the implementation method. +在上面的代码中,带有 `+` 的类型,即 `Add` 是自动推断的; Erg 首先推断出最小的类型。如果`f 0, 1`,它将推断`f x:{0},y:{1}`,如果`n:Nat; f n, 1`,它会推断`f x: Nat, y: {1}`。最小化之后,增加类型直到找到实现。在 `{0}, {1}` 的情况下,`Nat` 与 `Nat` 是单态的,因为 `Nat` 是具有 `+` 实现的最小类型。 +如果是 `{0}, {-1}`,它与 `Int` 是单态的,因为它不匹配 `Nat`。如果子类型和超类型之间没有关系,则首先尝试具有最低浓度(实例数)(或者在多态类型的情况下参数更少)的那个。 +`{0}` 和 `{1}` 是枚举类型,它们是部分类型,例如 `Int` 和 `Nat`。 +例如,可以为枚举类型指定名称和请求/实现方法。在有权访问该类型的命名空间中,满足请求的对象可以使用实现方法。 ```python Binary = Patch {0, 1} Binary. - # self 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. + # self 包含一个实例。 在此示例中,为 0 或 1。 + # 如果你想重写self,你必须追加! 必须添加到类型名称和方法名称。 is_zero(self) = match self: 0 -> True - 1 -> False # You can also use _ -> False + 1 -> False # 你也可以使用 _ -> 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. +此后,代码“0.to_bool()”是可能的(尽管“0 as Bool == False”是内置定义的)。 +这是一个实际上可以重写 `self` 的类型的示例,如代码所示。 ```python Binary! = Patch {0, 1}! @@ -197,32 +197,32 @@ b.switch!() print! b # => 0 ``` -## Structure type (anonymous type) +## 结构类型(匿名类型) ```python 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. +上面代码中的 `Binary` 是一个类型,其元素是 `0` 和 `1`。 它也是 `Int` 类型的子类型,它同时具有 `0` 和 `1`。 +像 `{}` 这样的对象本身就是一种类型,可以在分配或不分配给上述变量的情况下使用。 +这样的类型称为结构类型。 当我们想强调它作为后者而不是类(命名类型)的用途时,它也被称为未命名类型。 `{0, 1}`这样的结构类型称为枚举类型,还有区间类型、记录类型等。 -### 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. +无法指定以下内容。 例如,您不能指定 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int`。 +例如,`Int`和`Str`都是`Add`,但是`Int`和`Str`不能相加。 ```python add l: Add, r: Add = - l + r # TypeError: there is no implementation of `_+_`: |T, U <: Add| (T, U) -> + l + r # 类型错误: `_+_` 没有实现: |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. +此外,下面的类型 `A` 和 `B` 不被认为是同一类型。 但是,类型“O”被认为是匹配的 ```python ... |R1; R2; O; A <: Add(R1, O); B <: Add(R2, O)| ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/type/02_basic.md b/doc/zh_CN/syntax/type/02_basic.md index d555b8ce..8e34ccea 100644 --- a/doc/zh_CN/syntax/type/02_basic.md +++ b/doc/zh_CN/syntax/type/02_basic.md @@ -1,62 +1,62 @@ -# Basic syntax for types +# 类型的基本语法 -## 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 中,可以在 `:` 之后指定变量的类型,如下所示。这可以与作业同时完成。 ```python -i: Int # Declare the variable i to be of type Int +i: Int # 将变量 i 声明为 Int 类型 i: Int = 1 -j = 1 # type specification can be omitted +j = 1 # 类型说明可以省略 ``` -You can also specify a type for ordinary expressions. +您还可以指定普通表达式的类型。 ```python 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. +对于简单的变量赋值,大多数类型说明可以省略。 +在定义子例程和类型时,类型规范更有用。 ```python -# 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`. +请注意,在上述情况下,`x, y` 都是 `Array Int`。 ```python -# The value of a capital variable must be a constant expression +# 大写变量的值必须是常量表达式 f X: Int = X ``` -Alternatively, if you don't need complete information about the type argument, you can omit it with `_`. +或者,如果你不需要关于类型参数的完整信息,你可以用 `_` 省略它 ```python g v: [T; _] = ... ``` -Note, however, `_` at a type specification implies `Object`. +但是请注意,类型规范中的 `_` 意味着 `Object`。 ```python -f x: _, y: Int = x + y # TypeError: + is not implemented between Object and Int +f x: _, y: Int = x + y # 类型错误:Object 和 Int 之间没有实现 + ``` -## Subtype specification +## 子类型规范 -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. +除了 `:`(类型声明运算符),Erg 还允许您使用 `<:`(部分类型声明运算符)来指定类型之间的关系。 +`<:` 的左边只能指定一个类。 使用 `Subtypeof` 或类似的运算符来比较结构类型。 -This is also often used when defining subroutines or types, rather than simply specifying variables. +这也经常在定义子例程或类型时使用,而不是简单地指定变量。 ```python -# Subtype specification of an argument +# 参数的子类型规范 f X <: T = ... -# Subtype specification of the required attribute (.Iterator attribute is required to be a subtype of type Iterator) +# 所需属性的子类型规范(.Iterator 属性必须是 Iterator 类型的子类型) Iterable T = Trait { .Iterator = {Iterator} # {Iterator} == {I: Type | I <: Iterator} .iter = Self.() -> Self.Iterator T @@ -64,15 +64,15 @@ Iterable T = Trait { } ``` -You can also use a subtype specification when defining a class to statically check whether the class is a subtype of the specified type. +也可以在定义类时使用子类型规范来静态检查该类是否是指定类型的子类型。 ```python -# Class C is a subtype of Show +# C 类是 Show 的子类型 C = Class Object, Impl := Show -C.show self = ... # Show's required attributes. +C.show self = ... # 显示所需的属性。 ``` -You can also specify a subtype only in specific cases. +您也可以仅在特定情况下指定子类型 ```python K T: Eq @@ -84,17 +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. +实现结构类型时建议使用子类型规范。 +这是因为,由于结构子类型的性质,拼写错误或类型规范错误在实现所需属性时不会导致错误 ```python C = Class Object -C.shoe self = ... # Show is not implemented due to Typo (it is considered just a unique method). +C.shoe self = ... # Show 由于 Typo 没有实现(它被认为只是一种独特的方法) ``` -## Attribute definitions +## 属性定义 -Attributes can be defined for traits and classes only in modules. +只能在模块中为特征和类定义属性 ```python C = Class() @@ -105,7 +105,7 @@ c = C.new() assert c.pub_attr == "this is public" ``` -The syntax for defining a batch definition is called a batch definition, in which a newline is added after `C.` or `C::` and the definitions are grouped together below the indentation. +定义批处理定义的语法称为批处理定义,其中在 `C.` 或 `C::` 之后添加换行符,并且定义在缩进下方组合在一起 ```python C = Class() @@ -113,7 +113,7 @@ C.pub1 = ... C.pub2 = ... C::priv1 = ... C::priv2 = ... -# is equivalent to +# 相当于 C = Class() C. pub1 = ... @@ -123,9 +123,9 @@ C:: priv2 = ... ``` -## Aliasing +## 别名 -Types can be aliased. This allows long types, such as record types, to be shortened. +类型可以有别名。 这允许缩短长类型,例如记录类型 ```python Id = Int @@ -134,28 +134,28 @@ IorS = Int or Str Vector = Array Int ``` -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. +但是,每个模块只允许一个相同类型的别名,多个别名将导致警告。 +这意味着应将具有不同用途的类型定义为单独的类型。 +目的还在于防止在已经具有别名的类型之上添加别名。 ```python Id = Int -UserId = Int # TypeWarning: duplicate aliases: Id and UserId +UserId = Int # 类型警告:重复别名:Id 和 UserId Ids = Array Id -Ints = Array Int # TypeWarning: duplicate aliases: Isd and Ints +Ints = Array Int # 类型警告:重复别名:Isd 和 Ints IorS = Int or Str IorSorB = IorS or Bool -IorSorB_ = Int or Str or Bool # TypeWarning: duplicate aliases: IorSorB and IorSorB_ +IorSorB_ = Int or Str or Bool # 类型警告:重复别名:IorSorB 和 IorSorB_ Point2D = {x = Int; y = Int} Point3D = {.... Point2D; z = Int} -Point = {x = Int; y = Int; z = Int} # TypeWarning: duplicate aliases: Point3D and Point +Point = {x = Int; y = Int; z = Int} # 类型警告:重复别名:Point3D 和 Point ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/type/03_trait.md b/doc/zh_CN/syntax/type/03_trait.md index 9df474e0..5f6b1287 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 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. +Trait 是一种名义类型,它将类型属性要求添加到记录类型。 +它类似于 Python 中的抽象基类 (ABC),但区别在于能够执行代数运算。 ```python Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int} ``` -Trait does not distinguish between attributes and 方法. +特质不区分属性和方法。 -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. +注意,trait 只能声明,不能实现(实现是通过一个叫做 patching 的特性来实现的,后面会讨论)。 +可以通过指定部分类型来检查特征在类中的实现。 ```python Point2D <: Norm @@ -21,11 +21,11 @@ Point2D.norm self = self.x**2 + self.y**2 Error if the required attributes are not implemented. ```python -Point2D <: Norm # TypeError: Point2D is not a subtype of Norm +Point2D <: Norm # 类型错误:Point2D 不是 Norm 的子类型 Point2D = Class {.x = Int; .y = Int} ``` -Traits, like structural types, can apply operations such as composition, substitution, and elimination (e.g. `T and U`). The resulting trait is called an instant trait. +特征与结构类型一样,可以应用组合、替换和消除等操作(例如“T 和 U”)。 由此产生的特征称为即时特征。 ```python T = Trait {.x = Int} @@ -38,18 +38,18 @@ assert Structural(W) ! = Structural(T) assert Structural(W) == Structural(T.replace {.x = Ratio}) ``` -Trait is also a type, so it can be used for normal type specification. +Trait 也是一种类型,因此可以用于普通类型规范 ```python points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)] assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25]. ``` -## 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. +扩展运算符 `...` 允许您将包含某个特征的特征定义为超类型。 这称为特征的 __subsumption__。 +在下面的示例中,`BinAddSub` 包含 `BinAdd` 和 `BinSub`。 +这对应于类中的继承,但与继承不同的是,可以使用“和”组合多个基类型。 也允许被 `not` 部分排除的特征。 ```python Add R = Trait { @@ -65,15 +65,15 @@ Sub R = Trait { BinAddSub = Subsume Add(Self) and Sub(Self) ``` -## Structural Traits +## 结构特征 -Traits can be structured. +特征可以结构化 ```python SAdd = Structural Trait { . `_+_` = Self.(Self) -> Self } -# |A <: SAdd| cannot be omitted +# |A <: SAdd| 不能省略 add|A <: SAdd| x, y: A = x.`_+_` y C = Class {i = Int} @@ -84,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`. +名义特征不能简单地通过实现请求方法来使用,而必须明确声明已实现。 +在以下示例中,`add`不能与`C`类型的参数一起使用,因为没有明确的实现声明。 它必须是`C = Class {i = Int}, Impl := Add`。 ```python Add = Trait { .`_+_` = Self.(Self) -> Self } -# |A <: Add| can be omitted +# |A <: 添加| 可以省略 add|A <: Add| x, y: A = x.`_+_` y C = Class {i = Int} @@ -99,15 +99,15 @@ 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 a subclass of Add -# hint: inherit or patch 'Add' +add C.new(1), C.new(2) # 类型错误:C 不是 Add 的子类 +# 提示:继承或修补“添加” ``` -Structural traits do not need to be declared for this implementation, but instead type inference does not work. Type specification is required for use. +不需要为此实现声明结构特征,但类型推断不起作用。 使用时需要指定类型。 -## Polymorphic Traits +## 多态特征 -Traits can take parameters. This is the same as for polymorphic types. +特征可以带参数。 这与多态类型相同。 ```python Mapper T: Type = Trait { @@ -122,10 +122,10 @@ Mapper T: Type = Trait { assert [1, 2, 3].iter().map(x -> "{x}").collect(Array) == ["1", "2", "3"]. ``` -## Override in Trait +## Override特征 -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. +派生特征可以Override基本特征的类型定义。 +在这种情况下,Override方法的类型必须是基方法类型的子类型。 ```python # `Self.(R) -> O` is a subtype of ``Self.(R) -> O or Panic @@ -138,9 +138,9 @@ SafeDiv R, O = Subsume Div, { } ``` -## Implementing and resolving duplicate traits in the API +## 在 API 中实现和解决重复的特征 -The actual definitions of `Add`, `Sub`, and `Mul` look like this. +`Add`、`Sub` 和 `Mul` 的实际定义如下所示。 ```python Add R = Trait { @@ -157,11 +157,11 @@ Mul R = Trait { } ``` -`.Output` is duplicated. If you want to implement these multiple traits at the same time, specify the following. +`.Output` 重复。 如果要同时实现这些多个特征,请指定以下内容 ```python P = Class {.x = Int; .y = Int} -# P|Self <: Add(P)| can be abbreviated to P|<: Add(P)| +# 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} @@ -170,18 +170,18 @@ P|Self <: Mul(Int)|. `*` self, other = P.new {.x = self.x * other; .y = self.y * other} ``` -Duplicate APIs implemented in this way are almost always type inferred when used, but can also be resolved by explicitly specifying the type with `||`. +以这种方式实现的重复 API 在使用时几乎总是类型推断,但也可以通过使用 `||` 显式指定类型来解决。 ```python -print! P.Output # TypeError: ambiguous type +print! P.Output # 类型错误:不明确的类型 print! P|<: Mul(Int)|.Output # ``` -## Appendix: Differences from Rust traits +## 附录:与 Rust 特征的区别 -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. +Erg 的特征忠实于 [Schärli 等人] (https://www.ptidej.net/courses/ift6251/fall06/presentations/061122/061122.doc.pdf) 提出的特征。 +为了允许代数运算,特征被设计为不能有方法实现目录,但可以在必要时进行修补。 -

- Previous | Next -

+

+ 上一页 | 下一步 +

\ No newline at end of file diff --git a/doc/zh_CN/syntax/type/04_class.md b/doc/zh_CN/syntax/type/04_class.md index 2728fcdd..2d0e5715 100644 --- a/doc/zh_CN/syntax/type/04_class.md +++ b/doc/zh_CN/syntax/type/04_class.md @@ -1,11 +1,11 @@ # Class -A class in Erg is roughly a type that can create its own elements (instances). -Here is an example of a simple class. +Erg 中的类大致是一种可以创建自己的元素(实例)的类型。 +这是一个简单类的示例。 ```python Person = Class {.name = Str; .age = Nat} -# If `.new` is not defined, then Erg will create `Person.new = Person::__new__` +# 如果 `.new` 没有定义,那么 Erg 将创建 `Person.new = Person::__new__` Person. new name, age = Self::__new__ {.name = name; .age = age} @@ -14,23 +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. +赋予“Class”的类型(通常是记录类型)称为需求类型(在本例中为“{.name = Str; .age = Nat}”)。 +可以使用 `::__new__ { = ; 创建实例 ...}` 可以创建。 +`{.name = "约翰·史密斯"; .age = 25}` 只是一条记录,但它通过传递 `Person.new` 转换为 `Person` 实例。 +创建此类实例的子例程称为构造函数。 +在上面的类中,`.new` 方法被定义为可以省略字段名等。 -Note that the following definition without line breaks will result in a syntax error. +请注意,以下不带换行符的定义将导致语法错误。 ```python -Person.new name, age = ... # SyntaxError: cannot define attributes directly on an object +Person.new name, age = ... # 语法错误:不能直接在对象上定义属性 ``` -> __Warning__: This is a recently added specification and may not be followed in subsequent documents. If you find it, please report it. +> __Warning__:这是最近添加的规范,后续文档中可能不会遵循。 如果你发现它,请报告它。 -## 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 和其他语言中,实例属性通常在块侧定义如下,但请注意,这样的写法在 Erg 中具有不同的含义。 ```python # Python @@ -40,7 +40,7 @@ class Person: ``` ```python -# In Erg, this notation implies the declaration of a class attribute (not an instance attribute) +# 在Erg中,这个符号意味着类属性的声明(不是实例属性) Person = Class() Person. name: Str @@ -48,18 +48,18 @@ Person. ``` ```python -# Erg code for the Python code above +# 以上 Python 代码的 Erg 代码 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. +下面的例子说明了这一点。 `species` 属性对所有实例都是通用的,因此将其用作类属性更自然。 但是,属性 `name` 应该是实例属性,因为每个实例都应该单独拥有它。 ```python Person = Class {name = Str} @@ -71,51 +71,51 @@ Person. greet self = log "Hello, My name is {self::name}." -Person.describe() # species: human -Person.greet() # TypeError: unbound method Person.greet needs an argument +Person.describe() # 类型:Person +Person.greet() # 类型错误: 未绑定的方法 Person.greet 需要一个参数 john = Person.new {name = "John"} -john.describe() # species: human -john.greet() # Hello, My name is John. +john.describe() # 类型: human +john.greet() # 你好,我是约翰 alice = Person.new {name = "Alice"} -alice.describe() # species: human -alice.greet() # Hello, My name is Alice. +alice.describe() # 类型: human +alice.greet() # 你好,我是爱丽丝 ``` -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. +顺便说一下,如果实例属性和类型属性具有相同的名称和相同的类型,则会发生编译错误。 这是为了避免混淆。 ```python C = Class {.i = Int} -C.i = 1 # AttributeError: `.i` is already defined in instance fields +C.i = 1 # 属性错误:`.i` 已在实例字段中定义 ``` -## Class, Type +## 类(Class), 类型(Type) -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 方法 as well as class 方法. -Erg does not allow you to add class 方法, but you can use [patch](./07_patch.md) to extend a class. +请注意,`1` 的类和类型是不同的。 +只有一个类 `Int` 是 `1` 的生成器。 可以通过`classof(obj)`或`obj.__class__`获取对象所属的类。 +相比之下,`1`有无数种。 例如,`{1}, {0, 1}, 0..12, Nat, Int, Num`。 +但是,可以将最小类型定义为单一类型,在本例中为“{1}”。 可以通过`Typeof(obj)`获取对象所属的类型。 这是一个编译时函数。 +对象可以使用补丁方法以及类方法。 +Erg 不允许您添加类方法,但您可以使用 [patch](./07_patch.md) 来扩展类。 -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). +您还可以从现有类([Inheritable](./../27_decorator.md/#inheritable) 类)继承。 +您可以使用 `Inherit` 创建一个继承类。 左侧的类型称为派生类,右侧的“继承”的参数类型称为基类(继承类)。 ```python MyStr = Inherit Str -# other: You can use MyStr if you set ``other: Str''. +# other: 如果你设置 ``other: Str'',你可以使用 MyStr。 MyStr. `-` self, other: Str = self.replace other, "" abc = MyStr.new("abc") -# Comparison here gets an upcast +# 这里的比较是向上的 assert abc - "b" == "ac" ``` -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. +与 Python 不同,默认情况下,定义的 Erg 类是 `final`(不可继承的)。 +要使类可继承,必须将 `Inheritable` 装饰器附加到该类。 +Str` 是可继承的类之一。 ```python MyStr = Inherit Str # OK @@ -126,10 +126,10 @@ InheritableMyStr = Inherit Str MyStr3 = Inherit InheritableMyStr # OK ``` -`Inherit Object` and `Class()` are almost equivalent in practice. The latter is generally used. +`Inherit Object` 和 `Class()` 在实践中几乎是等价的。 一般使用后者。 -Classes have a different equivalence checking mechanism than types. -Types are equivalence tested based on their structure. +类具有与类型不同的等价检查机制。 +类型基于其结构进行等效性测试。 ```python Person = {.name = Str; .age = Nat} @@ -144,12 +144,12 @@ class has no equivalence relation defined. Person = Class {.name = Str; .age = Nat} Human = Class {.name = Str; .age = Nat} -Person == Human # TypeError: cannot compare classes +Person == Human # 类型错误:无法比较类 ``` -## 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. +我们说过类是一种可以生成自己的元素的类型,但这并不是严格的描述。 事实上,一个记录类型+补丁可以做同样的事情。 ```python Person = {.name = Str; .age = Nat} @@ -160,19 +160,19 @@ PersonImpl. john = Person.new("John Smith", 25) ``` -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. +使用类有四个优点。 +第一个是构造函数经过有效性检查,第二个是它的性能更高,第三个是您可以使用符号子类型(NST),第四个是您可以继承和覆盖。 -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. +我们之前看到记录类型 + 补丁也可以定义一个构造函数(某种意义上),但这当然不是一个合法的构造函数。 这当然不是一个合法的构造函数,因为它可以返回一个完全不相关的对象,即使它调用自己`.new`。 在类的情况下,`.new` 被静态检查以查看它是否生成满足要求的对象。 ~ -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. +类的类型检查只是检查对象的`。 __class__` 对象的属性。 因此可以快速检查一个对象是否属于一个类型。 ~ -Erg enables NSTs in classes; the advantages of NSTs include robustness. -When writing large programs, it is often the case that the structure of an object is coincidentally matched. +Erg 在课堂上启用 NST; NST 的优点包括健壮性。 +在编写大型程序时,经常会出现对象的结构巧合匹配的情况。 ```python Dog = {.name = Str; .age = Nat} @@ -189,8 +189,8 @@ 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. +`Dog` 和 `Person` 的结构完全一样,但让动物打招呼,让人类吠叫显然是无稽之谈。 +前者是不可能的,所以让它不适用更安全。 在这种情况下,最好使用类。 ```python Dog = Class {.name = Str; .age = Nat} @@ -200,12 +200,12 @@ 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`. +john.bark() # 类型错误: `Person` 对象没有方法 `.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. +另一个特点是补丁添加的类型属性是虚拟的,实现类不作为实体保存。 +也就是说,`T.x`、`T.bar` 是可以通过与 `{i = Int}` 兼容的类型访问(编译时绑定)的对象,并且未在 `{i = Int}` 或 ` C`。 +相反,类属性由类本身持有。 因此,它们不能被不处于继承关系的类访问,即使它们具有相同的结构。 ```python C = Class {i = Int} @@ -220,25 +220,25 @@ T. 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! -print! {i = 1}.bar # -C.new({i = 1}).bar # +print! T.bar # <函数 bar> +{i = Int}.bar # 类型错误:Record({i = Int}) 没有方法 `.bar`。 +C.bar # 类型错误:C 没有方法 `.bar` 打印! +print! {i = 1}.bar # <方法 bar> +C.new({i = 1}).bar # <方法 bar> ``` -## 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. +有两种类型的类:常规类,通过`Class`成为记录类,以及从记录类继承(`Inherit`)的数据类。 +数据类继承了记录类的功能,具有分解赋值、默认实现的`==`和`hash`等特性。另一方面,数据类有自己的等价关系和格式展示。 +另一方面,如果要定义自己的等价关系或格式显示,则应使用普通类。 ```python C = Class {i = Int} c = C.new {i = 1} d = C.new {i = 2} print! c # -c == d # TypeError: `==` is not implemented for `C` +c == d # 类型错误:`==` 没有为 `C` 实现 D = Inherit {i = Int} e = D.new {i = 1} @@ -247,9 +247,9 @@ print! e # D{i = 1} assert e ! = f ``` -## Enum Class +## 枚举类 -To facilitate defining classes of type `Or`, an `Enum` is provided. +为了便于定义“Or”类型的类,提供了一个“Enum”。 ```python X = Class() @@ -257,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. +每种类型都可以通过`XorY.X`、`XorY.Y`来访问,构造函数可以通过`XorY.cons(X)`获得。 +`.cons` 是一个接受类并返回其构造函数的方法。 ```python x1 = XorY.new X.new() @@ -266,9 +266,9 @@ x2 = XorY.cons(X)() assert x1 == x2 ``` -## Class Relationships +## 类关系 -A class is a subtype of a requirement type. 方法 (including patch 方法) of the requirement type can be used in the class. +类是需求类型的子类型。 类中可以使用需求类型的方法(包括补丁方法)。 ```python T = Trait {.foo = Foo} @@ -283,5 +283,5 @@ assert T.foo == Foo ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/type/05_inheritance.md b/doc/zh_CN/syntax/type/05_inheritance.md index 85744b2a..e87ac090 100644 --- a/doc/zh_CN/syntax/type/05_inheritance.md +++ b/doc/zh_CN/syntax/type/05_inheritance.md @@ -1,7 +1,7 @@ -# 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. +继承允许您定义一个新类,为现有类添加功能或专业化。 +继承类似于包含在特征中。 继承的类成为原始类的子类型。 ```python NewInt = Inherit Int @@ -12,9 +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. +如果你希望新定义的类是可继承的,你必须给它一个 `Inheritable` 装饰器。 -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. +您可以指定一个可选参数 `additional` 以允许该类具有其他实例属性,但前提是该类是一个值类。 但是,如果类是值类,则不能添加实例属性。 ```python @Inheritable @@ -24,15 +24,15 @@ 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 +MailAddress = Inherit Str, additional: {owner = Str} # 类型错误:实例变量不能添加到值类中 ``` -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. +Erg 的特殊设计不允许继承“Never”类型。 Erg 的特殊设计不允许继承 `Never` 类型,因为 `Never` 是一个永远无法实例化的独特类。 -## 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. +[Or 类型](./13_algebraic.md) 也可以被继承。 在这种情况下,您可以通过指定可选参数 `Excluding` 来删除任何选项(可以使用 `or` 进行多项选择)。 +不能添加其他选项。 添加选项的类不是原始类的子类型。 ```python Number = Class Int or Float or Complex @@ -42,11 +42,11 @@ Number.abs(self): Float = f: Float -> f.abs() c: Complex -> c.abs().into Float -# c: Complex cannot appear in match choices +# c: 复杂不能出现在匹配选项中 RealNumber = Inherit Number, Excluding: Complex ``` -Similarly, [refinement type](./12_refinement.md) can also be specified. +同样,也可以指定[细化类型](./12_refinement.md)。 ```python Months = Class 0..12 @@ -56,25 +56,25 @@ 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 方法 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 方法. +该类与补丁相同,可以将新方法添加到原始类型,但可以进一步“覆盖”该类。 +这种覆盖称为覆盖。要覆盖,必须满足三个条件。 +首先,覆盖必须有一个 `Override` 装饰器,因为默认情况下它会导致错误。 +另外,覆盖不能改变方法的类型。它必须是原始类型的子类型。 +如果你重写了一个被另一个方法引用的方法,你也必须重写所有被引用的方法。 -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. +让我们从第一个条件开始。此条件是为了防止“意外覆盖”。 +换句话说,必须使用 `Override` 装饰器来防止派生类中新定义的方法的名称与基类的名称冲突。 -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 独有的,在其他面向对象语言中并不常见,同样是为了安全。让我们看看如果不是这种情况会出现什么问题。 ```python -# Bad example +# 反面示例 @Inheritable Base! = Class {x = Int!} Base! @@ -86,13 +86,13 @@ Base! 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 + g! ref! self = self.f!() # 无限递归警告:此代码陷入无限循环 + # 覆盖错误:方法 `.g` 被 `.f` 引用但未被覆盖 ``` -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. +在继承类 `Inherited!` 中,`.g!` 方法被重写以将处理转移到 `.f!`。 但是,基类中的 `.f!` 方法会将其处理转移到 `.g!`,从而导致无限循环。 `.f` 是 `Base!` 类中的一个没有问题的方法,但它被覆盖以一种意想不到的方式使用,并且被破坏了。 -Erg has built this rule into the specification. +Erg 已将此规则构建到规范中。 ```python # OK. @@ -114,52 +114,51 @@ 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. +然而,这个规范并没有完全解决覆盖问题。 然而,这个规范并没有完全解决覆盖问题,因为编译器无法检测覆盖是否解决了问题。 +创建派生类的程序员有责任纠正覆盖的影响。 只要有可能,尝试定义一个别名方法。 -### Replacing Traits (or what looks like it) +### 替换特征(或看起来像什么) -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()`. +例如,`Int`,`Real` 的子类型(实现了 `Add()`),似乎重新实现了 `Add()`。 ```python Int = Class ... , Impl := Add() and ... ``` -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)`). +但实际上 `Real` 中的 `Add()` 代表 `Add(Real, Real)`,而在 `Int` 中它只是被 `Add(Int, Int)` 覆盖。 +它们是两个不同的特征(`Add` 是一个 [covariate](./advanced/variance.md),所以`Add(Real, Real) :> Add(Int, Int)`)。 -## Multiple Inheritance - -Erg does not allow intersection, diff, and complement between normal classes. +## 多重继承 +Erg 不允许普通类之间的交集、差异和互补。 ```python -Int and Str # TypeError: cannot unite classes +Int and Str # 类型错误:无法合并类 ``` -This rule prevents inheritance from multiple classes, i.e., multiple inheritance. +该规则防止从多个类继承,即多重继承。 ```python -IntAndStr = Inherit Int and Str # SyntaxError: multiple inheritance of classes is not allowed +IntAndStr = Inherit Int and Str # 语法错误:不允许类的多重继承 ``` -However, multiple inherited Python classes can be used. +但是,可以使用多个继承的 Python 类。 -## Multi-layer (multi-level) Inheritance +## 多层(多级)继承 -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. +Erg 继承也禁止多层继承。 也就是说,您不能定义从另一个类继承的类。 +从“Object”继承的可继承类可能会异常继承。 -Also in this case, Python's multi-layered inherited classes can be used. +同样在这种情况下,可以使用 Python 的多层继承类。 -## Rewriting Inherited Attributes +## 重写继承的属性 -Erg does not allow rewriting the attributes inherited from the base class. This has two implications. +Erg 不允许重写从基类继承的属性。 这有两个含义。 -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. +第一个是对继承的源类属性的更新操作。 例如,它不能重新分配,也不能通过 `.update!` 方法更新。 -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. +覆盖与重写不同,因为它是一种用更专业的方法覆盖的操作。 覆盖也必须替换为兼容的类型。 ```python @Inheritable @@ -171,14 +170,14 @@ Base! 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! () => ()` + # 覆盖错误:`.inc_pub!` 必须是 `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 方法 provided by the base class. -Regardless of the visibility of the attribute, it cannot be updated directly. However, they can be read. +第二个是对继承源的(变量)实例属性的更新操作。 这也是被禁止的。 基类的实例属性只能从基类提供的方法中更新。 +无论属性的可见性如何,都无法直接更新。 但是,它们可以被读取。 ```python @Inheritable @@ -193,41 +192,41 @@ Inherited! add2_pub! ref! self = self.inc_pub!() self.inc_pub!() - # NG, `Child` cannot touch `self.pub` and `self::pri`. + # NG, `Child` 不能触摸 `self.pub` 和 `self::pri`。 add2_pub! ref! self = self.pub.update! p -> p + 2 ``` -After all, Erg inheritance can only add new attributes and override base class 方法. +毕竟 Erg 继承只能添加新的属性和覆盖基类的方法。 -## Usage of Inheritance +## 使用继承 -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. +虽然继承在正确使用时是一项强大的功能,但它也有一个缺点,即它往往会使类依赖关系复杂化,尤其是在使用多层或多层继承时。复杂的依赖关系会降低代码的可维护性。 +Erg 禁止多重和多层继承的原因是为了降低这种风险,并且引入了类补丁功能以降低依赖关系的复杂性,同时保留继承的“添加功能”方面。 -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 允许类型系统自动进行部分子类型确定(例如,Nat,其中 Int 大于或等于 0)。 +但是,例如,仅依靠 Erg 的类型系统很难创建“表示有效电子邮件地址的字符串类型”。您可能应该对普通字符串执行验证。然后,我们想为已通过验证的字符串对象添加某种“保证”。这相当于向下转换为继承的类。将 `Str object` 向下转换为 `ValidMailAddressStr` 与验证字符串是否采用正确的电子邮件地址格式是一一对应的。 ```python ValidMailAddressStr = Inherit Str ValidMailAddressStr. init s: Str = - validate s # mail-address validation + validate s # 邮件地址验证 Self.new s s1 = "invalid mail address" s2 = "foo@gmail.com" -_ = ValidMailAddressStr.init s1 # panic: invalid mail address +_ = ValidMailAddressStr.init s1 # 恐慌:无效的邮件地址 valid = ValidMailAddressStr.init s2 -valid: ValidMailAddressStr # assurance that it is in the correct email address format +valid: ValidMailAddressStr # 确保电子邮件地址格式正确 ``` -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. +另一个指标是您何时想要实现名义多态性。 +例如,下面定义的 `greet!` 过程将接受任何类型为 `Named` 的对象。 +但显然应用 `Dog` 类型的对象是错误的。 所以我们将使用 `Person` 类作为参数类型。 +这样,只有 `Person` 对象、从它们继承的类和 `Student` 对象将被接受为参数。 +这是比较保守的,避免不必要地承担过多的责任。 ```python Named = {name = Str; ...} @@ -243,12 +242,12 @@ 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: +structural_greet! max # 你好,我是马克斯 +structural_greet! john # 你好,我是约翰 +greet! alice # 你好,我是爱丽丝 +greet! max # 类型错误: ```

- Previous | Next + 上一页 | 下一页

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 7bfe0f93..7c79df2c 100644 --- a/doc/zh_CN/syntax/type/06_nst_vs_sst.md +++ b/doc/zh_CN/syntax/type/06_nst_vs_sst.md @@ -1,4 +1,4 @@ -# Nominal Subtyping vs. Structural Subtyping +# 名义子类型与结构子类型 ```python Months = 0..12 @@ -27,17 +27,17 @@ 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 方法 take priority. +# 如果两者都存在,则类方法优先 assert MonthsClass.new(2).name() == "february" ``` -## In The End, Which Should I Use, NST or SST? +## 最后,我应该使用哪个,NST 还是 SST? -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. +如果您无法决定使用哪一个,我们的建议是 NST。 +SST 需要抽象技能来编写在任何用例中都不会崩溃的代码。 好的抽象可以带来高生产力,但错误的抽象(外观上的共性)会导致适得其反的结果。(NST 可以通过故意将抽象保持在最低限度来降低这种风险。如果您不是库实现者,那么仅使用 NST 进行编码并不是一个坏主意。

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/type/07_patch.md b/doc/zh_CN/syntax/type/07_patch.md index 630fb8a9..6a02c067 100644 --- a/doc/zh_CN/syntax/type/07_patch.md +++ b/doc/zh_CN/syntax/type/07_patch.md @@ -1,8 +1,8 @@ -# Patch +# 修补 -Erg does not allow modification of existing types and classes. -This means, it is not possible to define additional 方法 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 不允许修改现有类型和类。 +这意味着,不可能在类中定义额外的方法,也不能执行特化(一种语言特性,单态化多态声明的类型并定义专用方法,如在 C++ 中)。 +但是,在许多情况下,您可能希望向现有类型或类添加功能,并且有一个称为“修补”的功能允许您执行此操作。 ```python StrReverse = Patch Str @@ -12,34 +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 方法 of the patch (`StrReverse`). -In fact, built-in method `.reverse` is not a method of `Str`, but a method added to `StrRReverse`. +补丁的名称应该是要添加的主要功能的简单描述。 +这样,被修补类型的对象(`Str`)可以使用修补程序的方法(`StrReverse`)。 +实际上,内置方法`.reverse`并不是`Str`的方法,而是`StrRReverse`中添加的方法。 -However, patch 方法 have lower precedence than 方法 of the nominal type (class/trait) and cannot override 方法 of existing types. +但是,补丁方法的优先级低于名义类型(类/特质)的方法,并且不能覆盖现有类型。 ```python StrangeInt = Patch Int StrangeInt. - `_+_` = Int.`_-_` # AssignError: . `_+_` is already defined in Int + `_+_` = Int.`_-_` # 赋值错误:. `_+_` 已在 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. +如果要覆盖,则必须从类继承。 +但是,基本上建议不要覆盖并定义具有不同名称的方法。 +由于一些安全限制,覆盖不是很容易做到。 ```python StrangeInt = Inherit Int StrangeInt. - # Overriding 方法 must be given Override decorators. - # In addition, you need to override all Int 方法 that depend on Int.`_+_`. +# 覆盖方法必须被赋予覆盖装饰器。 + # 另外,你需要覆盖所有依赖于 Int.`_+_` 的 Int 方法。 @Override - `_+_` = Super.`_-_` # OverrideError: Int.`_+_` is referenced by ... ````` , so these 方法 must also be overridden + `_+_` = Super.`_-_` # OverrideError: Int.`_+_` 被 ... ````` 引用,所以这些方法也必须被覆盖 ``` -## Selecting 修补程序 +## 选择修补程序 -修补程序 can be defined for a single type, and can be grouped together. +可以为单一类型定义修复程序,并且可以组合在一起。 ```python # foo.er @@ -70,7 +70,7 @@ assert "to camel case".to_camel_case() == "toCamelCase" assert "to kebab case".to_kebab_case() == "to-kebab-case" ``` -If multiple 修补程序 are defined, some of them may result in duplicate implementations. +如果定义了多个修复程序,其中一些可能会导致重复实施 ```python # foo.er @@ -78,15 +78,15 @@ If multiple 修补程序 are defined, some of them may result in duplicate imple StrReverse = Patch(Str) StrReverse. reverse self = ... -# more efficient implementation +# 更高效的实现 StrReverseMk2 = Patch(Str) StrReverseMk2. reverse self = ... -"hello".reverse() # PatchSelectionError: multiple choices of `.reverse`: StrReverse, StrReverseMk2 +"hello".reverse() # 补丁选择错误: `.reverse` 的多个选择: StrReverse, StrReverseMk2 ``` -In such a case, you can make it unique by using the __related function__ form instead of the method form. +在这种情况下,您可以使用 __related function__ 形式而不是方法形式使其唯一 ```python assert StrReverseMk2.reverse("hello") == "olleh" @@ -100,11 +100,11 @@ You can also make it unique by selectively importing. assert "hello".reverse() == "olleh" ``` -## Glue Patch +## 胶水补丁 -修补程序 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. +维修程序也可以将类型相互关联。 `StrReverse` 补丁涉及 `Str` 和 `Reverse`。 +这样的补丁称为 __glue patch__。 +因为 `Str` 是内置类型,所以用户需要使用胶水补丁来改造特征。 ```python Reverse = Trait { @@ -117,9 +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 修补程序 were "visible" at the same time, it would not be possible to uniquely determine which implementation to choose. -However, you can swap 修补程序 when moving to another scope (module). +每个类型/特征对只能定义一个胶水补丁。 +这是因为如果多个胶水修复程序同时“可见”,就不可能唯一确定选择哪个实现。 +但是,当移动到另一个范围(模块)时,您可以交换维修程序。 ```python NumericStr = Inherit Str @@ -129,13 +129,13 @@ 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` +# 重复修补程序错误:数值Str已与“反向”关联` +# 提示:'Str'(NumericStr'的超类)通过'StrReverse'与'Reverse'关联 ``` -## Appendix: Relationship to Rust's Trait +## 附录:与 Rust 特征的关系 -Erg 修补程序 are the equivalent of Rust's (retrofitted) `impl` blocks. +Erg 修复程序相当于 Rust 的(改造的)`impl` 块。 ```rust // Rust @@ -150,7 +150,7 @@ impl Reverse for String { } ``` -You could say that Rust's traits are features of Erg's traits and 修补程序. This makes Rust's traits sound more convenient, but that is not necessarily the case. +可以说,Rust 的特征是 Erg 的特征和修复程序的特征。 这使得 Rust 的特征听起来更方便,但事实并非如此。 ```python # Erg @@ -164,8 +164,8 @@ StrReverse. self.iter().rev().collect(Str) ``` -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. +因为 impl 块在 Erg 中被对象化为补丁,所以在从其他模块导入时可以选择性地包含。 作为副作用,它还允许将外部特征实现到外部结构。 +此外,结构类型不再需要诸如 `dyn trait` 和 `impl trait` 之类的语法。 ```python # Erg @@ -183,11 +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. +补丁不仅可以为一种特定类型定义,还可以为“一般功能类型”等定义。 +在这种情况下,要给出自由度的项作为参数给出(在下面的情况下,`T:Type`)。 以这种方式定义的补丁称为全对称补丁。 +如您所见,全对称补丁正是一个返回补丁的函数,但它本身也可以被视为补丁。 ```python FnType T: Type = Patch(T -> T) @@ -197,15 +197,15 @@ FnType(T). assert (Int -> Int).type == Int ``` -## Structural Patch +## 结构补丁 -In addition, 修补程序 can be defined for any type that satisfies a certain structure. -However, this has a lower priority than nominal 修补程序 and class 方法. +此外,可以为满足特定结构的任何类型定义修复程序。 +但是,这比名义上的维修程序和类方法具有较低的优先级。 -Careful design should be used when defining structural 修补程序, as some properties are lost by extension, such as the following. +在定义结构修复程序时应使用仔细的设计,因为某些属性会因扩展而丢失,例如以下内容。 ```python -# This should not be `Structural` +# 这不应该是 `Structural` Norm = Structural Patch {x = Int; y = Int} Norm. norm self = self::x**2 + self::y**2 @@ -218,5 +218,5 @@ assert Point3D.new({x = 1; y = 2; z = 3}).norm() == 14 # AssertionError: ```

- Previous | Next + 上一页 | 下一页

diff --git a/doc/zh_CN/syntax/type/08_value.md b/doc/zh_CN/syntax/type/08_value.md index 9f0bf89c..1483139a 100644 --- a/doc/zh_CN/syntax/type/08_value.md +++ b/doc/zh_CN/syntax/type/08_value.md @@ -1,6 +1,6 @@ -# Value Type +# 值类型 -Value types are Erg built-in types that can be evaluated at compile time, specifically: +值类型是可以在编译时评估的 Erg 内置类型,具体来说: ```python Value = ( @@ -21,17 +21,17 @@ Value = ( ) ``` -Value-type objects, constants, and compile-time subroutines applied to them are called __constant expressions__. +应用于它们的值类型对象、常量和编译时子例程称为 __constant 表达式__。 ```python 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. +小心子程序。子例程可能是也可能不是值类型。 +由于子程序的实质只是一个指针,因此可以将其视为一个值[1](#1),但是在编译不是子程序的东西时不能使用 在恒定的上下文中。 不是值类型,因为它没有多大意义。 -Types classified as value types may be added in the future. +将来可能会添加归类为值类型的类型。 --- -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) +1 Erg 中的术语“值类型”与其他语言中的定义不同。 纯 Erg 语义中没有内存的概念,并且因为它被放置在堆栈上而说它是值类型,或者因为它实际上是一个指针而说它不是值类型是不正确的。 值类型仅表示它是“值”类型或其子类型。 [↩](#f1) diff --git a/doc/zh_CN/syntax/type/09_attributive.md b/doc/zh_CN/syntax/type/09_attributive.md index 3098d671..96cae23e 100644 --- a/doc/zh_CN/syntax/type/09_attributive.md +++ b/doc/zh_CN/syntax/type/09_attributive.md @@ -1,9 +1,9 @@ -# Attributive Type +# 属性类型 -Attribute types are types that contain Record and Dataclass, Patch, Module, etc. -Types belonging to attribute types are not value types. +属性类型是包含 Record 和 Dataclass、Patch、Module 等的类型。 +属于属性类型的类型不是值类型。 -## 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 +可以展平复合的记录类型。 +例如,`{... {.name = Str; .age = Nat}; ... {.name = Str; .id = Nat}}` 变成 `{.name = Str; .age = 自然; .id = Nat}`。 \ No newline at end of file diff --git a/doc/zh_CN/syntax/type/10_interval.md b/doc/zh_CN/syntax/type/10_interval.md index 3d48f0b1..2ecd67e8 100644 --- a/doc/zh_CN/syntax/type/10_interval.md +++ b/doc/zh_CN/syntax/type/10_interval.md @@ -1,35 +1,35 @@ -# Interval Type +# 间隔类型 -The most basic use of `Range` objects is as iterator. +`Range` 对象最基本的用途是作为迭代器。 ```python for! 0..9, i => print! i ``` -Note that unlike Python, it includes a end number. +请注意,与 Python 不同,它包含一个结束编号。 -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. +然而,这不仅仅用于 `Range` 对象。 也可以使用类型。 这种类型称为Interval类型。 ```python i: 0..10 = 2 ``` -The `Nat` type is equivalent to `0.. ExtraStatus, and elements of Status can use 方法 of ExtraStatus. +# Status > ExtraStatus,Status的元素可以使用ExtraStatus的方法 Status = Trait {"Ok", "Error"} # ... ExtraStatus = Trait {"Ok", "Error", "Unknown"} # ... ``` -方法 can also be added by patching. +方法也可以通过补丁添加。 -Use the `or` operator to explicitly indicate inclusion or to add a choice to an existing Enum type. +使用“或”运算符明确指示包含或向现有 Enum 类型添加选项。 ```python ExtraStatus = Status or {"Unknown"} ``` -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. +如果您不想这样做,可以将其设为包装类 ```python Abc = Class {"A", "B", "C"} @@ -81,5 +81,5 @@ 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 +OpaqueAbc.new("A").is_uppercase() # 类型错误 ``` diff --git a/doc/zh_CN/syntax/type/12_refinement.md b/doc/zh_CN/syntax/type/12_refinement.md index f8df698d..ed5ae22c 100644 --- a/doc/zh_CN/syntax/type/12_refinement.md +++ b/doc/zh_CN/syntax/type/12_refinement.md @@ -1,9 +1,9 @@ -# 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. +细化类型的标准形式是`{Elem: Type | (预)*}`。 这意味着该类型是其元素为满足 `Pred` 的 `Elem` 的类型。 +可用于筛选类型的类型仅为 [Const type](./advanced/const.md)。 ```python Nat = 0.. _ @@ -14,32 +14,32 @@ Char = StrWithLen 1 Array3OrMore == {A: Array _, N | N >= 3} ``` -When there are multiple preds, they can be separated by `;` or `and` or `or`. `;` and `and` mean the same thing. +当有多个 pred 时,可以用 `;` 或 `and` 或 `or` 分隔。 `;` 和 `and` 的意思是一样的。 -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. +`Odd` 的元素是 `1, 3, 5, 7, 9, ...`。 +它被称为细化类型,因为它的元素是现有类型的一部分,就好像它是细化一样。 -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. +`Pred` 被称为(左侧)谓词表达式。 和赋值表达式一样,它不返回有意义的值,左侧只能放置一个模式。 +也就是说,诸如`X**2 - 5X + 6 == 0`之类的表达式不能用作细化类型的谓词表达式。 在这方面,它不同于右侧的谓词表达式。 ```python -{X: Int | X**2 - 5X + 6 == 0} # SyntaxError: the predicate form is invalid. Only names can be on the left-hand side +{X: Int | X**2 - 5X + 6 == 0} # 语法错误:谓词形式无效。 只有名字可以在左边 ``` -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. +如果你知道如何解二次方程,你会期望上面的细化形式等价于`{2, 3}`。 +但是,Erg 编译器对代数的了解很少,因此无法解决右边的谓词。 -## 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. +很高兴您定义了 `Odd`,但事实上,它看起来不能在文字之外使用太多。 要将普通 `Int` 对象中的奇数提升为 `Odd`,即将 `Int` 向下转换为 `Odd`,您需要传递 `Odd` 的构造函数。 +对于细化类型,普通构造函数 `.new` 可能会出现恐慌,并且有一个名为 `.try_new` 的辅助构造函数返回一个 `Result` 类型。 ```python i = Odd.new (0..10).sample!() i: Odd # or Panic ``` -It can also be used as a type specification in `match`. +它也可以用作 `match` 中的类型说明。 ```python # i: 0..10 @@ -51,12 +51,12 @@ match i: log "i: Nat" ``` -However, Erg cannot currently make sub-decisions such as `Even` because it was not `Odd`, etc. +但是,Erg 目前无法做出诸如“偶数”之类的子决策,因为它不是“奇数”等。 -## 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}`. +前面介绍的枚举/区间类型是细化类型的语法糖。 +`{a, b, ...}` 是 `{I: Typeof(a) | I == a 或 I == b 或 ... }`,并且 `a..b` 被去糖化为 `{I: Typeof(a) | 我 >= a 和我 <= b}`。 ```python {1, 2} == {I: Int | I == 1 or I == 2} @@ -64,12 +64,12 @@ The enumerative/interval types introduced before are syntax sugar of the refinem 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`. +正如 `_: {X}` 可以重写为 `X`(常量模式),`_: {X: T | Pred}` 可以重写为`X: T | Pred` ```python -# method `.m` is defined for arrays of length 3 or greater +# 方法 `.m` 是为长度为 3 或更大的数组定义的 Array(T, N | N >= 3) .m(&self) = ... ``` diff --git a/doc/zh_CN/syntax/type/13_algebraic.md b/doc/zh_CN/syntax/type/13_algebraic.md index e214c71d..ef4cde9e 100644 --- a/doc/zh_CN/syntax/type/13_algebraic.md +++ b/doc/zh_CN/syntax/type/13_algebraic.md @@ -1,37 +1,37 @@ -# Algebraic type +# 代数类型 -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、Intersection、Diff、Complement等。 +普通类只能进行Union,其他操作会导致类型错误。 -## Union +## 联合(Union) -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. +联合类型可以为类型提供多种可能性。 顾名思义,它们是由“或”运算符生成的。 +一个典型的 Union 是 `Option` 类型。 `Option` 类型是 `T 或 NoneType` 补丁类型,主要表示可能失败的值。 ```python IntOrStr = Int or Str assert dict.get("some key") in (Int or NoneType) -# Implicitly become `T != NoneType` +# 隐式变为 `T != NoneType` Option T = T or NoneType ``` -## Intersection +## 路口 -Intersection types are got by combining types with the `and` operation. +交集类型是通过将类型与 `and` 操作组合得到的。 ```python 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. +如上所述,普通类不能与“and”操作结合使用。 这是因为实例只属于一个类。 -## 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`. +Diff 类型是通过 `not` 操作获得的。 +最好使用 `and not` 作为更接近英文文本的符号,但建议只使用 `not`,因为它更适合与 `and` 和 `or` 一起使用。 ```python CompleteNum = Add and Sub and Mul and Div and Eq and Ord @@ -41,11 +41,11 @@ True = Bool not {False} OneTwoThree = {1, 2, 3, 4, 5, 6} - {4, 5, 6, 7, 8, 9, 10} ``` -## Complement +## 补充 -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. +补码类型是通过 `not` 操作得到的,这是一个一元操作。 `not T` 类型是 `{=} not T` 的简写。 +类型为“非 T”的交集等价于 Diff,类型为“非 T”的 Diff 等价于交集。 +但是,不推荐这种写法。 ```python # the simplest definition of the non-zero number type diff --git a/doc/zh_CN/syntax/type/advanced/shared.md b/doc/zh_CN/syntax/type/advanced/shared.md index 74a904bd..6b9d34a3 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 +# 共享参考 -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 中,以下代码将通过类型检查。 ```typescript class NormalMember {} @@ -14,12 +14,12 @@ normal_area.push(new NormalMember()) console.log(vip_area) # [NormalMember] ``` -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. +一个 NormalMember 已进入 vip_area。 这是一个明显的错误,但是出了什么问题? +原因是共享引用 [denatured](./variance.md)。 `normal_area` 是通过复制 `vip_area` 来创建的,但是这样做的时候类型已经改变了。 +但是 `VIPMember` 继承自 `NormalMember`,所以 `VIPMember[] <: NormalMember[]`,这不是问题。 +关系 `VIPMember[] <: NormalMember[]` 适用于不可变对象。 但是,如果您执行上述破坏性操作,则会出现故障。 -In Erg, such code is played back due to the ownership system. +在 Erg 中,由于所有权系统,此类代码会被回放。 ```python NormalMember = Class() @@ -29,20 +29,20 @@ 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` +log vip_area # 所有权错误:`vip_room` 已移至 `normal_room` ``` -However, it can be inconvenient for an object to be owned by only one place. -For this reason, Erg has a type `SharedCell!T!`, which represents a shared state. +然而,一个对象只属于一个地方可能会很不方便。 +出于这个原因,Erg 有一个类型 `SharedCell!T!`,它代表一个共享状态。 ```python $p1 = SharedCell!.new(!1) $p2 = $p1.mirror!() $p3 = SharedCell!.new(!1) -# If $p1 == $p2, a comparison of the content type Int! +# 如果$p1 == $p2,比较内容类型Int! assert $p1 == $p2 assert $p1 == $p3 -# Check if $p1 and $p2 point to the same thing with `.addr!`. +# 检查 $p1 和 $p2 是否用 `.addr!` 指向同一个东西。 assert $p1.addr!() == $p2.addr!() assert $p1.addr!() != $p3.addr!() $p1.add! 1 @@ -51,19 +51,19 @@ assert $p2 == 2 assert $p3 == 1 ``` -Objects of type `SharedCell!` must be prefixed with `$`. Also, by their nature, they cannot be constants. +`SharedCell!` 类型的对象必须以`$` 为前缀。 此外,就其性质而言,它们不可能是常数。 -The `SharedCell! T!` type is also a subtype of `T!` and can call 方法 of type `T!`. The only 方法 specific to the `SharedCell!T!` type are `.addr!`, `.mirror!` and `.try_take`. +`SharedCell! T!` 类型也是 `T!` 的子类型,可以调用 `T!` 类型的方法。 `SharedCell!T!` 类型特有的唯一方法是 `.addr!`、`.mirror!` 和 `.try_take`。 -An important fact is that `SharedCell! T!` is non-variant, i.e., no inclusions are defined for different type arguments. +一个重要的事实是`SharedCell! T!` 是非变体的,即没有为不同类型的参数定义包含。 ```python $vip_area = SharedCell!.new([].into [VIPMember; !_]) -$normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() # TypeError: expected SharedCell!([NormalMember; !_]), but got SharedCell!([VIPMember; !_]) -# hint: SharedCell!(T) is non-variant, which means it cannot have a supertype or a subtype. +$normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() #类型错误:预期 SharedCell!([NormalMember;!_]),但得到 SharedCell!([VIPMember;!_]) +# 提示:SharedCell!(T) 是非变体的,这意味着它不能有超类型或子类型。 ``` -However, the following code have not problem. In the last line, it's the `VIPMember` argument that has been typed converted. +但是,下面的代码没有问题。 在最后一行,它是 `VIPMember` 参数已被类型转换 ```python $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 800e37bb..e4a48af6 100644 --- a/doc/zh_CN/syntax/type/advanced/special.md +++ b/doc/zh_CN/syntax/type/advanced/special.md @@ -1,6 +1,6 @@ -# Special types (Self, Super) +# 特殊类型(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). +`Self` 代表它自己的类型。 您可以将其用作别名,但请注意派生类型的含义会发生变化(指的是自己的类型)。 ```python @Inheritable @@ -14,7 +14,7 @@ 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. +`Super` 表示基类的类型。方法本身引用基类,但实例使用自己的类型。 ```python @Inheritable @@ -29,9 +29,9 @@ 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`. +`Self` 和 `Super` 可以用作结构化类型和特征中的类型变量。 这指的是作为该类型子类型的类。 也就是说,`T` 类型中的`Self` 表示`Self <: T`。 ```python Add R = Trait { diff --git a/doc/zh_CN/syntax/type/advanced/typeof.md b/doc/zh_CN/syntax/type/advanced/typeof.md index b320d7a0..029cfc94 100644 --- a/doc/zh_CN/syntax/type/advanced/typeof.md +++ b/doc/zh_CN/syntax/type/advanced/typeof.md @@ -1,6 +1,6 @@ # Typeof, classof -`Typeof` is a function that can peek into Erg's type inference system, and its behavior is complex. +`Typeof` 是一个可以窥探 Erg 类型推断系统的函数,它的行为很复杂 ```python assert Typeof(1) == {I: Int | I == 1} @@ -16,10 +16,10 @@ 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. +`Typeof` 函数返回派生类型,而不是对象的类。 +因此,例如 `C = Class T` 类的`I: C`,`Typeof(I) == T`。 +值类没有对应的记录类型。 为了解决这个问题,值类应该是具有 `__valueclass_tag__` 属性的记录类型。 +请注意,您不能访问此属性,也不能在用户定义的类型上定义 `__valueclass_tag__` 属性。 ```python i: Int = ... @@ -28,15 +28,15 @@ s: Str = ... assert Typeof(s) == {__valueclass_tag__ = Phantom Str} ``` -`Typeof` outputs only structured types. I explained that structured types include attribute types, sieve types, and (true) algebraic types. -These are independent types (inference precedence exists) and inference conflicts do not occur. -Attribute types and algebraic types can span multiple classes, while sieve types are subtypes of a single class. -Erg infers object types as sieve types as much as possible, and when that is not possible, expands sieve base classes to structured types (see below). +`Typeof` 仅输出结构化类型。 我解释说结构化类型包括属性类型、筛类型和(真正的)代数类型。 +这些是独立的类型(存在推理优先级),不会发生推理冲突。 +属性类型和代数类型可以跨越多个类,而筛类型是单个类的子类型。 +Erg 尽可能将对象类型推断为筛类型,如果不可能,则将筛基类扩展为结构化类型(见下文)。 -## 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`. +所有类都可以转换为派生类型。 这称为 __结构化__。 类的结构化类型可以通过 `Structure` 函数获得。 +如果一个类是用`C = Class T`定义的(所有类都以这种形式定义),那么`Structure(C) == T`。 ```python C = Class {i = Int} @@ -47,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 structured -# You can't actually define a record with __valueclass_tag__, but conceptually +assert Structure(Option) # 类型错误:只能构造单态类型 +# 你实际上不能用 __valueclass_tag__ 定义一条记录,但在概念上 assert Structure(Int) == {__valueclass_tag__ = Phantom Int} assert Structure(Str) == {__valueclass_tag__ = Phantom Str} assert Structure((Nat, Nat)) == {__valueclass_tag__ = Phantom(Tuple(Nat, Nat))} assert Structure(Nat -> Nat) == {__valueclass_tag__ = Phantom(Func(Nat, Nat))} -# Marker classes are also record types with __valueclass_tag__ +# 标记类也是带有 __valueclass_tag__ 的记录类型 M = Inherit Marker assert Structure(M) == {__valueclass_tag__ = Phantom M} D = Inherit(C and M) diff --git a/doc/zh_CN/syntax/type/advanced/variance.md b/doc/zh_CN/syntax/type/advanced/variance.md index 44b72b71..56b0c938 100644 --- a/doc/zh_CN/syntax/type/advanced/variance.md +++ b/doc/zh_CN/syntax/type/advanced/variance.md @@ -1,70 +1,69 @@ -# variation +# 变化 -Erg can subtype polymorphic types, but there are some caveats. +Erg 可以对多态类型进行子类型化,但有一些注意事项。 -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, 方法 defined in `Option Object` can also be used in `Option Int`. +首先,考虑普通多态类型的包含关系。一般来说,有一个容器`K`和它分配的类型`A,B`,当`A < B`时,`K A < K B`。 +例如,`Option Int < Option Object`。因此,在`Option Object`中定义的方法也可以在`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 方法 called `.push!` and `.pop!`, which mean adding and removing elements, respectively. Here is the type: +考虑典型的多态类型 `Array!(T)`。 +请注意,这一次不是 `Array!(T, N)` 因为我们不关心元素的数量。 +现在,`Array!(T)` 类型具有称为 `.push!` 和 `.pop!` 的方法,分别表示添加和删除元素。这是类型: -Array.push!: Self(T).(T) => NoneType -Array.pop!: Self(T).() => T +`Array.push!: Self(T).(T) => NoneType` +`Array.pop!: Self(T).() => T` -As can be intuitively understood, +可以直观地理解: * `Array!(Object).push!(s)` is OK when `s: Str` (just upcast `Str` to `Object`) * When `o: Object`, `Array!(Str).push!(o)` is NG * `Array!(Object).pop!().into(Str)` is NG * `Array!(Str).pop!().into(Object)` is OK -is. In terms of the type system, this is +就类型系统而言,这是 -* (Self(Object).(Object) => NoneType) < (Self(Str).(Str) => NoneType) -* (Self(Str).() => Str) < (Self(Object).() => Object) +* `(Self(Object).(Object) => NoneType) < (Self(Str).(Str) => NoneType)` +* `(Self(Str).() => Str) < (Self(Object).() => Object)` +方法 -means +前者可能看起来很奇怪。即使是 `Str < Object`,包含关系在将其作为参数的函数中也是相反的。 +在类型论中,这种关系(`.push!` 的类型关系)称为逆变,反之,`.pop!` 的类型关系称为协变。 +换句话说,函数类型就其参数类型而言是逆变的,而就其返回类型而言是协变的。 +这听起来很复杂,但正如我们之前看到的,如果将其应用于实际示例,这是一个合理的规则。 +如果您仍然不明白,请考虑以下内容。 -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 有另一个修改。它是不变的。 +这是对 `SharedCell! T!`等内置类型的修改。这意味着对于两种类型 `T!, U!` 其中 `T! != U!`,在 `SharedCell! T!` 和 `SharedCell!意思是 +这是因为`SharedCell! T!` 是共享参考。有关详细信息,请参阅 [共享参考](shared.md)。 -Erg has another modification. It is non-variance. -This is a modification that built-in types such as `SharedCell! T!` have. This means that for two types `T!, U!` where `T! != U!`, casts between `SharedCell! T!` and `SharedCell! means that -This is because `SharedCell! T!` is a shared reference. See [shared references](shared.md) for details. +## 变异的泛型类型 -## Mutated generic type - -A universal type variable can specify its upper and lower bounds. +通用类型变量可以指定其上限和下限。 ```python |A <: T| K(A) |B :> T| K(B) ``` -In the type variable list, the __variant specification__ of the type variable is performed. In the above variant specification, the type variable `A` is declared to be any subclass of type `T` and the type variable `B` is declared to be any superclass of type `T`. -In this case, `T` is also called the upper type for `A` and the lower type for `B`. +在类型变量列表中,执行类型变量的__variant说明__。 在上述变体规范中,类型变量“A”被声明为“T”类型的任何子类,“B”类型被声明为“T”类型的任何超类。 +在这种情况下,`T` 也称为 `A` 的上部类型和 `B` 的下部类型。 -Mutation specifications can also overlap. +突变规范也可以重叠。 ```python # U U} ``` -Here is an example of code that uses a variable specification. +这是使用变量规范的代码示例: ```python show|S <: Show| s: S = log s @@ -77,37 +76,37 @@ List(T). 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: +`List T` 的例子很棘手,所以让我们更详细一点。 +要理解上面的代码,你需要了解多态类型退化。 [this section](./variance.md) 中详细讨论了方差,但现在我们需要三个事实: -* 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`) +* 普通的多态类型,例如`List T`,与`T`是协变的(`List U > List T` when `U > T`) +* 函数 `T -> U` 对于参数类型 `T` 是逆变的(`(S -> U) < (T -> U)` when `S > T`) +* 函数 `T -> U` 与返回类型 `U` 是协变的(`(T -> U) > (T -> S)` 当 `U > S` 时) -For example, `List Int` can be upcast to `List Object` and `Obj -> Obj` can be upcast to `Int -> Obj`. +例如,`List Int` 可以向上转换为 `List Object`,而 `Obj -> Obj` 可以向上转换为 `Int -> Obj`。 -Now let's consider what happens if we omit the variable specification of the method. +现在让我们考虑如果我们省略方法的变量说明会发生什么。 ```python ... List T = Class {head = T; rest = Cons T} List(T). - # List T can be pushed U if T > U + # 如果 T > U,列表 T 可以被推入 U push|U|(self, x: U): List T = Self. new {head = x; rest = self} - # List T can be List U if T < U + # List T 可以是 List U 如果 T < U upcast(self, U): List U = self ``` -Even in this case, the Erg compiler does a good job of inferring the upper and lower types of `U`. -Note, however, that the Erg compiler doesn't understand the semantics of 方法. The compiler simply infers and derives type relationships mechanically according to how variables and type variables are used. +即使在这种情况下,Erg 编译器也能很好地推断 `U` 的上下类型。 +但是请注意,Erg 编译器不理解方法的语义。编译器只是根据变量和类型变量的使用方式机械地推断和派生类型关系。 -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. +正如评论中所写,放在`List T`的`head`中的`U`类型是`T`的子类(`T:Int`,例如`Nat`)。也就是说,它被推断为 `U <: T`。此约束将 `.push{U}` upcast `(List(T), U) -> List(T) 的参数类型更改为 (List(T), T) -> List(T)`(例如 disallow `列表(整数).push{对象}`)。但是请注意,`U <: T` 约束不会改变函数的类型包含。 `(List(Int), Object) -> List(Int) to (List(Int), Int) -> List(Int)` 的事实并没有改变,只是在 `.push` 方法中表示强制转换无法执行。 +类似地,从 `List T` 到​​ `List U` 的转换可能会受到约束 `U :> T` 的约束,因此可以推断出变体规范。此约束将 `.upcast(U)` 的返回类型更改为向上转换 `List(T) -> List(T) 到 List(T) -> List(T)`(例如 `List(Object) .upcast(Int )`) 被禁止。 -Now let's see what happens if we allow this upcast. -Let's invert the denaturation designation. +现在让我们看看如果我们允许这种向上转换会发生什么。 +让我们反转变性名称。 ```python ... @@ -115,18 +114,18 @@ List T = Class {head = T; rest = Cons T} List(T). push|U :> T|(self, x: U): List T = Self. new {head = x; rest = self} upcast(self, U :> T): List U = self -# TypeWarning: `U` in the `.push` cannot take anything other than `U == T`. Replace `U` with `T`. -# TypeWarning: `U` in the `.upcast` cannot take anything other than `U == T`. Replace `U` with `T`. +# 类型警告:`.push` 中的 `U` 不能接受除 `U == T` 之外的任何内容。 将“U”替换为“T”。 +# 类型警告:`.upcast` 中的 `U` 不能接受除 `U == T` 之外的任何内容。 将“U”替换为“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. +只有当 `U == T` 时,约束 `U <: T` 和修改规范`U :> T` 才满足。 所以这个称号没有多大意义。 +只有“向上转换使得 `U == T`” = “向上转换不会改变 `U` 的位置”实际上是允许的。 -## 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`. +默认情况下,用户定义类型的突变是不可变的。 但是,您也可以使用 `Inputs/Outputs` 标记特征指定可变性。 +如果您指定 `Inputs(T)`,则类型相对于 `T` 是逆变的。 +如果您指定 `Outputs(T)`,则类型相对于 `T` 是协变的。 ```python K T = Class(...) @@ -134,10 +133,10 @@ assert not K(Str) <= K(Object) assert not K(Str) >= K(Object) InputStream T = Class ..., Impl := Inputs(T) -# A stream that accepts Objects can also be considered to accept Strs +# 接受Objects的流也可以认为接受Strs assert InputStream(Str) > InputStream(Object) OutputStream T = Class ..., Impl := Outputs(T) -# A stream that outputs a Str can also be considered to output an Object +# 输出Str的流也可以认为输出Object assert OutputStream(Str) < OutputStream(Object) ``` \ No newline at end of file diff --git a/doc/zh_CN/syntax/type/advanced/widening.md b/doc/zh_CN/syntax/type/advanced/widening.md index d29e27cf..282fcb73 100644 --- a/doc/zh_CN/syntax/type/advanced/widening.md +++ b/doc/zh_CN/syntax/type/advanced/widening.md @@ -1,14 +1,14 @@ -# Type Widening +# 类型加宽 -For example, define the polycorrelation coefficient as follows. +例如,定义多相关系数如下。 ```python ids|T|(x: T, y: T) = x, y ``` -There's nothing wrong with assigning a pair of instances of the same class. -When you assign an instance pair of another class that has a containment relationship, it is upcast to the larger one and becomes the same type. -Also, it is easy to understand that an error will occur if another class that is not in the containment relationship is assigned. +分配同一类的一对实例并没有错。 +当您分配另一个具有包含关系的类的实例对时,它会向上转换为较大的类并成为相同的类型。 +另外,很容易理解,如果分配了另一个不在包含关系中的类,就会发生错误。 ```python assert ids(1, 2) == (1, 2) @@ -16,7 +16,7 @@ assert ids(1, 2.0) == (1.0, 2.0) ids(1, "a") #TypeError ``` -Now, what about types that have different derived types? +现在,具有不同派生类型的类型呢? ```python i: Int or Str @@ -24,7 +24,7 @@ j: Int or NoneType ids(i, j) # ? ``` -Before explaining this, we have to focus on the fact that Erg's type system doesn't actually look at (runtime) classes. +在解释这一点之前,我们必须关注 Erg 的类型系统实际上并不关注(运行时)类这一事实。 ```python 1: {__valueclass_tag__ = Phantom Int} @@ -33,60 +33,60 @@ Before explaining this, we have to focus on the fact that Erg's type system does "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 +ids(1, "a"): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Str} == Never # 类型错误 ``` -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`. +我看不到该类,因为它可能无法准确看到,因为在 Erg 中,对象的类属于运行时信息。 +例如,一个`Int`或Str`类型的对象的类是`Int`或`Str`,但你只有通过执行才能知道它是哪一个。 +当然,`Int` 类型的对象的类被定义为 `Int`,但是在这种情况下,从类型系统中可见的是 `Int` 的结构类型 `{__valueclass_tag__ = Int}`。 -Now let's go back to another structured type example. In conclusion, the above code will result in a TypeError as the type does not match. -However, if you do type expansion with type annotations, compilation will pass. +现在让我们回到另一个结构化类型示例。 总之,上述代码将导致类型错误,因为类型不匹配。 +但是,如果您使用类型注释进行类型扩展,编译将通过。 ```python i: Int or Str j: Int or NoneType -ids(i, j) # TypeError: types of i and j not matched -# hint: try type widening (e.g. ids) +ids(i, j) # 类型错误:i 和 j 的类型不匹配 +# 提示:尝试扩大类型(例如 ids) ids(i, j) # OK ``` -`A and B` have the following possibilities. +`A 和 B` 有以下可能性。 -* `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 and B == A`:当`A <: B`或`A == B`时。 +* `A and B == B`:当 `A :> B` 或 `A == B` 时。 +* `A and B == {}`:当 `!(A :> B)` 和 `!(A <: B)` 时。 -`A or B` has the following possibilities. +`A 或 B` 具有以下可能性。 -* `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)`. +* `A 或 B == A`:当`A :> B` 或`A == B` 时。 +* `A or B == B`:当`A <: B`或`A == B`时。 +* `A 或 B` 是不可约的(独立类型):如果 `!(A :> B)` 和 `!(A <: B)`。 -## Type widening in subroutine definitions +## 子程序定义中的类型扩展 -Erg defaults to an error if return types do not match. +如果返回类型不匹配,Erg 默认会出错。 ```python parse_to_int s: Str = if not s.is_numeric(): do parse_to_int::return error("not numeric") - ... # return Int object -# TypeError: mismatched types of return values -# 3 | do parse_to_int::return error("not numeric") +... # 返回 Int 对象 +# 类型错误:返回值类型不匹配 +# 3 | 做 parse_to_int::return error("not numeric") # └─ Error # 4 | ... # └ Int ``` -In order to solve this, it is necessary to explicitly specify the return type as Or type. +为了解决这个问题,需要将返回类型显式指定为 Or 类型 ```python parse_to_int(s: Str): Int or Error = if not s.is_numeric(): do parse_to_int::return error("not numeric") - ... # return Int object + ... # 返回 Int 对象 ``` -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 +这是设计使然,这样您就不会无意中将子例程的返回类型与另一种类型混合。 +但是,如果返回值类型选项是具有包含关系的类型,例如 `Int` 或 `Nat`,它将与较大的对齐。 \ No newline at end of file From 4145c3b0ec366a3665b36f5ceac4bb8170c68987 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 19:18:29 +0800 Subject: [PATCH 16/42] translate save --- doc/zh_CN/syntax/type/13_algebraic.md | 22 ++-- doc/zh_CN/syntax/type/14_dependent.md | 36 +++--- doc/zh_CN/syntax/type/15_quantified.md | 150 +++++++++++------------ doc/zh_CN/syntax/type/16_subtyping.md | 32 ++--- doc/zh_CN/syntax/type/17_type_casting.md | 30 ++--- doc/zh_CN/syntax/type/18_mut.md | 148 +++++++++++----------- doc/zh_CN/syntax/type/19_bound.md | 14 +-- doc/zh_CN/syntax/type/advanced.md | 2 +- 8 files changed, 217 insertions(+), 217 deletions(-) diff --git a/doc/zh_CN/syntax/type/13_algebraic.md b/doc/zh_CN/syntax/type/13_algebraic.md index ef4cde9e..5567aafc 100644 --- a/doc/zh_CN/syntax/type/13_algebraic.md +++ b/doc/zh_CN/syntax/type/13_algebraic.md @@ -41,45 +41,45 @@ True = Bool not {False} OneTwoThree = {1, 2, 3, 4, 5, 6} - {4, 5, 6, 7, 8, 9, 10} ``` -## 补充 +## 补充 补码类型是通过 `not` 操作得到的,这是一个一元操作。 `not T` 类型是 `{=} not T` 的简写。 类型为“非 T”的交集等价于 Diff,类型为“非 T”的 Diff 等价于交集。 但是,不推荐这种写法。 ```python -# 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 ``` -## 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. +有两种代数类型:可以简化的表观代数类型和不能进一步简化的真实代数类型。 +“表观代数类型”包括 Enum、Interval 和 Record 类型的 `or` 和 `and`。 +这些不是真正的代数类型,因为它们被简化了,并且将它们用作类型说明符将导致警告; 要消除警告,您必须简化它们或定义它们的类型。 ```python assert {1, 2, 3} or {2, 3} == {1, 2, 3} assert {1, 2, 3} and {2, 3} == {2, 3} assert -2..-1 or 1..2 == {-2, -1, 1, 2} -i: {1, 2} or {3, 4} = 1 # TypeWarning: {1, 2} or {3, 4} can be simplified to {1, 2, 3, 4} +i: {1, 2} or {3, 4} = 1 # 类型警告:{1, 2} 或 {3, 4} 可以简化为 {1, 2, 3, 4} p: {x = Int, ...} and {y = Int; ...} = {x = 1; y = 2; z = 3} -# TypeWaring: {x = Int, ...} and {y = Int; ...} can be simplified to {x = Int; y = Int; ...} +# 类型警告:{x = Int, ...} 和 {y = Int; ...} 可以简化为 {x = Int; y = 整数; ...} Point1D = {x = Int; ...} Point2D = Point1D and {y = Int; ...} # == {x = Int; y = Int; ...} q: Point2D = {x = 1; y = 2; z = 3} ``` -True algebraic types include the types `Or` and `And`. Classes such as `or` between classes are of type `Or`. +真正的代数类型包括类型“或”和“与”。 类之间的“或”等类属于“或”类型。 ```python assert Int or Str == Or(Int, Str) assert Int and Marker == And(Int, Marker) ``` -Diff, Complement types are not true algebraic types because they can always be simplified. +Diff, Complement 类型不是真正的代数类型,因为它们总是可以被简化。 diff --git a/doc/zh_CN/syntax/type/14_dependent.md b/doc/zh_CN/syntax/type/14_dependent.md index 56fe4de2..6a7c8627 100644 --- a/doc/zh_CN/syntax/type/14_dependent.md +++ b/doc/zh_CN/syntax/type/14_dependent.md @@ -1,10 +1,10 @@ -# dependent type +# 依赖类型 -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. +依赖类型是一个特性,可以说是 Erg 的最大特性。 +依赖类型是将值作为参数的类型。 普通的多态类型只能将类型作为参数,但依赖类型放宽了这个限制。 -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`. +依赖类型等价于`[T; N]`(`数组(T,N)`)。 +这种类型不仅取决于内容类型“T”,还取决于内容数量“N”。 `N` 包含一个`Nat` 类型的对象。 ```python a1 = [1, 2, 3] @@ -14,7 +14,7 @@ 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: +如果函数参数中传递的类型对象与返回类型有关,则写: ```python narray: |N: Nat| {N} -> [{N}; N] @@ -22,16 +22,16 @@ narray(N: Nat): [N; N] = [N; N] assert array(3) == [3, 3, 3] ``` -When defining a dependent type, all type arguments must be constants. +定义依赖类型时,所有类型参数都必须是常量。 -Dependent types themselves exist in existing languages, but Erg has the feature of defining procedural 方法 on dependent types. +依赖类型本身存在于现有语言中,但 Erg 具有在依赖类型上定义过程方法的特性 ```python x=1 f x = print! f::x, module::x -# The Phantom type has an attribute called Phantom whose value is the same as the type argument +# Phantom 类型有一个名为 Phantom 的属性,其值与类型参数相同 T X: Int = Class Impl := Phantom X T(X). x self = self::Phantom @@ -39,19 +39,19 @@ T(X). T(1).x() # 1 ``` -Type arguments of mutable dependent types can be transitioned by method application. -Transition specification is done with `~>`. +可变依赖类型的类型参数可以通过方法应用程序进行转换。 +转换规范是用 `~>` 完成的 ```python -# Note that `Id` is an immutable type and cannot be transitioned +# 注意 `Id` 是不可变类型,不能转换 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 = self.close_something!() @@ -60,15 +60,15 @@ VM!("running" ~> "running").stop!ref!self = vm = VM!.new() vm.start!() vm.stop!() -vm.stop!() # TypeError: VM!(!"stopped", 1) doesn't have .stop!() -# hint: VM!(!"running", 1) has .stop!() +vm.stop!() # 类型错误:VM!(!"stopped", 1) 没有 .stop!() +# 提示:VM!(!"running", 1) 有 .stop!() ``` -You can also embed or inherit existing types to create dependent types. +您还可以嵌入或继承现有类型以创建依赖类型。 ```python MyArray(T, N) = Inherit[T; N] -# The type of self: Self(T, N) changes in conjunction with .array +# self 的类型:Self(T, N) 与 .array 一起变化 MyStruct!(T, N: Nat!) = Class {.array: [T; !N]} ``` \ No newline at end of file diff --git a/doc/zh_CN/syntax/type/15_quantified.md b/doc/zh_CN/syntax/type/15_quantified.md index 87c8b0ab..3acba232 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. +类型变量是用于例如指定子程序参数类型的变量,它的类型是任意的(不是单态的)。 +首先,作为引入类型变量的动机,考虑 `id` 函数,它按原样返回输入。 ```python id x: Int = x ``` -The `id` function that returns the input as is is defined for the type `Int`, but this function can obviously be defined for any type. -Let's use `Object` for the largest class. +返回输入的“id”函数是为“Int”类型定义的,但这个函数显然可以为任何类型定义。 +让我们使用 `Object` 来表示最大的类。 ```python 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`. +当然,它现在接受任意类型,但有一个问题:返回类型被扩展为 `Object`。 返回类型扩展为 `Object`。 +如果输入是“Int”类型,我想查看返回类型“Int”,如果输入是“Str”类型,我想查看“Str”。 ```python print! id 1 # -id(1) + 1 # TypeError: cannot add `Object` and `Int +id(1) + 1 # 类型错误:无法添加 `Object` 和 `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). +要确保输入的类型与返回值的类型相同,请使用 __type 变量__。 +类型变量在`||`(类型变量列表)中声明。 ```python id|T: Type| x: T = x @@ -36,12 +36,12 @@ assert id("foo") == "foo" assert id(True) == True ``` -This is called the __universal quantification (universalization)__ of the function. There are minor differences, but it corresponds to the function called generics in other languages. A universalized function is called a __polymorphic function__. -Defining a polymorphic function is like defining a function of the same form for all types (Erg prohibits overloading, so the code below cannot really be written). +这称为函数的 __universal quantification(泛化)__。 有细微的差别,但它对应于其他语言中称为泛型的函数。 泛化函数称为__多态函数__。 +定义一个多态函数就像为所有类型定义一个相同形式的函数(Erg 禁止重载,所以下面的代码真的不能写)。 ```python id|T: Type| x: T = x -# pseudo code +# 伪代码 id x: Int = x id x: Str = x id x: Bool = x @@ -50,23 +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`). +此外,类型变量“T”可以推断为“Type”类型,因为它在类型规范中使用。 所以 `|T: Type|` 可以简单地缩写为 `|T|`。 +你也可以省略`|T, N| 脚; N]` 如果可以推断它不是类型对象(`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 方法 to be used. +如果类型对于任意类型来说太大,您也可以提供约束。 +约束也有优势,例如,子类型规范允许使用某些方法。 ```python # T <: Add -# => T is a subclass of Add -# => can do addition +# => T 是 Add 的子类 +# => 可以做加法 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. +在本例中,`T` 必须是`Add` 类型的子类,并且要分配的`l` 和`r` 的实际类型必须相同。 +在这种情况下,“T”由“Int”、“Ratio”等满足。因此,例如,“Int”和“Str”的添加没有定义,因此被拒绝。 -You can also type it like this. +您也可以像这样键入它。 ```python f| @@ -78,7 +78,7 @@ f| x + y + z + x ``` -If the annotation list is long, you may want to pre-declare it. +如果注释列表很长,您可能需要预先声明它。 ```python f: |Y, Z: Type, X <: Add(Y, O1), O1 <: Add(Z, O2), O2 <: Add(X, O3)| (X, Y, Z) -> O3 @@ -86,13 +86,13 @@ f|X, Y, Z| x: X, y: Y, z: Z = x + y + z + x ``` -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. +与许多具有泛型的语言不同,所有声明的类型变量都必须在临时参数列表(`x: X, y: Y, z: Z` 部分)或其他类型变量的参数中使用。 +这是 Erg 语言设计的一个要求,即所有类型变量都可以从真实参数中推断出来。 +因此,无法推断的信息,例如返回类型,是从真实参数传递的; Erg 允许从实参传递类型。 ```python Iterator T = Trait { - # Passing return types from arguments. + # 从参数传递返回类型。 # .collect: |K: Type -> Type| Self(T). ({K}) -> K(T) .collect(self(T), K: Type -> Type): K(T) = ... ... @@ -102,7 +102,7 @@ it = [1, 2, 3].iter().map i -> i + 1 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. +类型变量只能在 `||` 期间声明。 但是,一旦声明,它们就可以在任何地方使用,直到它们退出作用域 ```python f|X|(x: X): () = @@ -115,42 +115,42 @@ f 1 # ``` -You can also explicitly monophasize at the time of use as follows +您也可以在使用时明确单相如下 ```python f: Int -> Int = id|Int| ``` -In that case, the specified type takes precedence over the type of the actual argument (failure to match will result in a type error that the type of the actual argument is wrong). -That is, if the actual object passed can be converted to the specified type, it will be converted; otherwise, a compile error will result. +在这种情况下,指定的类型优先于实际参数的类型(匹配失败将导致类型错误,即实际参数的类型错误)。 +即如果传递的实际对象可以转换为指定的类型,则进行转换; 否则会导致编译错误。 ```python 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 +id|Int|("str") # 类型错误: id|Int| is type `Int -> Int`但得到了 Str ``` -When this syntax is batting against comprehensions, you need to enclose it in `()`. +当此语法与理解相冲突时,您需要将其括在 `()` 中。 ```python -# {id|Int| x | x <- 1..10} would be interpreted as {id | ...} will be interpreted as. +# {id|Int| x | x <- 1..10} 将被解释为 {id | ...} {(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. +不能使用与已存在的类型相同的名称来声明类型变量。 这是因为所有类型变量都是常量。 ```python I: Type -# ↓ invalid type variable, already exists +# ↓ 无效类型变量,已经存在 f|I: Type| ... = ... ``` -## Type arguments in method definitions +## 在方法定义中输入参数 -Type arguments on the left-hand side are treated as bound variables by default. +默认情况下,左侧的类型参数被视为绑定变量。 ```python K(T: Type, N: Nat) = ... @@ -158,76 +158,76 @@ K(T, N). foo(x) = ... ``` -Using another type variable name will result in a warning. +使用另一个类型变量名称将导致警告。 ```python K(T: Type, N: Nat) = ... -K(U, M). # Warning: K's type variable names are 'T' and 'N' +K(U, M). # 警告:K 的类型变量名是 'T' 和 'N' foo(x) = ... ``` -Constants are the same in all namespaces since their definition, so of course they cannot be used for type variable names. +自定义以来,所有命名空间中的常量都是相同的,因此它们当然不能用于类型变量名称 ```python N = 1 -K(N: Nat) = ... # NameError: N is already defined +K(N: Nat) = ... # 名称错误:N 已定义 L(M: Nat) = ... -# 定义ined only if M == N == 1 +# 仅当 M == N == 1 时才定义 L(N). foo(self, x) = ... -# 定义ined for any M: Nat +# 为任何定义 M: Nat L(M). .bar(self, x) = ... ``` -You cannot have multiple definitions for each type argument, but you can define 方法 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). +每个类型参数不能有多个定义,但可以定义具有相同名称的方法,因为未分配类型参数的依赖类型(非原始类型)和分配的依赖类型(原始类型)之间没有关系 )。 ```python K(I: Int) = ... 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) + # K 不是真正的类型(atomic Kind),所以我们不能定义方法 + # 这不是方法(更像是静态方法) 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? +上一节中定义的 `id` 函数是一个可以是任何类型的函数。 那么 `id` 函数本身的类型是什么? ```python print! classof(id) # |T: Type| T -> T ``` -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. +我们得到一个类型`|T: Type| T -> T`。 这称为一个 __封闭的全称量化类型/全称类型__,即`['a. ...]'` 在 ML 和 `forall t. ...` 在 Haskell 中。 为什么使用形容词“关闭”将在下面讨论。 -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. +封闭的全称量化类型有一个限制:只有子程序类型可以被通用量化,即只有子程序类型可以放在左子句中。 但这已经足够了,因为子程序是 Erg 中最基本的控制结构,所以当我们说“我要处理任意 X”时,即我想要一个可以处理任意 X 的子程序。所以,量化类型具有相同的含义 作为多态函数类型。 从现在开始,这种类型基本上被称为多态函数类型。 -Like anonymous functions, polymorphic types have arbitrary type variable names, but they all have the same value. +与匿名函数一样,多态类型具有任意类型变量名称,但它们都具有相同的值。 ```python assert (|T: Type| T -> T) == (|U: Type| U -> U) ``` -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). +当存在 alpha 等价时,等式得到满足,就像在 lambda 演算中一样。 由于对类型的操作有一些限制,所以总是可以确定等价的(如果我们不考虑 stoppage 属性)。 -## 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__. +类型变量在左侧定义并在右侧使用的类型,例如 `OpenFn T: Type = T -> T`,称为 __open 通用类型__。 +相反,在右侧定义和使用类型变量的类型,例如 `ClosedFn = |T: Type| T -> T`,被称为 __封闭的通用类型__。 -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. +开放通用类型是所有同构“真”类型的超类型。 相反,封闭的通用类型是所有同构真类型的子类型。 ```python (|T: Type| T -> T) < (Int -> Int) < (T -> T) ``` -You may remember that closed ones are smaller/open ones are larger. -But why is this so? For a better understanding, let's consider an instance of each. +您可能还记得封闭的较小/开放的较大。 +但为什么会这样呢? 为了更好地理解,让我们考虑每个实例。 ```python # id: |T: Type| T -> T @@ -236,7 +236,7 @@ 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 @@ -244,37 +244,37 @@ id_arbitrary_fn|T|(f1: T -> T): (T -> T) = f # 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 +id_poly_fn(iid) # 类型错误 -# Return Int type function as is +# 按原样返回 Int 类型函数 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)`. +由于 `id` 是 `|T: Type| 类型T -> T`,可以赋值给`Int-> Int`类型的参数`f3`,我们可以考虑`(|T| T -> T) < (Int -> Int)`。 +反之,`Int -> Int`类型的`iid`不能赋值给`(|T| T -> T)`类型的参数`f2`,但可以赋值给`(|T| T -> T)`的参数`f1`输入 `T -> T`,所以 `(Int -> Int) < (T -> T)`。 +因此,确实是`(|T| T -> T) < (Int -> Int) < (T -> T)`。 -## 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. +依赖类型和量化类型(多态函数类型)之间有什么关系,它们之间有什么区别? +我们可以说依赖类型是一种接受参数的类型,而量化类型是一种赋予参数任意性的类型。 -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 方法, etc. using its type argument `T`. +重要的一点是封闭的多态类型本身没有类型参数。例如,多态函数类型`|T| T -> T` 是一个接受多态函数 __only__ 的类型,它的定义是封闭的。您不能使用其类型参数`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 中,类型本身也是一个值,因此带参数的类型(例如函数类型)可能是依赖类型。换句话说,多态函数类型既是量化类型又是依赖类型。 ```python PolyFn = Patch(|T| T -> T) PolyFn. - type self = T # NameError: cannot find 'T' + type self = T # 名称错误:找不到“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 +assert (Int -> Int).type() == Int # 由 DepFn +assert DepFn(Int).type() == Int # 由 DepFn ``` diff --git a/doc/zh_CN/syntax/type/16_subtyping.md b/doc/zh_CN/syntax/type/16_subtyping.md index ca71245c..86c44646 100644 --- a/doc/zh_CN/syntax/type/16_subtyping.md +++ b/doc/zh_CN/syntax/type/16_subtyping.md @@ -1,6 +1,6 @@ -# Subtyping +# 子类型 -In Erg, class inclusion can be determined with the comparison operators `<`, `>`. +在 Erg 中,可以使用比较运算符 `<`、`>` 确定类包含。 ```python Nat < Int @@ -11,20 +11,20 @@ Int < Object {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. +请注意,这与 `<:` 运算符的含义不同。 它声明左侧的类是右侧类型的子类型,并且仅在编译时才有意义。 ```python -C <: T # T: StructuralType +C <: T # T: 结构类型 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)``. +您还可以为多态子类型规范指定 `Self <: Add`,例如 `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. +结构类型是结构类型的类型,如果它们具有相同的结构,则被认为是相同的对象。 ```python T = Structural {i = Int} @@ -36,23 +36,23 @@ 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. +相反,类是符号类型的类型,不能在结构上与类型和实例进行比较 ```python C = Class {i = Int} D = Class {i = Int} -assert C == D # TypeError: cannot compare classes +assert C == D # 类型错误:无法比较类 c = C.new {i = 1} assert c in C assert not c in D ``` -## 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. +子例程的参数和返回值只采用一个类。 +换句话说,您不能直接将结构类型或特征指定为函数的类型。 +必须使用部分类型规范将其指定为“作为该类型子类型的单个类”。 ```python # OK @@ -60,13 +60,13 @@ f1 x, y: Int = x + y # NG f2 x, y: Add = x + y # OK -# A is some concrete class +# A 是一些具体的类 f3 x, y: A = x + y ``` -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`. +子程序中的类型推断也遵循此规则。 当子例程中的变量具有未指定的类型时,编译器首先检查它是否是其中一个类的实例,如果不是,则在特征范围内查找匹配项。 如果仍然找不到,则会发生编译错误。 此错误可以通过使用结构类型来解决,但由于推断匿名类型可能会给程序员带来意想不到的后果,因此它被设计为由程序员使用 `Structural` 显式指定。 -## Class upcasting +## 类向上转换 ```python 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 f1465b5c..bd6abbb1 100644 --- a/doc/zh_CN/syntax/type/17_type_casting.md +++ b/doc/zh_CN/syntax/type/17_type_casting.md @@ -1,12 +1,12 @@ -# Cast +# 投掷 -## Upcasting +## 向上转型 -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. +因为 Python 是一种使用鸭子类型的语言,所以没有强制转换的概念。没有必要向上转型,本质上也没有向下转型。 +但是,Erg 是静态类型的,因此有时必须进行强制转换。 +一个简单的例子是 `1 + 2.0`:`+`(Int, Ratio) 或 Int(<: Add(Ratio, Ratio)) 操作在 Erg 语言规范中没有定义。这是因为 `Int <: Ratio`,所以 1 向上转换为 1.0,即 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扩展字节码在BINARY_ADD中增加了类型信息,此时类型信息为Ratio-Ratio。在这种情况下,BINARY_ADD 指令执行 Int 的转换,因此没有插入指定转换的特殊指令。因此,例如,即使您在子类中重写了某个方法,如果您将父类指定为类型,则会执行类型强制,并在父类的方法中执行该方法(在编译时执行名称修改以引用父母的方法)。编译器只执行类型强制验证和名称修改。运行时不强制转换对象(当前。可以实现强制转换指令以优化执行)。 ~~ ```python @Inheritable @@ -16,7 +16,7 @@ Parent. Child = Inherit Parent Child. - # Override requires Override decorator + # Override 需要 Override 装饰器 @Override greet!() = print! "Hello from Child" @@ -25,11 +25,11 @@ greet! p: Parent = p.greet!() parent = Parent.new() child = Child.new() -parent # "Hello from Parent" greet! -child # "Hello from Parent" +parent # 来自Parent的问候! +child # 来自child的问候! ``` -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. +此行为不会造成与 Python 的不兼容。 首先,Python 没有指定变量的类型,所以可以这么说,所有的变量都是类型变量。 由于类型变量会选择它们可以适应的最小类型,因此如果您没有在 Erg 中指定类型,则可以实现与 Python 中相同的行为。 ```python @Inheritable @@ -46,11 +46,11 @@ greet! some = some.greet!() parent = Parent.new() child = Child.new() -parent # "Hello from Parent" greet! -child # "Hello from Child" +parent # 来自Parent的问候! +child # 来自child的问候! ``` -You can also use `.from` and `.into`, which are automatically implemented for types that are inherited from each other. +您还可以使用 `.from` 和 `.into`,它们会为相互继承的类型自动实现 ```python assert 1 == 1.0 @@ -58,9 +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``. +由于向下转换通常是不安全的并且转换方法很重要,我们改为实现“TryFrom.try_from” ```python IntTryFromFloat = Patch Int diff --git a/doc/zh_CN/syntax/type/18_mut.md b/doc/zh_CN/syntax/type/18_mut.md index 0377d83c..02c3dbd4 100644 --- a/doc/zh_CN/syntax/type/18_mut.md +++ b/doc/zh_CN/syntax/type/18_mut.md @@ -1,9 +1,9 @@ -# Mutable Type +# 可变类型 -> __Warning__: The information in this section is old and contains some errors. +> __Warning__:本节中的信息是旧的并且包含一些错误。 -By default all types in Erg are immutable, i.e. their internal state cannot be updated. -But you can of course also define mutable types. Variable types are declared with `!`. +默认情况下,Erg 中的所有类型都是不可变的,即它们的内部状态无法更新。 +但是你当然也可以定义可变类型。 变量类型用 `!` 声明。 ```python Person! = Class({name = Str; age = Nat!}) @@ -12,12 +12,12 @@ Person!. 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. +准确地说,基类型是可变类型或包含可变类型的复合类型的类型必须在类型名称的末尾有一个“!”。 没有 `!` 的类型可以存在于同一个命名空间中,并被视为单独的类型。 +在上面的例子中,`.age` 属性是可变的,`.name` 属性是不可变的。 如果即使一个属性是可变的,那么整个属性也是可变的。 -Mutable types can define procedural 方法 that rewrite instances, but having procedural 方法 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. +可变类型可以定义重写实例的过程方法,但具有过程方法并不一定使它们可变。 例如数组类型`[T; N]` 实现了一个 `sample!` 随机选择一个元素的方法,但当然不会破坏性地修改数组。 -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`. +对可变对象的破坏性操作主要是通过 .update! 方法完成的。 `.update!` 方法是一个高阶过程,它通过应用函数 `f` 来更新 `self` ```python i = !1 @@ -25,7 +25,7 @@ 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. +`.set!` 方法只是丢弃旧内容并用新值替换它。 .set!x = .update!_ -> x。 ```python i = !1 @@ -33,14 +33,14 @@ i.set! 2 assert i == 2 ``` -The `.freeze_map` method operates on values ​​unchanged. +`.freeze_map` 方法对不变的值进行操作 ```python a = [1, 2, 3].into [Nat; !3] x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(Array) ``` -In a polymorphic immutable type the type argument `T` of the type is implicitly assumed to be immutable. +在多态不可变类型中,该类型的类型参数“T”被隐式假定为不可变。 ```python # ImmutType < Type @@ -48,29 +48,29 @@ 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) . +在标准库中,变量 `(...)!` 类型通常基于不可变 `(...)` 类型。 但是,`T!` 和 `T` 类型没有特殊的语言关系,并且不能这样构造 [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. +请注意,有几种类型的对象可变性。 +下面我们将回顾内置集合类型的不可变/可变语义。 ```python -# array type -## immutable types -[T; N] # Cannot perform mutable operations -## mutable types -[T!; N] # can change contents one by one -[T; !N] # variable length, content is immutable but can be modified by adding/deleting elements -[!T; N] # The content is an immutable object, but it can be replaced 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 +# 数组类型 +## 不可变类型 +[T; N] # 不能执行可变操作 +## 可变类型 +[T; N] # 可以一一改变内容 +[T; !N] # 可变长度,内容不可变但可以通过添加/删除元素来修改 +[!T; N] # 内容是不可变的对象,但是可以替换成不同的类型(实际上可以通过不改变类型来替换) +[!T; !N] # 类型和长度可以改变 +[T; !N] # 内容和长度可以改变 +[!T!; N] # 内容和类型可以改变 +[!T!; !N] # 可以执行各种可变操作 ``` -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. +当然,您不必全部记住和使用它们。 +对于可变数组类型,只需将 `!` 添加到您想要可变的部分,实际上是 `[T; N]`, `[T!; N]`,`[T; !N]`, ` [T!; !N]` 可以涵盖大多数情况。 -These array types are syntactic sugar, the actual types are: +这些数组类型是语法糖,实际类型是: ```python # actually 4 types @@ -83,7 +83,7 @@ These array types are syntactic sugar, the actual types are: [!T!; !N] = ArrayWithMutTypeAndLength!(!T!, !N) ``` -This is what it means to be able to change the type. +这就是能够改变类型的意思。 ```python a = [1, 2, 3].into [!Nat; 3] @@ -91,73 +91,73 @@ a.map!(_ -> "a") a: [!Str; 3] ``` -The same is true for other collection types. +其他集合类型也是如此。 ```python -# 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 +# 元组类型 +## 不可变类型 +(T, U) # 元素个数不变,内容不能变 +## 可变类型 +(T!, U) # 元素个数不变,第一个元素可以改变 +(T,U)! # 元素个数不变,内容可以替换 ... ``` ```python -# 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 +# 设置类型 +## 不可变类型 +{T; N} # 不可变元素个数,内容不能改变 +## 可变类型 +{T!; N} # 不可变元素个数,内容可以改变(一个一个) +{T; N}! # 可变元素个数,内容不能改变 +{T!; N}! # 可变元素个数,内容可以改变 ... ``` ```python -# 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 +# 字典类型 +## 不可变类型 +{K: V} # 长度不可变,内容不能改变 +## 可变类型 +{K:V!} # 恒定长度,值可以改变(一一) +{K:V}! # 可变长度,内容不能改变,但可以通过添加或删除元素来增加或删除,内容类型也可以改变 ... ``` ```python -# 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} +# 记录类型 +## 不可变类型 +{x = Int; y = Str} # 内容不能改变 +## 可变类型 +{x = Int!; y = Str} # 可以改变x的值 +{x = Int; y = Str}! # 替换 {x = Int; 的任何实例 y = Str} ... ``` -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. +一个类型 `(...)` 简单地变成了 `T! = (...)!` 当 `T = (...)` 被称为简单结构化类型。 简单的结构化类型也可以(语义上)说是没有内部结构的类型。 +数组、元组、集合、字典和记录类型都是非简单的结构化类型,但 Int 和 Sieve 类型是。 ```python -# Sieve type -## Enums -{1, 2, 3} # one of 1, 2, 3, cannot be changed -{1, 2, 3}! # 1, 2, 3, you can change -## interval type -1..12 # 1 to 12, cannot be changed -1..12! # Any of 1-12, you can change -## Sieve type (general type) -{I: Int | I % 2 == 0} # even type, immutable -{I: Int! | I % 2 == 0} # even type, can be changed -{I: Int | I % 2 == 0}! # Exactly the same type as above, but the above notation is preferred +#筛子类型 +## 枚举 +{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}! # 与上面完全相同的类型,但上面的表示法是首选 ``` -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. +从上面的解释来看,可变类型不仅包括自身可变的,还包括内部类型可变的。 +诸如 `{x: Int!}` 和 `[Int!; 之类的类型3]` 是内部可变类型,其中内部的对象是可变的,而实例本身是不可变的。 -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. +对于具有内部结构并在类型构造函数本身上具有 `!` 的类型 `K!(T, U)`,`*self` 可以更改整个对象。也可以进行局部更改。 +但是,希望尽可能保持本地更改权限,因此如果只能更改 `T`,最好使用 `K(T!, U)`。 +而对于没有内部结构的类型‘T!’,这个实例只是一个可以交换的‘T’盒子。方法不能更改类型。 --- -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 +1 `T!` 和 `T` 类型没有特殊的语言关系是有意的。这是一个设计。如果存在关系,例如命名空间中存在`T`/`T!`类型,则无法从其他模块引入`T!`/`T`类型。此外,可变类型不是为不可变类型唯一定义的。给定定义 `T = (U, V)`,`T!` 的可能变量子类型是 `(U!, V)` 和 `(U, V!)`。[↩](#f1) \ No newline at end of file diff --git a/doc/zh_CN/syntax/type/19_bound.md b/doc/zh_CN/syntax/type/19_bound.md index c3365d95..a7876319 100644 --- a/doc/zh_CN/syntax/type/19_bound.md +++ b/doc/zh_CN/syntax/type/19_bound.md @@ -1,13 +1,13 @@ -# 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 +## 谓词 -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. +您可以使用返回 `Bool` 的表达式(谓词表达式)指定变量满足的条件。 +只能使用 [值对象](./08_value.md) 和运算符。 未来版本可能会支持编译时函数 ```python f a: [T; N] | T, N, N > 5 = ... diff --git a/doc/zh_CN/syntax/type/advanced.md b/doc/zh_CN/syntax/type/advanced.md index 1fdeed74..01dd89dc 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 +下面,我们将讨论更高级的类型系统。 初学者不必阅读所有部分。 \ No newline at end of file From 3b5bbb59bc0a5cd435cb211ec6aae2cfa95b07cf Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 20:27:44 +0800 Subject: [PATCH 17/42] translate save --- doc/zh_CN/syntax/00_basic.md | 76 +++++++-------- doc/zh_CN/syntax/01_literal.md | 67 ++++++------- doc/zh_CN/syntax/02_name.md | 92 +++++++++--------- doc/zh_CN/syntax/03_declaration.md | 26 ++--- doc/zh_CN/syntax/04_function.md | 136 +++++++++++++-------------- doc/zh_CN/syntax/05_builtin_funcs.md | 14 +-- doc/zh_CN/syntax/06_operator.md | 18 ++-- doc/zh_CN/syntax/07_side_effect.md | 72 +++++++------- doc/zh_CN/syntax/08_procedure.md | 6 +- doc/zh_CN/syntax/09_builtin_procs.md | 10 +- doc/zh_CN/syntax/10_array.md | 26 ++--- doc/zh_CN/syntax/11_tuple.md | 53 +++++------ doc/zh_CN/syntax/12_dict.md | 30 +++--- doc/zh_CN/syntax/13_record.md | 92 +++++++++--------- doc/zh_CN/syntax/14_set.md | 17 ++-- doc/zh_CN/syntax/15_type.md | 4 +- doc/zh_CN/syntax/16_iterator.md | 30 +++--- doc/zh_CN/syntax/17_mutability.md | 64 ++++++------- doc/zh_CN/syntax/18_ownership.md | 82 ++++++++-------- doc/zh_CN/syntax/19_visibility.md | 68 +++++++------- doc/zh_CN/syntax/20_naming_rule.md | 26 ++--- doc/zh_CN/syntax/21_lambda.md | 53 ++++++----- doc/zh_CN/syntax/22_subroutine.md | 32 +++---- doc/zh_CN/syntax/23_closure.md | 38 ++++---- doc/zh_CN/syntax/24_module.md | 6 +- doc/zh_CN/syntax/25_object_system.md | 80 ++++++++-------- 26 files changed, 609 insertions(+), 609 deletions(-) diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md index a1383dfd..1a86adf8 100644 --- a/doc/zh_CN/syntax/00_basic.md +++ b/doc/zh_CN/syntax/00_basic.md @@ -1,46 +1,46 @@ -# Basics +# 基本 -> __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. +> __Warning__:本文档不完整。 它未经校对(样式、正确链接、误译等)。 此外,Erg 的语法可能在版本 0.* 期间发生破坏性更改,并且文档可能没有相应更新。 请事先了解这一点。 +> 如果您在本文档中发现任何错误,请报告至 [此处的表单](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我们将不胜感激您的建议。 > -> [The Erg book original version (Japanese)](http://mtshiba.me/TheErgBook/) +> [Erg原版(日文)](http://mtshiba.me/TheErgBook/) -This document describes the basic syntax of Erg. The [Standard API](./API/index.md) and [internal documents for Erg contributors](./dev_guide/index.md) are located in another directory. +本文档描述 Erg 的基本语法。 [标准 API](./API/index.md) 和 [Erg 贡献者的内部文档](./dev_guide/index.md) 位于另一个目录中。 -## Hello, World! +## 你好,世界! -First, let's do "Hello World". +首先,让我们做“Hello World”。 ```python print!("Hello, World!") ``` -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. +这与 Python 和同一家族中的其他语言几乎相同。 最显着的特征是`!`,后面会解释它的含义。 +在 Erg 中,括号 `()` 可以省略,除非在解释上有一些混淆。 +括号的省略与 Ruby 类似,但不能省略可以以多种方式解释的括号。 ```python 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! # OK, 但这并不意味着调用,只是将 `print!` 作为可调用对象 -print! f x # OK, interpreted as `print!(f(x))` +print! f x # OK, 解释为 `print!(f(x))` print!(f(x, y)) # OK print! f(x, y) # OK print! f(x, g y) # OK -print! f x, y # NG, 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))` +print! f x, y # NG, 可以理解为 `print!(f(x), y)` 或 `print!(f(x, y))` print! +print!(f x, y) # NG, 可以表示“print!(f(x),y)”或“print!(f(x,y))” +print! f(x, g y, z) # NG, 可以表示“print!(x,g(y),z)”或“print!(x,g(y,z))” ``` -## Scripts +## 脚本 -Erg code is called a script. Scripts can be saved and executed in file format (.er). +Erg 代码称为脚本。 脚本可以以文件格式 (.er) 保存和执行。 -## REPL/File Execution +## REPL/文件执行 -To start REPL, simply type: +要启动 REPL,只需键入: ```sh > erg @@ -66,9 +66,9 @@ Or you can compile from a file. 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. +`#` 之后的代码作为注释被忽略。 使用它来解释代码的意图或暂时禁用代码。 ```python # Comment @@ -79,21 +79,21 @@ Treated as a comment all the way up to the corresponding `]#` ]# ``` -## 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 中几乎所有东西都是表达式。 +每个表达式由分隔符分隔 - 新行或分号 `;`-。 +Erg 脚本基本上是从左到右、从上到下进行评估的。 ```python -n = 1 # assignment expression -f(1, 2) # function-call expression -1 + 1 # operator-call expression +n = 1 # 赋值表达式 +f(1, 2) # 函数调用表达式 +1 + 1 # 运算符调用表达式 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. +如下所示,有一种称为 Instant block 的语法,它将块中评估的最后一个表达式作为变量的值。 +这与没有参数的函数不同,它不添加 `()`。 请注意,即时块仅在运行中评估一次 ```python i = @@ -102,15 +102,15 @@ i = assert i == 2 ``` -This cannot be accomplished with a semicolon (`;`). +这不能用分号 (`;`) 完成。 ```python -i = (x = 1; x + 1) # SyntaxError: cannot use `;` in parentheses +i = (x = 1; x + 1) # 语法错误:不能在括号中使用 `;` ``` -## 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 和 Python 一样,使用缩进来表示块。 有五个运算符(特殊形式)触发块的开始:`=`、`->`、`=>`、`do` 和 `do!`(此外,`:` 和 `|` ,虽然不是运算符,但也会产生缩进)。 每个的含义将在后面描述。 ```python f x, y = @@ -129,15 +129,15 @@ ans = match x: _ -> "unknown" ``` -If a line is too long, it can be broken using `\`. +如果一行太长,可以使用 `\` 将其断开 ```python -# this does not means `x + y + z` but means `x; +y; +z` -x +# 这不是表示 `x + y + z` 而是表示 `x; +y; +z` +X + y + z -# this means `x + y + z` +# 这意味着`x + y + z` x \ + y \ + z diff --git a/doc/zh_CN/syntax/01_literal.md b/doc/zh_CN/syntax/01_literal.md index 8c85b141..a285d8d3 100644 --- a/doc/zh_CN/syntax/01_literal.md +++ b/doc/zh_CN/syntax/01_literal.md @@ -1,40 +1,40 @@ -# Literal +# 字面量 -## Basic Literals +## 基本字面量 -### Int Literal +### 整数字面量 ```python 0, -0, 1, -1, 2, -2, 3, -3, ... ``` -### Ratio Literal +### 比率文字 ```python 0.00, -0.0, 0.1, 400.104, ... ``` -If a `Ratio` literal has an integer or decimal part of `0`, you can omit the `0`. +如果“比率”文字的整数或小数部分为`0`,则可以省略`0` ```python 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. +> __注意__:这个函数 `assert` 用于表明 `1.0` 和 `1.` 相等。 +后续文档可能会使用 `assert` 来表示结果是相等的。 -### 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 `\"`. +可以使用任何 Unicode 可表示的字符串。 +与 Python 不同,引号不能包含在 `'` 中。 如果要在字符串中使用 `"`,请使用 `\"`。 ```python "", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "السَّلَامُ عَلَيْكُمْ", ... ``` -`{}` allows you to embed expressions in strings. This is called string interpolation. -If you want to output `{`, `}` itself, use `\{`, `\}`. +`{}` 允许您在字符串中嵌入表达式。 这称为字符串插值。 +如果要输出 `{`、`}` 本身,请使用 `\{`、`\}`。 ```python assert "1 + 1 is 2" == "{1} + {1} is {1+1}" @@ -42,10 +42,10 @@ s = "1+1" assert "\{1+1}\" == "\{{s}\}" ``` -### 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. +这是学术计算中常用的表示指数符号的文字。 它是“比率”类型的一个实例。 +该符号与 Python 中的符号相同。 ```python 1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ... @@ -55,61 +55,61 @@ The notation is the same as in Python. assert 1e-10 == 0.0000000001 ``` -## Compound Literals +## 复合字面量 -Each of these literals has its own documentation describing them separately, so please refer to that documentation for details. +这些文字中的每一个都有自己的文档分别描述它们,因此请参阅该文档以获取详细信息。 -### [Array Literal](./10_array.md) +### [数组字面量](./10_array.md) ```python [], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ... ``` -### [Dict Literal](./11_dict.md) +### [字典字面量](./11_dict.md) ```python {:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ... ``` -### [Tuple Literal](./12_tuple.md) +### [元组字面量](./12_tuple.md) ```python (), (1, 2, 3), (1, "hello", True), ... ``` -### [Record Literal](./13_record.md) +### [Record 字面量](./13_record.md) ```python {=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ... ``` -### [Set Literal](./14_set.md) +### [Set 字面量](./14_set.md) ```python {}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ... ``` -As a difference from `Array` literals, duplicate elements are removed in `Set`. +与 `Array` 字面量不同的是,`Set` 中删除了重复元素 ```python assert {1, 2, 1} == {1, 2} ``` -### What looks like a literal but isn't +### 看起来像文字但不是 -## Boolean Object +## 布尔对象 ```python True, False ``` -### None Object +### None 对象 ```python None ``` -## Range Object +## Range 对象 ```python assert 0..5 == {1, 2, 3, 4, 5} @@ -118,26 +118,27 @@ assert 0..<10 notin 10 assert 0..9 == 0..<10 ``` -## Float Object +## Float 对象 ```python assert 0.0f64 == 0 assert 0.0f32 == 0.0f64 ``` -Float objects are constructed by multiplying a `Ratio` object by `f64`, which is a `Float 64` unit object. +浮点对象是通过将 `Ratio` 对象乘以 `f64` 构造的,后者是 `Float 64` 单位对象 -## Complex Object +## Complex 对象 ```python 1+2im, 0.4-1.2im, 0im, im ``` -A `Complex` object is simply an arithmetic combination of an imaginary unit object, `im`. +一个“复杂”对象只是一个虚数单位对象`im`的算术组合 -## *-less multiplication -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 `*`. +## *-less 乘法 + +在 Erg 中,您可以省略 `*` 来表示乘法,只要解释上没有混淆即可。 但是,运算符的组合强度设置为强于 `*`。 ```python # 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 750cbfa8..a4f8a26f 100644 --- a/doc/zh_CN/syntax/02_name.md +++ b/doc/zh_CN/syntax/02_name.md @@ -1,81 +1,81 @@ -# Variable +# 多变的 -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. +变量是一种代数; Erg 中的代数 - 如果没有混淆,有时简称为变量 - 指的是命名对象并使它们可从代码的其他地方引用的功能。 -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. +变量定义如下。 +`n` 部分称为变量名(或标识符),`=` 是赋值运算符,`1` 部分是赋值。 ```python 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.). +以这种方式定义的“n”此后可以用作表示整数对象“1”的变量。 该系统称为分配(或绑定)。 +我们刚刚说过`1`是一个对象。 稍后我们将讨论对象是什么,但现在我们假设它是可以赋值的,即在赋值运算符的右侧(`=` 等)。 -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. +如果要指定变量的“类型”,请执行以下操作。 类型大致是一个对象所属的集合,后面会解释。 +这里我们指定`n`是自然数(`Nat`)类型。 ```python n: Nat = 1 ``` -Note that, unlike other languages, multiple assignments are not allowed. +请注意,与其他语言不同,不允许多次分配 ```python # NG -l1 = l2 = [1, 2, 3] # SyntaxError: multiple assignment not allowed +l1 = l2 = [1, 2, 3] # 语法错误:不允许多重赋值 # 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. +也不能重新分配给变量。 稍后将描述可用于保存可变状态的语法 ```python i = 1 -i = i + 1 # AssignError: cannot assign twice +i = i + 1 # 分配错误:不能分配两次 ``` -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. +您可以在内部范围内定义具有相同名称的变量,但您只是覆盖它,而不是破坏性地重写它的值。 如果您返回外部范围,该值也会返回。 +请注意,这是与 Python “语句”范围不同的行为。 +这种功能通常称为阴影。 但是,与其他语言中的阴影不同,您不能在同一范围内进行阴影。 ```python x = 0 -# x = 1 # AssignError: cannot assign twice +# x = 1 # 赋值错误:不能赋值两次 if x.is_zero(), do: - x = 1 # different from outer x with same name + x = 1 # 与同名的外部 x 不同 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. +乍一看,以下内容似乎可行,但仍然不可能。 这是一个设计决定,而不是技术限制。 ```python x = 0 if x.is_zero(), do: - x = x + 1 # NameError: cannot define variables refer to variables with the same name + x = x + 1 # 名称错误:无法定义变量引用同名变量 assert x == 1 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. +常数也是一种代数。 如果标识符以大写字母开头,则将其视为常量。 它们被称为常量,因为一旦定义,它们就不会改变。 +`N` 部分称为常量名(或标识符)。 否则,它与变量相同。 ```python N = 0 if True, do: - N = 1 # AssignError: constants cannot be shadowed + N = 1 # 赋值错误:常量不能被遮蔽 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). +除了 [types](./type/01_type_system.md) 之外的对象标识符使用全大写(所有字母大写的样式)是常见的做法。 ```python PI = 3.141592653589793 @@ -90,19 +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`. +当 `x` 为 `3.141592653589793` 时,上面的代码会打印 `π`。 如果 `x` 更改为任何其他数字,它会打印 `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. +有些对象不能绑定为常量。 例如,可变对象。 可变对象是其状态可以改变的对象,后面会详细介绍。 +这是因为只有常量表达式才能分配给常量的规则。 常量表达式也将在后面讨论。 ```python X = 1 # OK -X = !1 # TypeError: cannot define Int! object as a constant +X = !1 # 类型错误:无法定义 Int! 对象作为常量 ``` -## 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. +您可以使用 `Del` 函数删除变量。 依赖于变量的所有其他变量(即直接引用变量值的变量)也将被删除。 ```python x = 1 @@ -114,19 +114,19 @@ assert f(2) == 3 Del x Del y, Z -f(2) # NameError: f is not defined (deleted in line 6) +f(2) # 名称错误:f 未定义(在第 6 行中删除) ``` -Note that `Del` can only delete variables defined in the user-defined module. Built-in constants such as `True` cannot be deleted. +注意 `Del` 只能删除用户自定义模块中定义的变量。 无法删除诸如“True”之类的内置常量。 ```python -Del True # TypeError: cannot delete built-in constants -Del print! # TypeError: cannot delete built-in variables +Del True # 类型错误:无法删除内置常量 +Del print! # TypeError: 无法删除内置变量 ``` -## 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. +请注意,当 `x = a` 时,`x == a` 不一定为真。 一个例子是`Float.NaN`。 这是 IEEE 754 定义的浮点数的正式规范。 ```python x = Float.NaN @@ -134,29 +134,29 @@ assert x ! = NaN assert x ! = x ``` -There are other objects for which no equivalence relation is defined in the first place. +还有其他对象首先没有定义等价关系。 ```python f = x -> x**2 + 2x + 1 g = x -> (x + 1)**2 -f == g # TypeError: cannot compare function objects +f == g # 类型错误:无法比较函数对象 C = Class {i: Int} D = Class {i: Int} -C == D # TypeError: cannot compare class objects +C == D # 类型错误:无法比较类对象 ``` -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. +严格来说,`=` 不会将右侧的值直接分配给左侧的标识符。 +在函数和类对象的情况下,执行“修改”,例如将变量名称信息赋予对象。 但是,结构类型并非如此。 ```python f x = x -print! f # +print! f # <函数 f> g x = x + 1 -print! g # +print! g # <函数 g> C = Class {i: Int} -print! C # +print! C # <类 C> ```

diff --git a/doc/zh_CN/syntax/03_declaration.md b/doc/zh_CN/syntax/03_declaration.md index 5c9e8924..5dda32df 100644 --- a/doc/zh_CN/syntax/03_declaration.md +++ b/doc/zh_CN/syntax/03_declaration.md @@ -1,12 +1,12 @@ -# Declaration +# 宣言(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. +声明是用于指定要使用的变量类型的语法。 +可以在代码中的任何地方进行声明,但单独的声明并不引用变量。 它们必须被初始化。 +分配后,可以检查声明以确保类型与分配它的对象兼容。 ```python i: Int -# Can be declared at the same time as the assignment, like i: Int = 2 +# 可以与赋值同时声明,如 i: Int = 2 i = 2 i: Num i: Nat @@ -14,24 +14,24 @@ i: -2..2 i: {2} ``` -Declaration after assignment is similar to type checking by `assert`, but has the feature that it is checked at compile time. -Type checking by `assert` at runtime can be checked for "may be type Foo", but type checking by `:` at compile time is strict: if the type is not determined to be "type Foo", it will not pass the check and an error will occur. +赋值后的声明类似于`assert`的类型检查,但具有在编译时检查的特点。 +在运行时通过`assert`进行类型检查可以检查“可能是Foo类型”,但是在编译时通过`:`进行类型检查是严格的:如果类型未确定为“类型Foo”,则不会通过 检查会出现错误。 ```python 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) +assert i in Nat # 这可能会通过 +i: Int # 这会通过 +i: Nat # 这不会通过(-1 不是 Nat 的元素) ``` -Functions can be declared in 2 different ways. +函数可以用两种不同的方式声明。 ```python f: (x: Int, y: Int) -> Int f: (Int, Int) -> Int ``` -If you declare the argument names explicitly, a type error will result if the names are different at definition time. If you want to give the argument names arbitrary names, you can declare them in the second way. In that case, only the method name and its type will be seen by type checking. +如果显式声明参数名称,如果在定义时名称不同,则会导致类型错误。 如果你想给参数名称任意命名,你可以用第二种方式声明它们。 在这种情况下,类型检查只会看到方法名称及其类型。 ```python T = Trait { @@ -39,7 +39,7 @@ T = Trait { } 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` +C.f(a: Int, b: Int): Int = ... # 类型错误:`.f` 必须是 `(x: Int, y: Int) -> Int` 的类型,而不是 `(a: Int, b: Int) -> Int` ```

diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md index 962c90e0..21c016cd 100644 --- a/doc/zh_CN/syntax/04_function.md +++ b/doc/zh_CN/syntax/04_function.md @@ -1,17 +1,17 @@ -# Function +# 功能 -A function is a block that takes an "argument", processes it, and returns it as a "return value". It is defined as follows. +函数是一个块,它接受一个“参数”,对其进行处理,并将其作为“返回值”返回。 定义如下。 ```python add x, y = x + y -# or +# 或者 add(x, y) = x + y ``` -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. +在函数名之后指定的名称称为参数。 +相反,传递给函数的对象称为参数。 +函数 `add` 是一个以 `x` 和 `y` 作为参数并返回它们之和的函数,`x + y`。 +可以按如下方式调用(应用/调用)定义的函数。 ```python add 1, 2 @@ -19,9 +19,9 @@ 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). +函数像`f x, y, ...`一样被调用,但是如果单行参数太多,可以使用`:`(冒号)来应用它们。 ```python f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4 @@ -38,7 +38,7 @@ f: 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. +以上三个代码的含义相同。 例如,这种风格在使用 `if` 函数时也很有用 ```python result = if Bool.sample!(): @@ -50,39 +50,39 @@ result = if Bool.sample!(): 0 ``` -After `:`, no code other than comments may be written, and must always be on a new line. +在 `:` 之后,除了注释之外,不得编写任何代码,并且必须始终在新行上 -## 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. +如果使用大量参数定义函数,则存在以错误顺序传递参数的危险。 +在这种情况下,使用关键字参数调用函数是安全的。 ```python f x, y, z, w, v, u: Int = ... ``` -The functions defined above have many arguments and are arranged in a confusing order. You should not create such a function, but you may encounter such code when using code written by others. Therefore, we use keyword arguments. If you use keyword arguments, the values are passed from the name to the correct argument, even if they are in the wrong order. +上面定义的函数有很多参数,并且排列顺序混乱。 您不应该创建这样的函数,但是在使用别人编写的代码时可能会遇到这样的代码。 因此,我们使用关键字参数。 如果使用关键字参数,则值会从名称传递到正确的参数,即使它们的顺序错误。 ```python f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3 ``` -Note that keyword arguments and a new line immediately after the `:` are considered a colon-call style. +请注意,紧跟在 `:` 之后的关键字参数和新行被视为冒号调用样式 ```python -# means `f(x: y)` +# 意思是 `f(x: y)` f x: y -# means `f(x, y)` +# 意思是 `f(x, y)` f x: y ``` -## 定义ault parameters +## 定义错误参数 -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`. +默认参数由`:=`(walrus运算符)指定。 如果未指定 `base`,则将 `math.E` 分配给 `base`。 ```python math_log x: Ratio, base := math.E = ... @@ -91,7 +91,7 @@ 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`. +请注意,不指定参数和指定`None`是有区别的 ```python p! x := 0 = print! @@ -100,34 +100,34 @@ p!() # 0 p!(None) # None ``` -Can also be used with type specification and patterns. +也可以与类型规范和模式一起使用 ```python math_log x, base: Ratio := math.E = ... f [x, y] := [1, 2] = ... ``` -However, within the default arguments, it is not possible to call the procedures (described later) or assign mutable objects. +但是,在默认参数中,不能调用过程(稍后描述)或分配可变对象 ```python f x := p! 1 = ... # NG ``` -Also, the argument just defined cannot be used as the value passed to the default argument. +此外,刚刚定义的参数不能用作传递给默认参数的值 ```python 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. +输出其参数的日志(记录)的 `log` 函数可以采用任意数量的参数。 -```python -log "Hello", "World", "!" # Hello World ! +```蟒蛇 +记录“你好”、“世界”、“!” # 你好世界 ! ``` -To define such a function, add `...` to a parameter. This way, the function receives arguments as a variable-length array. +要定义这样的函数,请将 `...` 添加到参数中。 这样,函数将参数作为可变长度数组接收 ```python f ...x = @@ -138,7 +138,7 @@ f ...x = f 1, 2, 3, 4, 5 ``` -## Function definition with multiple patterns +## 具有多种模式的函数定义 ```python fib n: Nat = @@ -148,7 +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. +像上面这样的函数,其中 `match` 直接出现在定义下,可以重写如下 ```python fib 0 = 0 @@ -156,26 +156,26 @@ fib 1 = 1 fib(n: Nat): Nat = fib(n - 1) + fib(n - 2) ``` -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. +注意一个函数定义有多个模式不是所谓的重载(multiple definition); 一个函数只有一个定义。 在上面的示例中,“n”必须与“0”或“1”属于同一类型。 此外,与 `match` 一样,模式匹配是从上到下完成的。 -If instances of different classes are mixed, the last definition must specify that the function argument is of type `Or`. +如果不同类的实例混合在一起,最后一个定义必须指定函数参数的类型为`Or` ```python f "aa" = ... f 1 = ... -# `f x = ... ` is invalid +# `f x = ... ` 无效 f x: Int or Str = ... ``` -Also, like `match`, it must also be exhaustive. +此外,像 `match` 一样,它也必须是详尽的。 ```python fib 0 = 0 fib 1 = 1 -# PatternError: pattern of fib's parameter is not exhaustive +# 模式错误:fib 参数的模式并不详尽 ``` -However, it can be made exhaustive by explicitly specifying the type using the [refinement type](./type/12_refinement.md) described later. +但是,可以通过使用稍后描述的 [refinement type](./type/12_refinement.md) 显式指定类型来使其详尽无遗。 ```python fib: 0..1 -> 0..1 @@ -184,12 +184,12 @@ fib 1 = 1 # OK ``` -## Recursive functions +## 递归函数 -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`. +作为一个简单的例子,让我们定义一个执行阶乘计算的函数`factorial`。 阶乘是“将所有小于或等于的正数相乘”的计算。 +5 的阶乘是 `5*4*3*2*1 == 120`。 ```python factorial 0 = 1 @@ -197,13 +197,13 @@ factorial 1 = 1 factorial(n: Nat): Nat = n * factorial(n - 1) ``` -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. +首先,从阶乘的定义来看,0和1的阶乘都是1。 +反过来,2的阶乘是`2*1 == 2`,3的阶乘是`3*2*1 == 6`,4的阶乘是`4*3*2*1 == 24 `。 +如果我们仔细观察,我们可以看到一个数 n 的阶乘是前一个数 n-1 乘以 n 的阶乘。 +将其放入代码中,我们得到 `n * factorial(n - 1)`。 +由于 `factorial` 的定义包含自身,`factorial` 是一个递归函数。 -As a reminder, if you do not add a type specification, it is inferred like this. +提醒一下,如果您不添加类型规范,则会这样推断。 ```python factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int @@ -212,20 +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 +但是,即使您可以推理,您也应该明确指定递归函数的类型。 在上面的例子中,像“factorial(-1)”这样的代码可以工作,但是 ```python 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. +函数名以大写字母开头,表示编译时函数。 用户定义的编译时函数必须将所有参数作为常量,并且必须指定它们的类型。 +编译时函数的功能有限。 在编译时函数中只能使用常量表达式,即只有一些运算符(例如求积、比较和类型构造操作)和编译时函数。 要传递的参数也必须是常量表达式。 +作为回报,优点是计算可以在编译时完成。 ```python Add(X, Y: Nat): Nat = X + Y @@ -236,32 +236,32 @@ 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 +Sin X = math.sin X # 常量错误:此函数在编译时不可计算 ``` -Compile-time functions are also used in polymorphic type definitions. +编译时函数也用于多态类型定义。 ```python Option T: Type = T or NoneType Option: Type -> Type ``` -## Appendix: Function Comparison +## 附录:功能对比 -Erg does not define `==` for functions. This is because there is no structural equivalence algorithm for functions in general. +Erg 没有为函数定义 `==`。 这是因为通常没有函数的结构等价算法。 ```python f = x: Int -> (x + 1)**2 g = x: Int -> x**2 + 2x + 1 -assert f == g # TypeError: cannot compare functions +assert f == g # 类型错误:无法比较函数 ``` -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. +尽管 `f` 和 `g` 总是返回相同的结果,但要做出这样的决定是极其困难的。 我们必须向编译器教授代数。 +所以 Erg 完全放弃了函数比较,并且 `(x -> x) == (x -> x)` 也会导致编译错误。 这是与 Python 不同的规范,应该注意 ```python -# Python, weird example +# Python,奇怪的例子 f = lambda x: x assert f == f assert (lambda x: x) ! = (lambda x: x) @@ -271,19 +271,19 @@ assert (lambda x: x) ! = (lambda x: x) ```python 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 # 类型错误:f() 接受 1 个位置参数,但给出了 2 个 +f(a, b) # # 类型错误:f() 接受 1 个位置参数,但给出了 2 个 f((a, b)) # OK ``` -The function type `T -> U` is actually the syntax sugar of `(T,) -> U`. +函数类型`T -> U`实际上是`(T,) -> U`的语法糖。

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/05_builtin_funcs.md b/doc/zh_CN/syntax/05_builtin_funcs.md index e696d9bb..9a21013c 100644 --- a/doc/zh_CN/syntax/05_builtin_funcs.md +++ b/doc/zh_CN/syntax/05_builtin_funcs.md @@ -1,8 +1,8 @@ -# Built-in functions +# 内置函数 -## if +## 如果 -`if` is a function that changes processing depending on a condition. +`if` 是一个根据条件改变处理的函数。 ```python result: Option Int = if! Bool.sample!(), do: @@ -11,8 +11,8 @@ result: Option Int = if! Bool.sample!(), do: print! result # None (or 1) ``` -`.sample!()` returns a random set of values. If the return value is true, `print! "True"` is executed. -You can also specify what to do if the condition is false; the second do block is called the else block. +`.sample!()` 返回一组随机值。 如果返回值为真,`print! “真”`被执行。 +如果条件为假,您还可以指定要执行的操作; 第二个 do 块称为 else 块。 ```python result: Nat = if Bool.sample!(): @@ -25,7 +25,7 @@ result: Nat = if Bool.sample!(): print! result # 1 (or 0) ``` -If the process is a single line, you can omit indentation. +如果进程是单行,则可以省略缩进。 ```python result = if Bool.sample!(): @@ -35,7 +35,7 @@ result = if Bool.sample!(): ## for -You can use `for` to write a repeating process. +你可以使用 `for` 来编写一个重复的过程。 ```python 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 f4a25d01..7f733b4a 100644 --- a/doc/zh_CN/syntax/06_operator.md +++ b/doc/zh_CN/syntax/06_operator.md @@ -1,26 +1,26 @@ -# operator +# 运算符 -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. +运算符是一种函数,因此它们本身就是可以绑定到变量的一流对象。 绑定时,需要用```括起来。 +对于`+`(和`-`),有一元和二元运算符,所以必须指定`_+_`(二元运算)/`+_`(一元运算)。 ```python -add = `+` # SyntaxError: specify `_+_` or `+_` +add = `+` # 语法错误:指定 `_+_` 或 `+_` add=`_+_` assert f(1, 2) == 3 assert f("a", "b") == "ab" -g = `*` # OK, this is binary only +g = `*` # OK, 这只是二进制 assert g(1, 2) == 2 ``` -Some fundamental operators, called special forms, cannot be bound. +一些称为特殊形式的基本运算符不能被绑定。 ```python -def = `=` # SyntaxError: cannot bind `=` operator, this is a special form +def = `=` # 语法错误:无法绑定 `=` 运算符,这是一种特殊形式 # NG: def x, 1 -function = `->` # SyntaxError: cannot bind `->` operator, this is a special form +function = `->` # 语法错误:无法绑定 `->` 运算符,这是一种特殊形式 # NG: function x, x + 1 ``` diff --git a/doc/zh_CN/syntax/07_side_effect.md b/doc/zh_CN/syntax/07_side_effect.md index e0604cbe..bbae2ecd 100644 --- a/doc/zh_CN/syntax/07_side_effect.md +++ b/doc/zh_CN/syntax/07_side_effect.md @@ -1,44 +1,44 @@ -# 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. +我们一直忽略了解释“!”的含义,但现在它的含义终于要揭晓了。 这个 `!` 表示这个对象是一个带有“副作用”的“过程”。 过程是具有副作用的函数。 ```python -f x = print! x # EffectError: functions cannot be assigned objects with side effects -# hint: change the name to 'f!' +f x = print! x # EffectError: 不能为函数分配有副作用的对象 +# 提示:将名称更改为 '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. +上面的代码会导致编译错误。 这是因为您在函数中使用了过程。 在这种情况下,您必须将其定义为过程。 ```python 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. +`p!`, `q!`, ... 是过程的典型变量名。 +以这种方式定义的过程也不能在函数中使用,因此副作用是完全隔离的。 ## 方法 -Functions and procedures each can be 方法. Functional 方法 can only take immutable references to `self`, while procedural 方法 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. +函数和过程中的每一个都可以是方法。 函数式方法只能对`self`进行不可变引用,而程序性方法可以对`self`进行可变引用。 +`self` 是一个特殊的参数,在方法的上下文中是指调用对象本身。 引用 `self` 不能分配给任何其他变量。 ```python C!. method ref self = - x = self # OwnershipError: cannot move out 'self' + x = self # 所有权错误:无法移出`self` x ``` -Procedural 方法 can also take [ownership](./18_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition. +程序方法也可以采取 `self` 的 [ownership](./18_ownership.md)。 从方法定义中删除 `ref` 或 `ref!` ```python n = 1 s = n.into(Str) # '1' -n # ValueError: n was moved by .into (line 2) +n # 值错误:n 被 .into 移动(第 2 行) ``` -Only one procedural 方法 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`. +在任何给定时间,只有一种程序方法可以具有可变引用。 此外,在获取可变引用时,不能从原始对象获取更多可变引用。 从这个意义上说,`ref!` 会对`self` 产生副作用。 -Note, however, that it is possible to create (immutable/mutable) references from mutable references. This allows recursion and `print!` of `self` in procedural 方法. +但是请注意,可以从可变引用创建(不可变/可变)引用。 这允许在程序方法中递归和 `print!` 的`self`。 ```python T -> T # OK (move) @@ -52,23 +52,23 @@ T -> Ref T # OK T => Ref! ``` -## 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. +代码是否具有副作用的规则无法立即理解。 +直到你能理解它们,我们建议你暂时把它们定义为函数,如果出现错误,添加`!`将它们视为过程。 +但是,对于那些想了解该语言的确切规范的人,以下是对副作用的更详细说明。 -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)`. +首先,必须声明返回值的等价与 Erg 中的副作用无关。 +有些过程对于任何给定的 `x` 都会导致 `p!(x) == p!(x)`(例如,总是返回 `None`),并且有些函数会导致 `f(x) ! = f(x)`。 -An example of the former is `print!`, and an example of the latter is the following function. +前者的一个例子是`print!`,后者的一个例子是下面的函数。 ```python nan _ = Float.NaN assert nan(1) ! = nan(1) ``` -There are also objects, such as classes, for which equivalence determination itself is not possible. +还有一些对象,例如类,等价确定本身是不可能的 ```python T = Structural {i = Int} @@ -77,16 +77,16 @@ assert T == U C = Class {i = Int} D = Class {i = Int} -assert C == D # TypeError: cannot compare classes +assert C == D # 类型错误:无法比较类 ``` -Back to the point: the precise definition of "side-effect" in Erg is +言归正传:Erg 中“副作用”的准确定义是 -* Accessing mutable external information. +* 访问可变的外部信息。 -"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. +“外部”一般是指外部范围; Erg 无法触及的计算机资源和执行前/执行后的信息不包含在“外部”中。 “访问”包括阅读和写作。 -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: +例如,考虑 `print!` 过程。 乍一看,`print!` 似乎没有重写任何变量。 但如果它是一个函数,它可以重写外部变量,例如,使用如下代码: ```python camera = import "some_camera_module" @@ -94,27 +94,27 @@ ocr = import "some_ocr_module" n = 0 _ = - f x = print x # Suppose we could use print as a function + f x = print x # 假设我们可以使用 print 作为函数 f(3.141592) -cam = camera.new() # camera faces PC display +cam = camera.new() # 摄像头面向 PC 显示器 image = cam.shot!() n = ocr.read_num(image) # n = 3.141592 ``` -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. +将“camera”模块视为为特定相机产品提供 API 的外部库,将“ocr”视为用于 OCR(光学字符识别)的库。 +直接的副作用是由 `cam.shot!()` 引起的,但显然这些信息是从 `f` 泄露的。 因此,`print!` 本质上不可能是一个函数。 -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. +然而,在某些情况下,您可能希望临时检查函数中的值,而不想为此目的在相关函数中添加 `!`。 在这种情况下,可以使用 `log` 函数。 +`log` 打印整个代码执行后的值。 这样,副作用就不会传播。 ```python log "this will be printed after execution" print! "this will be printed immediately" -# 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". +如果没有反馈给程序,或者换句话说,如果没有外部对象可以使用内部信息,那么信息的“泄漏”是可以允许的。 只需要不“传播”信息。

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/08_procedure.md b/doc/zh_CN/syntax/08_procedure.md index 3b4def38..a9a9652e 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). +处理可变对象时需要过程,但将可变对象作为参数并不一定使其成为过程。 +这是一个函数接受一个可变对象(不是过程)。 ```python peek_str s: Str! = log s diff --git a/doc/zh_CN/syntax/09_builtin_procs.md b/doc/zh_CN/syntax/09_builtin_procs.md index dd51f978..f2e878c2 100644 --- a/doc/zh_CN/syntax/09_builtin_procs.md +++ b/doc/zh_CN/syntax/09_builtin_procs.md @@ -1,10 +1,10 @@ -# Built-in procedure +# 内置程序 -## id! +## id! -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 语义中,结构相同的对象之间没有区别,但实际上对象在内存中具有不同的位置。 +`id!` 返回一个代表这个位置的数字。 ```python ``` diff --git a/doc/zh_CN/syntax/10_array.md b/doc/zh_CN/syntax/10_array.md index d55c2135..cecdeb58 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. +数组是最基本的__collection(聚合)__。 +集合是一个可以在其中包含多个对象的对象。 ```python a = [1, 2, 3] -a: [Int; 3] # Type specification: number after semicolon is the number of elements -# Can be omitted if the number of elements is not known +a: [Int; 3] # 类型说明:分号后的数字为元素个数 +# 如果元素个数未知,可以省略 a: [Int] mut_a = [!1, !2, !3] @@ -14,34 +14,34 @@ mut_a[0].inc!() assert mut_a == [2, 2, 3] ``` -As a rule, arrays cannot contain objects of different types. +通常,数组不能包含不同类型的对象。 ```python. -[1, "a"] # TypeError: 1st element is Int, but 2nd element is Str +[1, "a"] # 类型错误:第一个元素是 Int,但第二个元素是 Str ``` -However, you can bypass the restriction by explicitly specifying the type like this. +但是,您可以通过像这样显式指定类型来绕过限制。 ```python [1, "a"]: [Int or Str]. ``` -## Slice +## 切片 -An array can also have multiple values taken out at once. This is called slicing. +一个数组也可以同时取出多个值。 这称为切片。 ```python l = [1, 2, 3, 4] -# Same as l[1:3] in Python +# 与 Python 中的 l[1:3] 相同 assert l[1.. <3] == [2, 3] assert l[1..2] == [2, 3] -# Same as l[1] +# 与 l[1] 相同 assert l[1..1] == [2] -# Same as l[::2] in Python +# 与 Python 中的 l[::2] 相同 assert l[..].step(2) == [2, 4] ``` -The object obtained by slicing is an (immutable) copy to an array. +通过切片获得的对象是数组的(不可变的)副本 ```python print! Typeof l[1..2] # [Int; 4] diff --git a/doc/zh_CN/syntax/11_tuple.md b/doc/zh_CN/syntax/11_tuple.md index f232038e..4548eca3 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. +元组类似于数组,但可以保存不同类型的对象。 +这样的集合称为不等集合。 相比之下,同构集合包括数组、集合等。 ```python t = (1, True, "a") @@ -9,8 +9,8 @@ t = (1, True, "a") assert(i == 1 and b == True and s == "a") ``` -The tuple `t` can retrieve the nth element in the form `t.n`; note that unlike Python, it is not `t[n]`. -This is because accessing tuple elements is more like an attribute (the existence of the element is checked at compile time, and the type can change depending on `n`) than a method (an array's `[]` is a method). +元组`t`可以以`t.n`的形式检索第n个元素; 请注意,与 Python 不同,它不是 `t[n]`。 +这是因为访问元组元素更像是一个属性(在编译时检查元素的存在,并且类型可以根据 `n` 改变)而不是方法(数组的 `[]` 是一种方法)。 ```python assert t.0 == 1 @@ -18,55 +18,55 @@ assert t.1 == True assert t.2 == "a" ``` -Parentheses `()` are optional when not nested. +括号 `()` 在不嵌套时是可选的。 ```python t = 1, True, "a" i, b, s = t ``` -Tuples can hold objects of different types, so they cannot be iterated like arrays. +元组可以保存不同类型的对象,因此它们不能像数组一样被迭代。 ```python t: ({1}, {2}, {3}) = (1, 2, 3) -(1, 2, 3).iter().map(x -> x + 1) # TypeError: type ({1}, {2}, {3}) has no method `.iter()` -# If all types are the same, they can be represented by `(T; n)` like arrays, but this still does not allow iteration +(1, 2, 3).iter().map(x -> x + 1) # 类型错误:类型 ({1}, {2}, {3}) 没有方法 `.iter()` +# 如果所有类型都相同,则可以像数组一样用`(T; n)`表示,但这仍然不允许迭代 t: (Int; 3) = (1, 2, 3) assert (Int; 3) == (Int, Int, Int) ``` -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. +但是,非同质集合(如元组)可以通过向上转换、相交等方式转换为同质集合(如数组)。 +这称为均衡。 ```python (Int, Bool, Str) can be [T; 3] where T :> Int, T :> Bool, T :> Str ``` ```python -t: (Int, Bool, Str) = (1, True, "a") # non-homogenous -a: [Int or Bool or Str; 3] = [1, True, "a"] # homogenous -_a: [Show; 3] = [1, True, "a"] # homogenous +t: (Int, Bool, Str) = (1, True, "a") # 非同质 +a: [Int or Bool or Str; 3] = [1, True, "a"] # 同质的 +_a: [Show; 3] = [1, True, "a"] # 同质的 _a.iter().map(x -> log x) # OK t.try_into([Show; 3])? .iter().map(x -> log x) # OK ``` -## Unit +## 单元 -A tuple with zero elements is called a __unit__. A unit is a value, but also refers to its own type. +零元素的元组称为 __unit__。 一个单元是一个值,但也指它自己的类型。 ```python unit = () (): () ``` -Unit is a superclass of all element 0 tuples. +Unit 是所有元素 0 元组的父类。 ```python () > (Int; 0) () > (Str; 0) ``` -The use of this object is for procedures with no arguments and no return value, etc. Erg subroutines must have arguments and a return value. However, in some cases, such as a procedure, there may be no meaningful arguments or return value, only side effects. In such cases, we use units as "meaningless, formal values. +该对象的用途是用于没有参数和没有返回值的过程等。Erg 子例程必须有参数和返回值。 但是,在某些情况下,例如过程,可能没有有意义的参数或返回值,只有副作用。 在这种情况下,我们将单位用作“无意义的正式值” ```python # ↓ Actually, this parenthesis is a unit @@ -76,31 +76,30 @@ p!() =. p!: () => () ``` -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. +但是,在这种情况下,Python 倾向于使用“无”而不是单位。 +在 Erg 中,当您从一开始就确定操作不会返回有意义的值(例如在过程中)时,您应该使用 `()`,并且当操作可能失败并且您可能会返回 `None` 将一无所获,例如在检索元素时。 -## 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 的所有 `Callable` 对象都是一个参数和一个返回值; 一个接受 N 个参数的子例程只是接收“一个具有 N 个元素的元组”作为参数。 ```python -# f x = ... is implicitly assumed to be f(x) = ... is considered to be +# 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 -# ArgumentError: f takes 1 positional argument but 3 were given +f(1, 2, 3) # 参数错误:f 接受 1 个位置参数,但给出了 3 个 g x: Int, . . y: Int = y assert (2, 3) == g 1, 2, 3 ``` -This also explains the function type. +这也解释了函数类型。 ```python assert f in T: {(T,) -> T | T} assert g in {(Int, ... (Int; N)) -> (Int; N) | N: Nat} ``` -To be precise, the function's input is not a tuple but a "Named tuple with default attributes". This is a special tuple that can only be used in function arguments, can be named like a record, and can have a default value. +准确地说,函数的输入不是元组,而是“具有默认属性的命名元组”。 这是一个特殊的元组,只能在函数参数中使用,可以像记录一样命名,并且可以有默认值。 ```python 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 9f0b6929..747b27e6 100644 --- a/doc/zh_CN/syntax/12_dict.md +++ b/doc/zh_CN/syntax/12_dict.md @@ -1,37 +1,37 @@ -# Dict +# 字典 -Dict is a collection of key/value pairs. +Dict 是键/值对的集合。 ```python ids = {"Alice": 145, "Bob": 214, "Charlie": 301} assert ids["Alice"] == 145 ``` -The key does not have to be a string if it is a `Hash` object. +如果键是“哈希”对象,则键不必是字符串。 ```python -# deprecated to use a range object as a key (confused with slice) +# 不推荐使用范围对象作为键(与切片混淆) r = {1..3: "1~3", 4..6: "4~6", 7..9: "7~9"} assert r[1..3] == "1~3" l = {[]: "empty", [1]: "1"} assert l[[]] == "empty" ``` -Order does not matter for Dict. It also cannot have duplicate elements. In this respect, Dict is similar to Set. -You could say that a Dict is a Set with values. +对于字典来说,顺序无关紧要。 它也不能有重复的元素。 在这方面,Dict 与 Set 类似。 +您可以说 Dict 是具有值的 Set。 ```python {"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214} ``` -When generating a dict from a dict literal, it is checked for duplicate keys. -Any duplicates will result in a compile error. +从 dict 文字生成 dict 时,会检查重复键。 +任何重复都会导致编译错误。 ```python -{"Alice": 145, "Alice": 1} # KeyError: Duplicate key "Alice" +{"Alice": 145, "Alice": 1} # Key错误:重复键`Alice` ``` -Empty Dict is created with `{:}`. Note that `{}` denotes an empty set. +空字典是用 `{:}` 创建的。 请注意,`{}` 表示一个空集。 ```python mut_dict = !{:} @@ -40,9 +40,9 @@ mut_dict.insert! "Bob", 214 assert mut_dict["Alice"] == 145 ``` -## Heterogeneous Dict +## 异构字典 -There need not be a single key/value type. Such a dictionary is called a __heterogenous dict_. +不需要有单一的键/值类型。 这样的字典称为 __heterogenous dict_。 ```python d: {Str: Int, Int: Str} = {"a": 1, 1: "a"} @@ -50,14 +50,14 @@ assert d["a"] == 1 assert d[1] == "a" ``` -However, it is not possible to assign values of the same type to keys of different types, or values of different types to keys of the same type. -In such cases, use the type Or instead. +但是,不能将相同类型的值分配给不同类型的键,或者将不同类型的值分配给相同类型的键。 +在这种情况下,请改用 Or 类型。 ```python invalid1 = {1: "a", "a": "b"} invalid2 = {1: "a", 2: 2} -# Erg type inference does not infer Or type, so type specification is required +# Erg 类型推断不推断 Or 类型,因此需要类型说明 valid1: {Int or Str: Str} = {1: "a", "a": "b"} valid2: {Int: Int or Str} = {1: "a", 2: 2} ``` diff --git a/doc/zh_CN/syntax/13_record.md b/doc/zh_CN/syntax/13_record.md index d5b2570f..e855b998 100644 --- a/doc/zh_CN/syntax/13_record.md +++ b/doc/zh_CN/syntax/13_record.md @@ -1,7 +1,7 @@ -# Record +# 记录(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. +记录是一个集合,它结合了通过键访问的 Dict 和在编译时检查其访问的元组的属性。 +如果您了解 JavaScript,请将其视为一种(更增强的)对象字面量表示法。 ```python john = {.name = "John"; .age = 21} @@ -9,27 +9,27 @@ 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 +john["name"] # 错误:john 不可订阅 ``` -The `.name` and `.age` parts are called attributes, and the `"John"` and `21` parts are called attribute values. +`.name` 和 `.age` 部分称为属性,而 `"John"` 和 `21` 部分称为属性值。 -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. +与 JavaScript 对象字面量的区别在于它们不能作为字符串访问。 也就是说,属性不仅仅是字符串。 +这是因为对值的访问是在编译时确定的,而且字典和记录是不同的东西。 换句话说,`{"name": "John"}` 是一个字典,`{name = "John"}` 是一个记录。 +那么我们应该如何使用字典和记录呢? +一般来说,我们建议使用记录。 记录具有在编译时检查元素是否存在以及能够指定 __visibility_ 的优点。 +指定可见性等同于在 Java 和其他语言中指定公共/私有。 有关详细信息,请参阅 [可见性](./15_visibility.md) 了解详细信息。 ```python a = {x = 1; .y = x + 1} -a.x # AttributeError: x is private -# Hint: declare as `.x`. +a.x # 属性错误:x 是私有的 +# 提示:声明为 `.x`。 assert a.y == 2 ``` -The above example may seem strange to someone familiar with JavaScript, but simply declaring `x` makes it inaccessible from the outside. `. `. `. +对于熟悉 JavaScript 的人来说,上面的示例可能看起来很奇怪,但简单地声明 `x` 会使其无法从外部访问 -You can also explicitly specify the type of an attribute. +您还可以显式指定属性的类型 ```python anonymous = { @@ -39,7 +39,7 @@ anonymous = { anonymous.name.set! "John" ``` -A record can also have the method. +一个记录也可以有方法。 ```python o = { @@ -52,27 +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. +关于记录有一个值得注意的语法。 当记录的所有属性值都是类(不是结构类型)时,记录本身表现为一个类型,其自身的属性作为必需属性。 +这种类型称为记录类型。 有关详细信息,请参阅 [记录] 部分。 ```python -# record +# 记录 john = {.name = "John"} -# record type +# 记录 type john: {.name = Str} Named = {.name = Str} john: Named greet! n: Named = print! "Hello, I am {n.name}" -john # "Hello, I am John" print! +john # “你好,我是约翰 print! Named.name # Str ``` -## Deconstructing a record +## 解构记录 -Records can be deconstructed as follows. +记录可以按如下方式解构。 ```python 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. +当存在与属性同名的变量时,`x = ...`也可以缩写为`x`,例如`x = x`或`x = .x`到`x`,和` .x = .x` 或 `.x = x` 到 `.x`。 +但是,当只有一个属性时,必须在其后加上`;`以与集合区分开来。 ```python x = 1 @@ -106,22 +106,22 @@ tuple = {x} assert tuple.1 == 1 ``` -This syntax can be used to deconstructed a record and assign it to a variable. +此语法可用于解构记录并将其分配给变量 ```python -# same as `{x = x; y = y} = xy` +# 一样 `{x = x; y = y} = xy` {x; y} = xy assert x == 1 assert y == 2 -# same as `{.a = a; .b = b} = ab` +# 一样 `{.a = a; .b = b} = ab` {a; b} = ab assert a == 1 assert b == 2 ``` -## Empty Record +## 空记录 -An empty record is represented by `{=}`. An empty record is also its own class, like Unit. +空记录由`{=}`表示。 空记录也是它自己的类,如 Unit ```python empty_record = {=} @@ -132,10 +132,10 @@ empty_record: Structural {=} {x = 3; y = 5}: Structural {=} ``` -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 方法. +空记录不同于空 Dict `{:}` 或空集 `{}`。 特别要注意的是,它与 `{}` 的含义相反(在 Python 中,`{}` 是一个空字典,而在 Erg 中它是 Erg 中的 `!{:}`)。 +作为枚举类型,`{}` 是一个空类型,其元素中不包含任何内容。 `Never` 类型是这种类型的一个分类。 +相反,记录类 `{=}` 没有必需的实例属性,因此所有对象都是它的元素。 `Object` 是 this 的别名。 +一个`Object`(`Object`的一个补丁)是`的一个元素。 __sizeof__` 和其他非常基本的提供方法。 ```python AnyPatch = Patch Structural {=} @@ -145,13 +145,13 @@ AnyPatch = Patch Structural {=} 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`. +请注意,没有其他类型或类在结构上与 `{}`、`Never` 类型等效,如果用户在右侧使用 `{}`、`Class {}` 定义类型,则会出错。 +这意味着,例如,`1..10 或 -10。 -1`,但 `1..10 和 -10... -1`。 例如,当它应该是 1..10 或 -10...-1 时是 `-1`。 +此外,如果您定义的类型(例如 `Int 和 Str`)会导致组合 `Object`,则会警告您只需将其设置为 `Object`。 -## Instant Block +## 即时封锁 -Erg has another syntax, instant block, which simply returns the last value evaluated. Attributes cannot be retained. +Erg 有另一种语法 Instant 块,它只返回最后评估的值。 不能保留属性。 ```python x = @@ -161,13 +161,13 @@ x = assert x == 8 y = - .x = 1 # SyntaxError: cannot define an attribute in an entity block + .x = 1 # 语法错误:无法在实体块中定义属性 ``` -## 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. +如果您尝试自己实现方法,则必须直接在实例中定义裸记录(由记录文字生成的记录)。 +这是低效的,并且随着属性数量的增加,错误消息等变得难以查看和使用。 ```python john = { @@ -177,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! () => None}, Int +# 类型错误:{name = Str; 没有实现 + 年龄=诠释; 。迎接! =参考(自我)。 () => 无; inc_age! =参考! () => 无}, 整数 ``` -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). +因此,在这种情况下,您可以继承一个记录类。 这样的类称为数据类。 +这在 [class](./type/04_class.md) 中有描述。 ```python Person = Inherit {name = Str; age = Nat} @@ -191,7 +191,7 @@ Person. john = Person.new {name = "John Smith"; age = 20} john + 1 -# TypeError: + is not implemented for Person, Int +# 类型错误:Person、Int 没有实现 + ```

diff --git a/doc/zh_CN/syntax/14_set.md b/doc/zh_CN/syntax/14_set.md index ffbea36f..e209411d 100644 --- a/doc/zh_CN/syntax/14_set.md +++ b/doc/zh_CN/syntax/14_set.md @@ -1,14 +1,14 @@ # Set -A set represents a collection, which is structurally a duplicate, unordered array. +一个Set代表一个集合,它在结构上是一个重复的无序数组。 ```python assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3} -assert {1, 2} == {1, 1, 2} # duplicates are automatically removed +assert {1, 2} == {1, 1, 2} # 重复的被自动删除 assert {1, 2} == {2, 1} ``` -Sets can perform set operations. +Set可以执行集合操作。 ```python assert 1 in {1, 2, 3} @@ -18,23 +18,22 @@ 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. +Set是同质集合。 为了使不同类的对象共存,它们必须同质化 ```python s: {Int or Str} = {"a", 1, "b", -1} ``` -## Sets as types - -Sets can also be treated as types. Such types are called __Enum types__. +## Sets为类型 +Sets也可以被视为类型。 这种类型称为 _枚举类型_。 ```python 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. +Set的元素直接是类型的元素。 +请注意,这些Set本身是不同的。 ```python mut_set = {1, 2, 3}.into {Int; !3} diff --git a/doc/zh_CN/syntax/15_type.md b/doc/zh_CN/syntax/15_type.md index 76f0cee9..37dd77c6 100644 --- a/doc/zh_CN/syntax/15_type.md +++ b/doc/zh_CN/syntax/15_type.md @@ -1,6 +1,6 @@ -# types +# 类型 -Types are a very important feature in Erg, so we have a [dedicated section](./type/01_type_system.md). Please see there. +类型是 Erg 中一个非常重要的特性,所以我们有一个 [dedicated section](./type/01_type_system.md)。 请看那里。

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/16_iterator.md b/doc/zh_CN/syntax/16_iterator.md index 89ab4879..57121153 100644 --- a/doc/zh_CN/syntax/16_iterator.md +++ b/doc/zh_CN/syntax/16_iterator.md @@ -1,24 +1,24 @@ -# Iterator +# 迭代器 -An iterator is an object used to retrieve elements of a container. +迭代器是用于检索容器元素的对象。 ```python for! 0..9, i => print! i ``` -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__. +此代码打印数字 0 到 9。 +每个数字(=Int 对象)都分配给`i`,并执行以下操作(=`print!i`)。 这种重复执行称为__iteration__。 -Now let's look at the type signature of the `for!` procedure. +现在让我们看看 `for!` 过程的类型签名。 ```python for!: |T: Type, I <: Iterable T| (I, T => None) => None ``` -The first argument seems to accept an object of type `Iterable`. +第一个参数似乎接受“Iterable”类型的对象。 -`Iterable` is a type with `.Iterator` attribute, `.iter` method in the request method. +`Iterable` 是一个具有`.Iterator` 属性的类型,`.iter` 方法在request 方法中。 ```python Iterable T = Trait { @@ -27,7 +27,7 @@ Iterable T = Trait { } ``` -The type `{Iterator}` of the `.Iterator` attribute is so-called set-kind (kind is described [here](./type/advanced/kind.md)). +`.Iterator` 属性的类型 `{Iterator}` 是所谓的 set-kind(kind 在 [here](./type/advanced/kind.md) 中描述) ```python assert [1, 2, 3] in Iterable(Int) @@ -35,13 +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() # <数组迭代器对象> +log (1..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 方法 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. +`ArrayIterator` 和 `RangeIterator` 都是实现 `Iterator` 的类,它们的存在只是为了提供 `Array` 和 `Range` 迭代函数。 +这种设计模式称为伴生类 [1](#1)。 +而“IteratorImpl”补丁是迭代功能的核心。 `Iterator` 只需要一个`.next` 方法,`IteratorImpl` 确实提供了几十种方法。 `ArrayIterator`和`RangeIterator`只需实现`.next`方法就可以使用`IteratorImpl`的实现方法。 为了方便起见,标准库实现了许多迭代器。 ```mermaid classDiagram @@ -78,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. +诸如 `Iterable` 之类的以静态分派但统一的方式提供用于处理特征(在本例中为 `Iterator`)的接口的类型称为伴生类适配器。 --- -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) +1 这个模式似乎没有统一的名称,但是在 Rust 中,有 [companion struct 模式]( https://gist.github.com/qnighy/be99c2ece6f3f4b1248608a04e104b38#:~:text=%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82 %8B%E3%80%82-,companion%20struct,-%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A8%E3%80% 81%E3 %81%9D%E3%81%AE),并以此命名。 [↩](#f1)

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/17_mutability.md b/doc/zh_CN/syntax/17_mutability.md index f61711b9..7dff9f30 100644 --- a/doc/zh_CN/syntax/17_mutability.md +++ b/doc/zh_CN/syntax/17_mutability.md @@ -1,7 +1,7 @@ -# Mutability +# 可变性 -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 变量都是不可变的。 但是,Erg 对象具有可变性的概念。 +以下面的代码为例。 ```python a = [1, 2, 3] @@ -9,9 +9,9 @@ a = a + [4, 5, 6] print! a # [1, 2, 3, 4, 5, 6] ``` -The above code cannot actually be executed by Erg. This is because it is not reassignable. +上面的代码实际上不能被 Erg 执行。 这是因为它不可重新分配。 -This code can be executed. +可以执行此代码。 ```python b = ![1, 2, 3] @@ -19,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. +`a, b` 的最终结果看起来一样,但它们的含义却大不相同。 +虽然 `a` 是表示 `Nat` 数组的变量,但第一行和第二行指向的对象是不同的。 名称`a`相同,但内容不同。 ```python a = [1, 2, 3] @@ -29,9 +29,9 @@ _a = a + [4, 5, 6] print! id! _a # 0x000002A798DFE980 ``` -The `id!` procedure returns the address in memory where the object resides. +`id!` 过程返回对象驻留的内存地址。 -`b` is a `Nat` "dynamic" array. The content of the object changes, but the variables point to the same thing. +`b` 是一个 `Nat` “动态” 数组。 对象的内容发生了变化,但变量指向的是同一个东西 ```python b = ![1, 2, 3] @@ -48,13 +48,13 @@ if! True. do! 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. +`!` 是一个特殊的运算符,称为 __mutation 运算符__。 它使不可变对象可变。 +标有“!”的对象的行为可以自定义。 ```python Point = Class {.x = Int; .y = Int} -# In this case .x is made mutable and .y remains immutable +# 在这种情况下 .x 是可变的,而 .y 保持不变 Point! = Class {.x = Int!; .y = Int} Point!. inc_x! ref!(self) = self.x.update! x -> x + 1 @@ -64,10 +64,10 @@ 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. +与变量不同,常量在所有范围内都指向同一事物。 +常量使用 `=` 运算符声明。 ```python PI = 3.141592653589 @@ -75,28 +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. +常量在全局以下的所有范围内都是相同的,并且不能被覆盖。因此,它们不能被 ``=`` 重新定义。此限制允许它用于模式匹配。 +`True` 和 `False` 可以用于模式匹配的原因是因为它们是常量。 +此外,常量总是指向不可变对象。诸如 `Str!` 之类的类型不能是常量。 +所有内置类型都是常量,因为它们应该在编译时确定。可以生成非常量的类型,但不能用于指定类型,只能像简单记录一样使用。相反,类型是其内容在编译时确定的记录。 -## Variable, Name, Identifier, Symbol +## 变量、名称、标识符、符号 -Let's clear up a few terms related to variables in Erg. +让我们理清一些与 Erg 中的变量相关的术语。 -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. +变量是一种为对象赋予名称以便可以重用(或指向该名称)的机制。 +标识符是指定变量的语法元素。 +符号是表示名称的语法元素、记号。 -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. +只有非符号字符是符号,符号不称为符号,尽管它们可以作为运算符的标识符。 +例如,`x` 是一个标识符和一个符号。 `x.y` 也是一个标识符,但它不是一个符号。 `x` 和 `y` 是符号。 +即使 `x` 没有绑定到任何对象,`x` 仍然是一个符号和一个标识符,但它不会被称为变量。 +`x.y` 形式的标识符称为字段访问器。 +`x[y]` 形式的标识符称为下标访问器。 -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. +变量和标识符之间的区别在于,如果我们在 Erg 的语法理论意义上谈论变量,则两者实际上是相同的。 +在 C 中,类型和函数不能分配给变量; int 和 main 是标识符,而不是变量(严格来说可以赋值,但有限制)。 +然而,在尔格语中,“一切都是对象”。不仅函数和类型,甚至运算符都可以分配给变量。

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/18_ownership.md b/doc/zh_CN/syntax/18_ownership.md index 492fa6bd..6f432ae4 100644 --- a/doc/zh_CN/syntax/18_ownership.md +++ b/doc/zh_CN/syntax/18_ownership.md @@ -1,13 +1,13 @@ -# Ownership system +#所有权制度 -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. +由于 Erg 是一种使用 Python 作为宿主语言的语言,因此内存管理的方法取决于 Python 的实现。 +但语义上 Erg 的内存管理与 Python 的不同。 一个显着的区别在于所有权制度和禁止循环引用。 -## Ownership +## 所有权 -Erg has an ownership system inspired by Rust. -Rust's ownership system is generally considered esoteric, but Erg's is simplified to be intuitive. -In Erg, __mutable objects__ are owned and cannot be referenced after ownership is lost. +Erg 有一个受 Rust 启发的所有权系统。 +Rust 的所有权系统通常被认为是深奥的,但 Erg 的所有权系统被简化为直观。 +在 Erg 中,__mutable objects__ 是拥有的,并且在所有权丢失后无法引用。 ```python v = [1, 2, 3].into [Int; !3] @@ -16,23 +16,23 @@ push! vec, x = vec.push!(x) vec -# The contents of v ([1, 2, 3]) are owned by w +# v ([1, 2, 3])的内容归w所有 w = push! v, 4 -print! v # error: v was moved +print! v # 错误:v 被移动了 print!w # [1, 2, 3, 4] ``` -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. +复制一个对象并转移其所有权。 它通过将 `.clone` 方法应用于实际参数来做到这一点。 +复制的对象与原始对象完全相同,但相互独立,不受更改影响。 -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. +复制相当于 Python 的深拷贝,由于它完全重新创建相同的对象,因此计算和内存成本通常高于冻结和借用。 +需要复制对象的子例程被称为“参数消耗”子例程。 ```python capitalize s: Str!= @@ -44,30 +44,30 @@ s2 = capitalize s1.clone() log s2, s1 # !"HELLO hello" ``` -## freeze +## 冻结 -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). +我们利用了不可变对象可以从多个位置引用的事实,并将可变对象转换为不可变对象。 +这称为冻结。 例如,在从可变数组创建迭代器时会使用冻结。 +由于您不能直接从可变数组创建迭代器,请将其转换为不可变数组。 +如果您不想破坏数组,请使用 [`.freeze_map` 方法](./type/mut.md)。 ```python -# Compute the sum of the values ​​produced by the iterator +# 计算迭代器产生的值的总和 sum|T <: Add + HasUnit| i: Iterator T = ... x = [1, 2, 3].into [Int; !3] x.push!(4) -i = x.iter() # TypeError: [Int; !4] has no method `iter` +i = x.iter() # 类型错误:[Int; !4] 没有方法 `iter` y = x.freeze() i = y.iter() assert sum(i) == 10 -y # y can still be touched +y # y 仍然可以被触摸 ``` -## borrow +## 借 -Borrowing is cheaper than duplicating or freezing. -Borrowing can be done in the following simple cases: +借用比复制或冻结便宜。 +可以在以下简单情况下进行借款: ```python peek_str ref(s: Str!) = @@ -77,33 +77,33 @@ 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. +借来的值称为原始对象的 __reference__。 +您可以“转租”对另一个子例程的引用,但您不能使用它,因为您只是借用它。 ```python steal_str ref(s: Str!) = - # Since the log function only borrows the arguments, it can be sub-leased + # 由于日志函数只借用参数,所以可以转租 log s - # error because the discard function consumes arguments - discard s # OwnershipError: cannot consume a borrowed value - # hint: use `clone` method + # 错误,因为丢弃函数消耗了参数 + discard s # OwnershipError: 不能消费借来的值 + # 提示:使用 `clone` 方法 ``` ```python steal_str ref(s: Str!) = - # This is no good either (= consumes the right side) - x = s # OwnershipError: cannot consume a borrowed value + # 这也不好(=消耗右边) + x = s # OwnershipError: 不能消费借来的值 x ``` -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. +Erg 的引用比 Rust 的更严格。 引用是语言中的一等对象,但不能显式创建,它们只能指定为通过 `ref`/`ref!` 传递的参数。 +这意味着您不能将引用填充到数组中或创建将引用作为属性的类。 -However, such restrictions are a natural specification in languages ​​without references in the first place, and they are not so inconvenient. +但是,这样的限制是语言中的自然规范,一开始就没有引用,而且它们并没有那么不方便。 -## circular references +## 循环引用 -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. +Erg 旨在防止无意的内存泄漏,如果内存检查器检测到循环引用,则会发出错误。 在大多数情况下,这个错误可以通过弱引用 `Weak` 来解决。 但是,由于无法生成循环图等具有循环结构的对象,因此我们计划实现一个 API,可以将循环引用作为不安全操作生成。

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/19_visibility.md b/doc/zh_CN/syntax/19_visibility.md index d03d4caf..d0af6a68 100644 --- a/doc/zh_CN/syntax/19_visibility.md +++ b/doc/zh_CN/syntax/19_visibility.md @@ -1,8 +1,8 @@ -# Visibility +# 可见性 -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 变量具有 __visibility__ 的概念。 +到目前为止,我们看到的所有变量都称为 __private variables__。 这是一个外部不可见的变量。 +例如,`foo` 模块中定义的私有变量不能被另一个模块引用。 ```python # foo.er @@ -12,11 +12,11 @@ x = "this is an invisible variable" ```python #bar.er foo = import "foo" -foo.x # AttributeError: Module 'foo' has no attribute 'x' ('x' is private) +foo.x # AttributeError: 模块 'foo' 没有属性 'x' ('x' 是私有的) ``` -On the other hand, there are also __public variables__, which can be referenced from the outside. -Public variables are defined with `.`. +另一方面,也有__public variables__,可以从外部引用。 +公共变量用`.`定义。 ```python # foo.er @@ -29,7 +29,7 @@ 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. +您不需要向私有变量添加任何内容,但您也可以添加 `::` 或 `self::`(用于类型等的`Self::`)以表明它们是私有的。 增加。 如果它是一个模块,它也可以是 `module::` ```python ::x = "this is an invisible variable" @@ -43,12 +43,12 @@ In the context of purely sequential execution, private variables are almost syno ```python ::x = "this is a private variable" y = - x + 1 # exactly module::x + x + 1 # 完全是 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. +通过使用`::`,可以区分作用域内同名的变量。 +在左侧指定要引用的变量的范围。 为顶层指定 `module`。 +如果未指定,则照常引用最里面的变量。 ```python ::x = 0 @@ -64,7 +64,7 @@ y = assert module::x == 0 ``` -In the anonymous subroutine scope, `self` specifies its own scope. +在匿名子程序作用域中,`self` 指定了它自己的作用域 ```python x = 0 @@ -73,21 +73,21 @@ f = x -> f1# 0 1 ``` -`::` is also responsible for accessing private instance attributes. +`::` 还负责访问私有实例属性。 ```python x = 0 C = Class {x = Int} C. - # Top-level x is referenced (warning to use module::x) + # 顶级 x 被引用(警告使用 module::x) f1 self = x - # instance attribute x is referenced + # 实例属性 x 被引用 f2 self = self::x ``` -## Visibility in external modules +## 外部模块中的可见性 -A class defined in one module can actually define 方法 from an external module. +在一个模块中定义的类实际上可以定义来自外部模块的方法。 ```python # foo.er @@ -106,35 +106,35 @@ Foo. .f() = foo = Foo.new() foo.public() - foo::private() # AttributeError + foo::private() # 属性错误 ``` -However, both of those 方法 are only available within that module. -Private 方法 defined externally are visible to 方法 of the `Foo` class only within the defining module. -Public 方法 are exposed outside the class, but not outside the module. +但是,这两种方法都只在该模块中可用。 +外部定义的私有方法对 Foo 类的方法仅在定义模块内可见。 +公共方法暴露在类之外,但不在模块之外。 ```python # baz.er {Foo; ...} = import "foo" foo = Foo.new() -foo.public() # AttributeError: 'Foo' has no attribute 'public' ('public' is defined in module 'bar') +foo.public() # 属性错误:“Foo”没有属性“public”(“public”在模块“bar”中定义) ``` -Also, 方法 cannot be defined in the type to be re-exported. -This is to avoid confusion about 方法 being found or not found depending on the module they are imported from. +此外,方法不能在要重新导出的类型中定义。 +这是为了避免混淆方法是否找到,具体取决于导入方法的模块。 ```python #bar.er {.Foo; ...} = import "foo" .Foo:: - private self = pass # Error + private self = pass # 错误 Foo. - public self = self::private() # Error + public self = self::private() # 错误 ``` -If you want to do something like this, define a [patch](./type/07_patch.md). +如果你想做这样的事情,定义一个 [patch](./type/07_patch.md)。 ```python #bar.er @@ -156,10 +156,10 @@ foo = Foo.new() foo.public() ``` -## restricted public variables +## 受限公共变量 -Variable visibility is not limited to complete public/private. -You can also publish with restrictions. +可变可见性不限于完全公共/私有。 +您也可以有限制地发布。 ```python # foo.er @@ -174,15 +174,15 @@ You can also publish with restrictions. _ = .a.z # OK } -_ = .record.a.x # VisibilityError +_ = .record.a.x # 可见性错误 _ = .record.a.y # OK _ = .record.a.z # OK ``` ```python foo = import "foo" -_ = foo.record.a.x # VisibilityError -_ = foo.record.a.y # VisibilityError +_ = foo.record.a.x # 可见性错误 +_ = foo.record.a.y # 可见性错误 _ = foo.record.a.z # OK ``` diff --git a/doc/zh_CN/syntax/20_naming_rule.md b/doc/zh_CN/syntax/20_naming_rule.md index 89117377..221c7a4c 100644 --- a/doc/zh_CN/syntax/20_naming_rule.md +++ b/doc/zh_CN/syntax/20_naming_rule.md @@ -1,6 +1,6 @@ -# 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. +如果要将变量用作常量表达式,请确保它以大写字母开头。 两个或多个字母可能是小写的。 ```python i: Option Type = Int @@ -9,36 +9,36 @@ match i: None -> log "None" ``` -Objects with side effects always end with `!`. Procedures and procedural 方法, and mutable types. -However, the `Proc` type itself is not mutable. +具有副作用的对象总是以 `!` 结尾。 程序和程序方法,以及可变类型。 +然而,`Proc` 类型本身是不可变的。 ```python # Callable == Func or Proc c: Callable = print! match c: - p! -> log "proc" # `: Proc` can be omitted since it is self-explanatory + p! -> log "proc" # `: Proc` 可以省略,因为它是不言自明的 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. +如果您想向外界公开一个属性,请在开头使用 `.` 定义它。 如果你不把`.`放在开头,它将是私有的。 为避免混淆,它们不能在同一范围内共存。 ```python -o = {x = 1; .x = 2} # SyntaxError: private and public variables with the same name cannot coexist +o = {x = 1; .x = 2} # 语法错误:同名的私有变量和公共变量不能共存 ``` -## Literal Identifiers +## 文字标识符 -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. +可以通过将字符串括在单引号 ('') 中来规避上述规则。 也就是说,程序对象也可以在没有 `!` 的情况下分配。 但是,在这种情况下,即使该值是常量表达式,也不会被视为常量。 +像这样用单引号括起来的字符串称为文字标识符。 +这在调用Python等其他语言的API(FFI)时使用。 ```python bar! = pyimport("foo").'bar' ``` -Identifiers that are also valid in Erg do not need to be enclosed in ''. +在 Erg 中也有效的标识符不需要用 '' 括起来。 -Furthermore, literal identifiers can contain both symbols and spaces, so strings that cannot normally be used as identifiers can be used as identifiers. +此外,文字标识符可以包含符号和空格,因此通常不能用作标识符的字符串可以用作标识符。 ```python '∂/∂t' y diff --git a/doc/zh_CN/syntax/21_lambda.md b/doc/zh_CN/syntax/21_lambda.md index 94aeb3a4..8cac3bea 100644 --- a/doc/zh_CN/syntax/21_lambda.md +++ b/doc/zh_CN/syntax/21_lambda.md @@ -1,50 +1,50 @@ -# anonymous function +# 匿名函数 -Anonymous functions are a syntax for creating function objects on the fly without naming them. +匿名函数是一种无需命名即可动态创建函数对象的语法。 ```python -# `->` is an anonymous function operator -# same as `f x, y = x + y` +# `->` 是匿名函数操作符 +# 同 `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. +如果只有一个参数,您可以省略 `()`。 ```python assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4] assert ((i, j) -> [i, j])(1, 2) == [1, 2] ``` -In the case below 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. +在下面的情况下,它是 `0..9, (i -> ...)` 而不是 `(0..9, i) -> ...` +`->` 在左侧只接受一个参数。 多个参数作为单个元组接收 ```python for 0..9, i: Int -> ... ``` -In anonymous functions, there is a difference in parsing due to whitespace. +在匿名函数中,由于空格,解析存在差异 ```python -# In this case, interpreted as `T(() -> Int)` +# 在这种情况下,解释为 `T(() -> Int)` i: T() -> Int -# in this case it is interpreted as (U()) -> Int +# 在这种情况下,它被解释为 (U()) -> Int k: U() -> Int ``` -Anonymous functions can be used without arguments. +匿名函数可以不带参数使用。 ```python -# `=>` is an anonymous procedure operator -p! = () => print! "`p!` was called" -# `() ->`, `() =>` have syntax sugar `do`, `do!` -# p! = do! print! "`p!` was called" -p!() # `p!` was called +# `=>` 是一个匿名过程操作符 +p! = () => print! # `p!` 被调用 +# `() ->`, `() =>` 有语法糖 `do`, `do!` +# p! = do! print! "`p!` 被调用 +p!() # `p!` 被调用 ``` -No-argument functions can be used for lazy initialization. +无参数函数可用于延迟初始化 ```python time = import "time" @@ -56,20 +56,21 @@ now = if! True: 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). +您还可以键入和模式匹配。 正因为如此,`match` 函数大多是借助匿名函数的力量来实现的。 +作为 `match` 函数的参数给出的匿名函数从顶部开始按顺序尝试。 因此,您应该在顶部描述特殊情况,在底部描述更一般的情况。 如果你弄错了顺序,编译器会发出警告(如果可能的话) + ```python n = (Complex or Ratio or Int).sample!() i = matchn: - PI -> PI # if equal to constant PI - For (i: 1..10) -> i # Int from 1 to 10 + PI -> PI # 如果等于常数 PI + For (i: 1..10) -> i # 整数从 1 到 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 + (c: Complex) -> c.real() # 对于复杂。 Int < Complex,但可以回退 + _ -> panic "cannot convert to Int" # 如果以上都不适用。 match 必须涵盖所有模式 ``` -Error handling is also generally done using `?` or `match`. +错误处理通常也使用 `?` 或 `match` 完成。 ```python res: ParseResult Int @@ -83,10 +84,10 @@ match res2: err: Error -> panic err.msg ``` -## Anonymous polycorrelation coefficient +## 匿名多相关系数 ```python -# same as id|T| x: T = x +# 与此相同 id|T|x:T = x id = |T| x: T -> x ``` diff --git a/doc/zh_CN/syntax/22_subroutine.md b/doc/zh_CN/syntax/22_subroutine.md index 2371fd32..78728e20 100644 --- a/doc/zh_CN/syntax/22_subroutine.md +++ b/doc/zh_CN/syntax/22_subroutine.md @@ -1,55 +1,55 @@ -# Subroutine Signatures +# 子程序签名 -## Func +## 函数 ```python some_func(x: T, y: U) -> V some_func: (T, U) -> V ``` -## Proc +## 过程 ```python some_proc!(x: T, y: U) => V some_proc!: (T, U) => V ``` -## Func Method +## 函数方法 -The method type cannot be specified externally with ``Self``. +方法类型不能用`Self`在外部指定 ```python .some_method(self, x: T, y: U) => () -# Self.(T, U) => () takes ownership of self +# Self.(T, U) => () 拥有 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. +在下文中,假设类型 `T!` 采用类型参数 `N: Nat`。 要在外部指定它,请使用类型变量 ```python T!: Nat -> Type -# ~> indicates the state of the type argument before and after application (in this case, self must be a variable reference) +# ~> 表示应用前后类型参数的状态(此时self必须是变量引用) 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 方法 that do not have `ref!`, i.e., are deprived of ownership after application, the type argument transition (`~>`) cannot be used. +注意,`.some_method` 的类型是 `Ref!(T(N ~> N+X))。 ({X}) => () | N,X:Nat`。 +对于没有 `ref!` 的方法,即在应用后被剥夺所有权,不能使用类型参数转换(`~>`)。 -If ownership is taken, it is as follows. +如果取得所有权,则如下所示。 ```python -# If you don't use N, you can omit it with _. +# 如果不使用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 +## 运算符 -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 ``. +中性字母运算符,例如 `and` 和 `or` 可以通过用 ` 括起来定义为中性运算符。 ```python 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 151fa2cb..eb3122ac 100644 --- a/doc/zh_CN/syntax/23_closure.md +++ b/doc/zh_CN/syntax/23_closure.md @@ -1,6 +1,6 @@ -# Closure +# 关闭 -Erg subroutines have a feature called a "closure" that captures external variables. +Erg 子例程有一个称为“闭包”的功能,可以捕获外部变量。 ```python outer = 1 @@ -8,7 +8,7 @@ f x = outer + x assert f(1) == 2 ``` -As with immutable objects, mutable objects can also be captured. +与不可变对象一样,可变对象也可以被捕获。 ```python sum = !0 @@ -22,11 +22,11 @@ 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. +但是请注意,函数不能捕获可变对象。 +如果可以在函数中引用可变对象,则可以编写如下代码。 ```python -# !!! This code actually gives an error !!! +# !!! 这段代码实际上给出了一个错误!!! i = !0 f x = i + x assert f 1 == 1 @@ -34,10 +34,10 @@ 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. +该函数应该为相同的参数返回相同的值,但假设被打破了。 +请注意,`i` 仅在调用时进行评估。 -Call `.clone` if you want the contents of the mutable object at the time the function was defined. +如果您想在定义函数时获取可变对象的内容,请调用`.clone` ```python i = !0 @@ -58,7 +58,7 @@ for! 1..10, i => assert sum == 45 ``` -The equivalent program above can be written in Python as follows: +上面的等效程序可以用 Python 编写如下: ```python # Python @@ -68,28 +68,28 @@ for i in range(1, 10): assert sum == 45 ``` -However, Erg recommends a simpler notation. -Instead of carrying around state using subroutines and mutable objects, use a style of localizing state using functions. This is called functional programming. +但是,Erg 建议使用更简单的表示法。 +与其使用子例程和可变对象来传递状态,不如使用一种使用函数来定位状态的风格。这称为函数式编程 ```python -# Functional style +# 功能风格 sum = (1..10).sum() assert sum == 45 ``` -The 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`. +`fold` 函数可以用来做比 sum 更多的事情。 +`fold` 是一个迭代器方法,它为每次迭代执行参数 `f`。 +累加结果的计数器的初始值在 `init` 中指定,并在 `acc` 中累加。 ```python -# start with 0, result will +# 从0开始,结果会 sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i) assert sum == 45 ``` -Erg is designed to be a natural succinct description of programming with immutable objects. +Erg 被设计为对使用不可变对象进行编程的自然简洁描述。

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/24_module.md b/doc/zh_CN/syntax/24_module.md index 63c58bf3..eee8832e 100644 --- a/doc/zh_CN/syntax/24_module.md +++ b/doc/zh_CN/syntax/24_module.md @@ -8,7 +8,7 @@ Erg allows you to think of the file itself as a single record. This is called a ``` ```python -# 定义ining the foo module is almost the same as defining this record +# 定义 foo 模块与定义这条记录几乎相同 foo = {.i = 1} ``` @@ -19,13 +19,13 @@ print! foo # assert foo.i == 1 ``` -Since module types are also record types, deconstruction assignment is possible. +由于模块类型也是记录类型,因此可以进行解构赋值 ```python {sin; cos; ...} = import "math" ``` -## module visibility +## 模块可见性 ```console └─┬ ./src diff --git a/doc/zh_CN/syntax/25_object_system.md b/doc/zh_CN/syntax/25_object_system.md index bed6a89d..ffb97156 100644 --- a/doc/zh_CN/syntax/25_object_system.md +++ b/doc/zh_CN/syntax/25_object_system.md @@ -1,19 +1,19 @@ -# Object +# 目的 -All data that can be assigned to a variable. The attributes of the `Object` class are as follows. +可以分配给变量的所有数据。 `Object` 类的属性如下。 -* `.__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) +* `.__repr__`:返回对象的(非丰富)字符串表示 +* `.__sizeof__`:返回对象的大小(包括堆分配) +* `.__dir__`: 返回对象属性列表 +* `.__hash__`:返回对象的哈希值 +* `.__getattribute__`: 获取并返回对象的属性 +* `.clone`:创建并返回一个对象的克隆(在内存中有一个独立的实体) +* `.copy`:返回对象的副本(指向内存中的同一事物) -## Record +## 记录 -An object generated by a record literal (`{attr = value; ...}`). -This object has basic 方法 such as `.clone` and `.__sizeof__`. +由记录文字(`{attr = value; ...}`)生成的对象。 +这个对象有基本的方法,比如`.clone`和`.__sizeof__`。 ```python obj = {.x = 1} @@ -23,59 +23,59 @@ obj2 = {...x; .y = 2} assert obj2.x == 1 and obj2.y == 2 ``` -## Attribute +## 属性 -An object associated with an object. In particular, a subroutine attribute that takes self (`self`) as its implicit first argument is called a method. +与对象关联的对象。 特别是,将 self (`self`) 作为其隐式第一个参数的子例程属性称为方法。 ```python -# note that there is no `.` in private_attr +# 请注意,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 +record.private_attr # AttributeError: private_attr 是私有的 assert record.method() == 3 ``` -## Element +## 元素 -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. +属于特定类型的对象(例如,“1”是“Int”类型的元素)。所有对象至少是`{=}`类型的元素。 +类的元素有时称为实例。 -## Subroutine +## 子程序 -Indicates an object that is an instance of a function or procedure (including 方法). The class representing a subroutine is `Subroutine`. -An object that implements `.__call__` is more commonly called a `Callable`. +表示作为函数或过程(包括方法)实例的对象。代表子程序的类是“子程序”。 +实现 `.__call__` 的对象通常称为 `Callable`。 -## Callable +## 可调用 -An object that implements `.__call__`. It is also the superclass of `Subroutine`. +一个实现`.__call__`的对象。它也是 `Subroutine` 的超类。 -## Type +## 类型 -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; !_]`) . +定义需求属性并使对象通用化的对象。 +主要有两种类型:多态类型和单态类型。典型的单态类型有`Int`、`Str`等,多态类型有`Option Int`、`[Int; 3]`等 +此外,定义改变对象状态的方法的类型称为 Mutable 类型,需要在变量属性中添加 `!`(例如动态数组:`[T; !_]`)。 -## Class +## 班级 -A type that has `.__new__`, `.__init__` 方法, etc. Implement class-based object orientation. +具有 `.__new__`、`.__init__` 方法等的类型。实现基于类的面向对象。 -## Function +## 功能 -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. +对外部变量(不包括静态变量)有读权限但对外部变量没有读/写权限的子程序。换句话说,它没有外部副作用。 +Erg 函数的定义与 Python 的不同,因为它们不允许副作用。 -## 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. +隐式将“self”作为第一个参数的子例程。它与简单的函数/过程是不同的类型。 -## 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 . +不是子例程和类型的对象。 +单态实体(`1`、`"a"` 等)也称为值对象,多态实体(`[1, 2, 3], {"a": 1}`)也称为容器对象。

上一页 | 下一页 From d0bb616c73ba7f032e18bc3b04803668db3ee4bd Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Sun, 4 Sep 2022 20:39:02 +0800 Subject: [PATCH 18/42] translate save --- doc/zh_CN/syntax/26_pattern_matching.md | 78 +++++++++---------- doc/zh_CN/syntax/27_comprehension.md | 40 +++++----- doc/zh_CN/syntax/28_spread_syntax.md | 10 +-- doc/zh_CN/syntax/29_decorator.md | 56 ++++++------- doc/zh_CN/syntax/30_error_handling.md | 57 +++++++------- doc/zh_CN/syntax/31_pipeline.md | 12 +-- .../syntax/32_integration_with_Python.md | 31 ++++---- doc/zh_CN/syntax/33_package_system.md | 30 +++---- doc/zh_CN/syntax/34_generator.md | 10 +-- doc/zh_CN/syntax/container_ownership.md | 12 +-- 10 files changed, 168 insertions(+), 168 deletions(-) diff --git a/doc/zh_CN/syntax/26_pattern_matching.md b/doc/zh_CN/syntax/26_pattern_matching.md index ac48c1e4..1b5b9bc9 100644 --- a/doc/zh_CN/syntax/26_pattern_matching.md +++ b/doc/zh_CN/syntax/26_pattern_matching.md @@ -1,51 +1,51 @@ -# pattern matching, refutable +# 模式匹配,可反驳 -## Patterns available in Erg +## Erg 中可用的模式 -### variable pattern +### 变量模式 ```python -# basic assignments +# 基本任务 i = 1 -# with type +# 有类型 i: Int = 1 -# with anonymous type +# 匿名类型 i: {1, 2, 3} = 2 -# functions +# 功能 fn x = x + 1 -# equals +# 等于 fn x: Add(Int) = x + 1 -# (anonymous) function +# (匿名)函数 fn = x -> x + 1 fn: Int -> Int = x -> x + 1 -# higher-order type +# 高阶类型 a: [Int; 4] = [0, 1, 2, 3] # or a: Array Int, 4 = [0, 1, 2, 3] ``` -### Literal patterns +### 文字字面量 ```python -# Raise a TypeError if `i` cannot be determined to be 1 at compile time. -# omit `_: {1} = i` +# 如果在编译时无法确定 `i` 为 1,则引发 TypeError。 +# 省略 `_: {1} = i` 1 = i -# simple pattern matching +# 简单的模式匹配 match x: 1 -> "1" 2 -> "2" _ -> "other" -# fibonacci function +# 斐波那契函数 fib0 = 0 fib1 = 1 fibn: Nat = fibn-1 + fibn-2 ``` -### constant pattern +### 常量模式 ```python cond=False @@ -62,18 +62,18 @@ name = match num: _ -> "unnamed" ``` -### Sieve pattern +### 筛子图案 ```python -# these two are the same +# 这两个是一样的 Array(T, N: {N | N >= 3}) Array(T, N | N >= 3) f M, N | M >= 0, N >= 1 = ... -f(1, 0) # TypeError: N (2nd parameter) must be 1 or more +f(1, 0) # 类型错误:N(第二个参数)必须为 1 或更多 ``` -### discard (wildcard) pattern +### 丢弃(通配符)模式 ```python _ = 1 @@ -82,9 +82,9 @@ zero_ = 0 right(_, r) = r ``` -### Variable length patterns +### 可变长度模式 -It is used in combination with the tuple/array/record pattern described later. +它与稍后描述的元组/数组/记录模式结合使用。 ```python [i,...j] = [1, 2, 3, 4] @@ -93,18 +93,18 @@ first|T|(fst: T, ...rest: T) = fst assert first(1, 2, 3) == 1 ``` -### Tuple pattern +### 元组模式 ```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) -# If not nested, () can be omitted (1, 2 are treated as (1, 2)) +# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) m, n = 1, 2 f(x, y) = ... ``` -### array pattern +### 数组模式 ```python [i, j] = [1, 2] @@ -114,11 +114,11 @@ length[] = 0 length[_, ...rest] = 1 + lengthrest ``` -#### record pattern +#### record 模式 ```python record = {i = 1; j = 2; k = 3} -{j; ...} = record # i, k will be freed +{j; ...} = record # i, k 将被释放 {sin; cos; tan; ...} = import "math" {*} = import "math" # import all @@ -131,7 +131,7 @@ age = match person: f {x: Int; y: Int} = ... ``` -### Data class pattern +### 数据类模式 ```python Point = Inherit {x = Int; y = Int} @@ -152,9 +152,9 @@ List T. _ -> ... ``` -### enumeration pattern +### 枚举模式 -*Actually, it's just an enumeration type +* 其实只是枚举类型 ```python match x: @@ -162,9 +162,9 @@ match x: _ -> "other" ``` -### range pattern +### Range 模式 -*Actually, it is just an interval type. +* 实际上,它只是一个区间类型。 ```python # 0 < i < 1 @@ -176,17 +176,17 @@ 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. +条件规格不是唯一的。 例如,要检查数字 `n` 是否为偶数,正统是 `n % 2 == 0`,但也可以写成 `(n / 2).round() == n / 2`。 +非唯一形式无论是正常工作还是等效于另一个条件都不是微不足道的。 -#### set +#### 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. +没有固定的模式。 因为集合没有办法唯一地检索元素。 +您可以通过迭代器检索它们,但不能保证顺序。

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/27_comprehension.md b/doc/zh_CN/syntax/27_comprehension.md index d734d27b..359be021 100644 --- a/doc/zh_CN/syntax/27_comprehension.md +++ b/doc/zh_CN/syntax/27_comprehension.md @@ -1,34 +1,34 @@ # Comprehension -Array with `[expr | (name <- iterable)+ (predicate)*]`, -set with `{expr | (name <- iterable)+ (predicate)*}`, -You can create a Dict with `{key: value | (name <- iterable)+ (predicate)*}`. +Array 和 `[expr | (name <- iterable)+ (predicate)*]`, +set 和 `{expr | (name <- iterable)+ (predicate)*}`, +你可以创建一个字典 `{key: value | (name <- iterable)+ (predicate)*}`. -The first part of the clauses separated by `|` is called the layout clause (location clause), the second part is called the bind clause (binding clause), and the third part is called the guard clause (conditional clause). -A guard clause can be omitted, but a bind clause cannot be omitted, and a guard clause cannot precede a bind clause. +由`|`分隔的子句的第一部分称为布局子句(位置子句),第二部分称为绑定子句(绑定子句),第三部分称为保护子句(条件子句)。 +保护子句可以省略,但绑定子句不能省略,保护子句不能在绑定子句之前。 -Comprehension example +理解示例 ```python -# the layout clause is i -# bind clause is i <- [0, 1, 2] +# 布局子句是 i +# 绑定子句是 i <- [0, 1, 2] assert [i | i <- [0, 1, 2]] == [0, 1, 2] -# layout clause is i / 2 -# bind clause is i <- 0..2 +# 布局子句是 i / 2 +# 绑定子句是 i <- 0..2 assert [i/2 | i <- 0..2] == [0.0, 0.5, 1.0] -# layout clause is (i, j) -# bind clause i <- 0..2, j <- 0..2 -# guard clause is (i + j) % 2 == 0 +# 布局子句是 (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 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. +Erg推导式受到 Haskell 的启发,但有一些不同。 +对于 Haskell 列表推导,变量的顺序会对结果产生影响,但在 Erg 中这并不重要。 ``` haskell -- Haskell @@ -41,21 +41,21 @@ For Haskell list comprehensions, the order of variables makes a difference in th assert [(i, j) | i <- 1..<3; j <- 3..<5] == [(i, j) | j <- 3..<5; i <- 1.. <3] ``` -This specification is the same as that of Python. +该规范与 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 +## 筛子类型 -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. +与推导类似的是筛类型。 筛子类型是以`{Name: Type | Predicate}`创建的(枚举类型) +sieve类型的情况下,只能指定一个Name,不能指定布局(但是如果是tuple类型可以处理多个值),Predicate可以在编译时计算,即 ,只能指定一个常量表达式。 ```python Nat = {I: Int | I >= 0} -# If the predicate expression is only and, it can be replaced with ; +# 如果谓词表达式只有and,可以替换为: # Nat2D = {(I, J): (Int, Int) | I >= 0; J >= 0} Nat2D = {(I, J): (Int, Int) | I >= 0 and J >= 0} ``` diff --git a/doc/zh_CN/syntax/28_spread_syntax.md b/doc/zh_CN/syntax/28_spread_syntax.md index a736a5a5..81b98343 100644 --- a/doc/zh_CN/syntax/28_spread_syntax.md +++ b/doc/zh_CN/syntax/28_spread_syntax.md @@ -1,6 +1,6 @@ -# Spread assignment +# 传播赋值 -In a decomposing assignment, putting `...` in front of a variable expands all remaining elements into that variable. This is called expansion assignment. +在分解赋值中,将 `...` 放在变量前面会将所有剩余元素展开到该变量中。 这称为扩展赋值。 ```python [x,...y] = [1, 2, 3] @@ -11,10 +11,10 @@ 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. +如果在 `...` 之后没有写入任何内容,则忽略并分配剩余的元素。 这种类型的扩展赋值具体称为抽取赋值。 +提取分配是一种方便的语法,用于本地化模块或记录中的特定属性。 ```python {sin; cos; tan; ..} = import "math" diff --git a/doc/zh_CN/syntax/29_decorator.md b/doc/zh_CN/syntax/29_decorator.md index 5417f3f3..66c9a07e 100644 --- a/doc/zh_CN/syntax/29_decorator.md +++ b/doc/zh_CN/syntax/29_decorator.md @@ -1,24 +1,24 @@ -# 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. +装饰器用于向类型或函数添加或演示特定状态或行为。 +装饰器的语法如下。 ```python @deco 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. +装饰器不是一个特殊的对象,它只是一个单参数函数。 装饰器等价于下面的伪代码。 ```python X=... X = deco(X) ``` -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 不允许重新分配变量,因此上面的代码不起作用。 +对于简单的变量,它与`X = deco(...)` 相同,但对于即时块和子例程,你不能这样做,所以你需要一个装饰器。 ```python @deco @@ -26,29 +26,29 @@ f x = y = ... x + y -# You can also prevent the code from becoming horizontal +# 还可以防止代码变成水平的 @LongNameDeco1 @LongNameDeco2 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. +指示定义类型是可继承的类。 如果为参数 `scope` 指定 `"public"`,甚至可以继承外部模块的类。 默认情况下它是`"private"`,不能被外部继承。 -##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 +## 覆盖 -Used when overriding attributes. By default, Erg will throw an error if you try to define the same attribute as the base class. +覆盖属性时使用。 默认情况下,如果您尝试定义与基类相同的属性,Erg 将抛出错误。 -## Impl +## 实现 -Indicates that the argument trait is implemented. +表示参数 trait 已实现。 ```python Add = Trait { @@ -66,10 +66,10 @@ C. `_-_` self, other = C.new {i = self::i - other::} ``` -## Attach +## 附 -Specifies the attachment patch that comes with the trait by default. -This allows you to reproduce the same behavior as Rust traits. +指定默认情况下随 trait 附带的附件补丁。 +这允许您重现与 Rust 特征相同的行为。 ```python # foo.er @@ -86,17 +86,17 @@ AddForOdd = Patch(Odd, Impl := ClosedAdd) AddForOdd.AddO = Even ``` -This will automatically apply the attachment patch when importing traits from other modules. +当从其他模块导入特征时,这将自动应用附件补丁。 -```python -# Originally, IntIsBinAdd and OddIsBinAdd should be imported at the same time, but if it's an attachment patch, you can omit it +```Python +# 本来应该同时导入IntIsBinAdd和OddIsBinAdd,但是如果是附件补丁可以省略 {BinAdd; ...} = import "foo" assert Int. AddO == Int assert Odd.AddO == Even ``` -Internally it's just attached using the trait's `.attach` method. Conflicts can be removed with the trait's `.detach` method. +在内部,它只是使用 trait 的 .attach 方法附加的。 可以使用 trait 的 `.detach` 方法消除冲突。 ```python @Attach X @@ -107,13 +107,13 @@ assert X not in U. attaches assert Y in U. attaches ``` -##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. +表示这是一个测试子例程。 测试子程序使用 `erg test` 命令运行。

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/30_error_handling.md b/doc/zh_CN/syntax/30_error_handling.md index 2e403ea7..2280a5ae 100644 --- a/doc/zh_CN/syntax/30_error_handling.md +++ b/doc/zh_CN/syntax/30_error_handling.md @@ -1,22 +1,22 @@ -# error handling system +# 错误处理系统 -Mainly use Result type. -In Erg, an error occurs if you throw away an Error type object (not supported at the top level). +主要使用Result类型。 +在 Erg 中,如果您丢弃 Error 类型的对象(顶层不支持),则会发生错误。 -## Exceptions, interop with Python +## 异常,与 Python 互操作 -Erg does not have an exception mechanism (Exception). When importing a Python function +Erg 没有异常机制(Exception)。 导入 Python 函数时 -* Set return value to `T or Error` type -* `T or Panic` type (may cause runtime error) +* 将返回值设置为 `T 或 Error` 类型 +* `T or Panic` 类型(可能导致运行时错误) -There are two options, `pyimport` defaults to the latter. If you want to import as the former, use -Specify `Error` in `pyimport` `exception_type` (`exception_type: {Error, Panic}`). +有两个选项,`pyimport` 默认为后者。 如果要作为前者导入,请使用 +在 `pyimport` `exception_type` 中指定 `Error` (`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. +`Result` 类型表示可能是错误的值。 `Result` 的错误处理在几个方面优于异常机制。 +首先,从类型定义中可以看出子程序可能会报错,实际使用时也很明显。 ```python # Python @@ -28,7 +28,7 @@ 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. +在上面的示例中,仅凭此代码无法判断哪个函数引发了异常。 即使回到函数定义,也很难判断函数是否抛出异常。 ```python # Erg @@ -41,15 +41,14 @@ 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. +另一方面,在这个例子中,我们可以看到 `foo!` 和 `qux!` 会引发错误。 +确切地说,`y` 也可能是 `Result` 类型,但您最终必须处理它才能使用里面的值。 -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. +使用 `Result` 类型的好处不止于此。 `Result` 类型也是线程安全的。 这意味着错误信息可以(轻松)在并行执行之间传递。 -## 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. +## 语境 +由于 `Error`/`Result` 类型本身不会产生副作用,不像异常,它不能有发送位置(Context)等信息,但是如果使用 `.context` 方法,可以将信息放在 `错误`对象。 可以添加。 `.context` 方法是一种使用 `Error` 对象本身并创建新的 `Error` 对象的方法。 它们是可链接的,并且可以包含多个上下文。 ```python f() = todo() \ @@ -62,14 +61,14 @@ f() # hint: and more hints ... ``` -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. +请注意,诸如 `.msg` 和 `.kind` 之类的 `Error` 属性不是次要的,因此它们不是上下文,并且不能像最初创建时那样被覆盖。 -## Stack trace +## 堆栈跟踪 -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. +`Result` 类型由于其方便性在其他语言中经常使用,但与异常机制相比,它的缺点是难以理解错误的来源。 +因此,在 Erg 中,`Error` 对象具有名为 `.stack` 的属性,并再现了类似伪异常机制的堆栈跟踪。 +`.stack` 是调用者对象的数组。 每次 Error 对象被`return`(包括通过`?`)时,它都会将它的调用子例程推送到`.stack`。 +如果它是 `?`ed 或 `.unwrap`ed 在一个不可能 `return` 的上下文中,它会因为回溯而恐慌。 ```python f x = @@ -93,12 +92,12 @@ i = g(1)? # Error: ... ``` -## Panic +## 恐慌 -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". +Erg 还有一种处理不可恢复错误的机制,称为 __panicing__。 +不可恢复的错误是由外部因素引起的错误,例如软件/硬件故障、严重到无法继续执行代码的错误或程序员未预料到的错误。 等如果发生这种情况,程序将立即终止,因为程序员的努力无法恢复正常运行。 这被称为“恐慌”。 -Panic is done with the `panic` function. +恐慌是通过 `panic` 功能完成的。 ```python panic "something went wrong!" diff --git a/doc/zh_CN/syntax/31_pipeline.md b/doc/zh_CN/syntax/31_pipeline.md index 4978f417..acaeef49 100644 --- a/doc/zh_CN/syntax/31_pipeline.md +++ b/doc/zh_CN/syntax/31_pipeline.md @@ -1,15 +1,15 @@ -# pipeline operator +# 管道运算符 -Pipeline operators are used like this: +管道运算符的使用方式如下: ```python assert f(g(x)) == (x |> g |> f) assert f(g(x, y)) == ((x, y) |> g |> f) ``` -In other words, the order `Callable(object)` can be changed to `object |> Callable`. -The pipeline operator can also be used on 方法. For 方法, `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 `()`. +换句话说,`Callable(object)` 的顺序可以更改为 `object |> Callable`。 +管道运算符也可用于方法。 对于方法,`object.method(args)` 更改为 `object |>.method(args)`。 +它看起来只是更多的`|>`,但由于粘合强度较低,您可以减少`()`的数量。 ```python rand = -1.0..1.0 |>.sample!() @@ -18,7 +18,7 @@ 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 \ diff --git a/doc/zh_CN/syntax/32_integration_with_Python.md b/doc/zh_CN/syntax/32_integration_with_Python.md index 021ce6dc..d18ac194 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 @@ -# Integration with Python +# 与 Python 集成 -## Export to Python +## 导出到 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 脚本时,会生成一个 .pyc 文件,可以简单地将其作为 Python 模块导入。 +但是,无法从 Python 访问在 Erg 端设置为私有的变量。 ```python # foo.er @@ -19,26 +19,26 @@ erg --compile foo.er import foo print(foo.public) -print(foo.private) # AttributeError: +print(foo.private) # 属性错误: ``` -## 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 导入的所有对象都是“Object”类型。 由于此时无法进行比较,因此有必要细化类型。 -## Type Specification in the Standard Library +## 标准库中的类型规范 -All APIs in the Python standard library are type specified by the Erg development team. +Python 标准库中的所有 API 都是由 Erg 开发团队指定的类型。 ```python time = pyimport "time" time.sleep! 1 ``` -## 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` 模块的 `foo.d.er` 文件。 +Python 端的类型提示被忽略,因为它们不是 100% 保证的。 ```python # foo.py @@ -63,11 +63,12 @@ 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. +这通过在运行时执行类型检查来确保类型安全。 ``declare`` 函数大致如下工作 + ```python 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) @@ -75,7 +76,7 @@ declare|S: Subroutine| sub!: S, T = y ``` -Since this is a runtime overhead, a project is planned to statically type analyze Python scripts with Erg's type system. +由于这是运行时开销,因此计划使用 Erg 的类型系统对 Python 脚本进行静态类型分析

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/33_package_system.md b/doc/zh_CN/syntax/33_package_system.md index 9d885e0e..c3453333 100644 --- a/doc/zh_CN/syntax/33_package_system.md +++ b/doc/zh_CN/syntax/33_package_system.md @@ -1,15 +1,15 @@ -# Package System +# 打包系统 -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包大致可以分为app包,即应用程序,以及lib包,即库。 +应用包的入口点是`src/app.er`。 `app.er` 中定义的`main` 函数被执行。 +lib 包的入口点是`src/lib.er`。导入包相当于导入 `lib.er`。 -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. +一个包有一个称为模块的子结构,在 Erg 中是一个 Erg 文件或由 Erg 文件组成的目录。外部 Erg 文件/目录是作为模块对象的可操作对象。 -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. +为了将目录识别为模块,有必要在目录中放置一个“(目录名称).er”文件。 +这类似于 Python 的 `__init__.py`,但与 `__init__.py` 不同的是,它放在目录之外。 -As an example, consider the following directory structure. +例如,考虑以下目录结构。 ```console └─┬ ./src @@ -21,9 +21,9 @@ As an example, consider the following directory structure. └─ 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. +您可以在 `app.er` 中导入 `foo` 和 `bar` 模块。由于 `bar.er` 文件,`bar` 目录可以被识别为一个模块。 +`foo` 模块是由文件组成的模块,`bar` 模块是由目录组成的模块。 `bar` 模块还包含 `baz` 和 `qux` 模块。 +该模块只是 `bar` 模块的一个属性,可以从 `app.er` 访问,如下所示。 ```python # app.er @@ -36,9 +36,9 @@ main args = ... ``` -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. +请注意用于访问子模块的 `/` 分隔符。 这是因为可以有诸如 `bar.baz.er` 之类的文件名。 +不鼓励使用此类文件名,因为 `.er` 前缀在 Erg 中是有意义的。 +例如,用于测试的模块。 以 `.test.er` 结尾的文件是一个(白盒)测试模块,它在运行测试时执行一个用 `@Test` 修饰的子例程。 ```console └─┬ ./src @@ -55,7 +55,7 @@ main args = ... ``` -Also, files ending in ``.private.er`` are private modules and can only be accessed by modules in the same directory. +此外,以 .private.er 结尾的文件是私有模块,只能由同一目录中的模块访问。 ```console └─┬ diff --git a/doc/zh_CN/syntax/34_generator.md b/doc/zh_CN/syntax/34_generator.md index 8e927025..5c807345 100644 --- a/doc/zh_CN/syntax/34_generator.md +++ b/doc/zh_CN/syntax/34_generator.md @@ -1,6 +1,6 @@ -# Generator +# 生成器 -Generators are special procedures that use the `yield!` procedure in a block. +生成器是在块中使用 `yield!` 过程的特殊过程。 ```python g!() = @@ -9,8 +9,8 @@ g!() = yield! 3 ``` -`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. +`yield!` 是在调用`self!.yield!` 的子程序块中定义的过程。 和`return`一样,它把传递给它的值作为返回值返回,但它具有保存block当前执行状态,再次调用时从头开始执行的特性。 +生成器既是过程又是迭代器; Python 生成器是一个创建迭代器的函数,而 Erg 直接迭代。 过程本身通常不是可变对象(没有`!`),但生成器是可变对象,因为它自己的内容可以随着每次执行而改变。 ```python # Generator! @@ -20,7 +20,7 @@ assert g!() == 2 assert g!() == 3 ``` -A Python-style generator can be defined as follows. +Python 风格的生成器可以定义如下。 ```python make_g() = () => diff --git a/doc/zh_CN/syntax/container_ownership.md b/doc/zh_CN/syntax/container_ownership.md index 08f90efc..4195d404 100644 --- a/doc/zh_CN/syntax/container_ownership.md +++ b/doc/zh_CN/syntax/container_ownership.md @@ -1,6 +1,6 @@ -# Subscript (index access) +# 下标(索引访问) -`[]` is different from normal 方法. +`[]` 不同于普通的方法。 ```python a = [!1, !2] @@ -8,10 +8,10 @@ a[0].inc!() assert a == [2, 2] ``` -Recall that the return value of a subroutine cannot be a reference. -The type of `a[0]` here should clearly be `Ref!(Int!)` (the type of `a[0]` depends on the context). -So `[]` is actually part of a special syntax, just like `.`. Unlike Python, it cannot be overloaded. -It is also not possible to reproduce the behavior of `[]` in a method. +回想一下,子例程的返回值不能是引用。 +这里的 `a[0]` 的类型显然应该是 `Ref!(Int!)`(`a[0]` 的类型取决于上下文)。 +所以 `[]` 实际上是特殊语法的一部分,就像 `.` 一样。 与 Python 不同,它不能被重载。 +也无法在方法中重现 `[]` 的行为。 ```python C = Class {i = Int!} From 089b02c6ed4e8ab8e54c2ab4ea7accb3e2449d66 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Mon, 5 Sep 2022 20:39:30 +0800 Subject: [PATCH 19/42] trifle --- doc/EN/API/procs.md | 2 +- doc/EN/API/types.md | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/EN/API/procs.md b/doc/EN/API/procs.md index 36696540..d89f82dc 100644 --- a/doc/EN/API/procs.md +++ b/doc/EN/API/procs.md @@ -8,7 +8,7 @@ print!(x) -> NoneType Returns x with a newline. -##debug! +## debug! ```python debug!(x, type = Info) -> NoneType diff --git a/doc/EN/API/types.md b/doc/EN/API/types.md index 2eba4b08..c0a28984 100644 --- a/doc/EN/API/types.md +++ b/doc/EN/API/types.md @@ -16,7 +16,7 @@ Attributes of the type itself are not stored in the `.__dict__` and cannot be re * `__str__`: returns the string representation (rich) of the object -###Fmt +### Fmt * `__format__`: Returns a formatted string @@ -151,13 +151,13 @@ As an example other than Complex, Vector, Matrix, and Tensor are Num (* in Matri * `isdecimal`: * `is sight`: * `is identifier` -*`islower` +* `islower` * `is numeric` * `isprintable` * `isspace` * `is title` * `isupper` -*`lower` +* `lower` * `swapcase` * `title` * `upper` @@ -182,9 +182,9 @@ Nat and Range have Iterators, so `Nat.iter().map n -> n**2`, `(3..10).iter().fol 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`: Returns the first element and the remaining Iterator. -*`all` -*`any` -*`filter` +* `all` +* `any` +* `filter` * `filter_map` * `find` * `find_map` @@ -192,13 +192,13 @@ Since all and any are destroyed after use, there are no side effects. These are * `flatten` * `fold` * `for_each` -*`map` +* `map` * `map_while` * `nth` -*`pos` +* `pos` * `take` * `unzip` -*`zip` +* `zip` ### Iterator!T = IteratorT and ... From 70d2ae73aea833f349dbb8cc0ea1fd9df00e7c9f Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Mon, 5 Sep 2022 20:43:02 +0800 Subject: [PATCH 20/42] trifle --- doc/EN/syntax/{grammar.txt => grammar.md} | 2 ++ doc/JA/syntax/{grammar.txt => grammar.md} | 2 ++ doc/zh_CN/syntax/container_ownership.md | 12 ++++++------ doc/zh_CN/syntax/{grammar.txt => grammar.md} | 4 +++- 4 files changed, 13 insertions(+), 7 deletions(-) rename doc/EN/syntax/{grammar.txt => grammar.md} (99%) rename doc/JA/syntax/{grammar.txt => grammar.md} (99%) rename doc/zh_CN/syntax/{grammar.txt => grammar.md} (98%) diff --git a/doc/EN/syntax/grammar.txt b/doc/EN/syntax/grammar.md similarity index 99% rename from doc/EN/syntax/grammar.txt rename to doc/EN/syntax/grammar.md index d9dbbb2a..06a6d6d2 100644 --- a/doc/EN/syntax/grammar.txt +++ b/doc/EN/syntax/grammar.md @@ -1,4 +1,5 @@ # The Grammar of Erg (ver 0.1.0, provisional) +``` special_op ::= '=' | '->' | '=>' | '.' | ',' | ':' | '::' | '|>' | '&' separator ::= ';' | '\n' escape ::= '\' @@ -86,3 +87,4 @@ expr ::= accessor | literal | call | def | lambda line ::= expr separator+ program ::= expr? | (line | comment)* +``` \ No newline at end of file diff --git a/doc/JA/syntax/grammar.txt b/doc/JA/syntax/grammar.md similarity index 99% rename from doc/JA/syntax/grammar.txt rename to doc/JA/syntax/grammar.md index d9dbbb2a..06a6d6d2 100644 --- a/doc/JA/syntax/grammar.txt +++ b/doc/JA/syntax/grammar.md @@ -1,4 +1,5 @@ # The Grammar of Erg (ver 0.1.0, provisional) +``` special_op ::= '=' | '->' | '=>' | '.' | ',' | ':' | '::' | '|>' | '&' separator ::= ';' | '\n' escape ::= '\' @@ -86,3 +87,4 @@ expr ::= accessor | literal | call | def | lambda line ::= expr separator+ program ::= expr? | (line | comment)* +``` \ No newline at end of file diff --git a/doc/zh_CN/syntax/container_ownership.md b/doc/zh_CN/syntax/container_ownership.md index 4195d404..da50a3d2 100644 --- a/doc/zh_CN/syntax/container_ownership.md +++ b/doc/zh_CN/syntax/container_ownership.md @@ -16,13 +16,13 @@ assert a == [2, 2] ```python C = Class {i = Int!} C. get(ref self) = - self::i # TypeError: `self::i` is `Int!` (require ownership) but `get` doesn't own `self` + self::i # 类型错误:`self::i` 是 `Int!`(需要所有权)但 `get` 不拥有 `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.new({i = 1}).steal().inc!() # 所有权警告:`C.new({i = 1}).steal()` 不属于任何人 +# 提示:分配给变量或使用 `uwn_do!` +# OK (分配) c = C.new({i = 1}) i = c.steal() i.inc!() @@ -31,12 +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. +此外,`[]` 可以不承认,但元素不会移动 ```python a = [!1, !2] i = a[0] i.inc!() assert a[1] == 2 -a[0] # OwnershipError: `a[0]` is moved to `i` +a[0] # 所有权错误:`a[0]` 被移动到 `i` ``` \ No newline at end of file diff --git a/doc/zh_CN/syntax/grammar.txt b/doc/zh_CN/syntax/grammar.md similarity index 98% rename from doc/zh_CN/syntax/grammar.txt rename to doc/zh_CN/syntax/grammar.md index d9dbbb2a..5e5ab93d 100644 --- a/doc/zh_CN/syntax/grammar.txt +++ b/doc/zh_CN/syntax/grammar.md @@ -1,4 +1,5 @@ -# The Grammar of Erg (ver 0.1.0, provisional) +# Erg 的语法(版本 0.1.0, 临时) +``` special_op ::= '=' | '->' | '=>' | '.' | ',' | ':' | '::' | '|>' | '&' separator ::= ';' | '\n' escape ::= '\' @@ -86,3 +87,4 @@ expr ::= accessor | literal | call | def | lambda line ::= expr separator+ program ::= expr? | (line | comment)* +``` \ No newline at end of file From 6208de871cdb118e96a9c74ef40d716ee224baa9 Mon Sep 17 00:00:00 2001 From: GreasySlug <9619abgoni@gmail.com> Date: Mon, 5 Sep 2022 21:54:42 +0900 Subject: [PATCH 21/42] Remove badges in JA doc --- doc/JA/dev_guide/branches.md | 1 - doc/JA/dev_guide/build_features.md | 1 - doc/JA/dev_guide/directories.md | 1 - doc/JA/dev_guide/doc_guideline.md | 1 - doc/JA/dev_guide/env.md | 1 - doc/JA/dev_guide/faq_syntax.md | 1 - doc/JA/dev_guide/i18n_messages.md | 1 - doc/JA/dev_guide/index.md | 1 - doc/JA/dev_guide/rust_code_guideline.md | 1 - doc/JA/dev_guide/terms.md | 1 - doc/JA/dev_guide/unify_terms.md | 1 - doc/JA/faq_general.md | 1 - doc/JA/faq_technical.md | 1 - doc/JA/improved_points.md | 1 - doc/JA/index.md | 1 - doc/JA/migration_from_py.md | 1 - doc/JA/syntax/00_basic.md | 1 - doc/JA/syntax/01_literal.md | 1 - doc/JA/syntax/02_name.md | 1 - doc/JA/syntax/03_declaration.md | 1 - doc/JA/syntax/04_function.md | 1 - doc/JA/syntax/05_builtin_funcs.md | 1 - doc/JA/syntax/06_operator.md | 1 - doc/JA/syntax/07_side_effect.md | 1 - doc/JA/syntax/08_procedure.md | 1 - doc/JA/syntax/09_builtin_procs.md | 1 - doc/JA/syntax/10_array.md | 1 - doc/JA/syntax/11_tuple.md | 1 - doc/JA/syntax/12_dict.md | 1 - doc/JA/syntax/13_record.md | 1 - doc/JA/syntax/14_set.md | 1 - doc/JA/syntax/15_type.md | 1 - doc/JA/syntax/16_iterator.md | 1 - doc/JA/syntax/17_mutability.md | 1 - doc/JA/syntax/18_ownership.md | 1 - doc/JA/syntax/19_visibility.md | 1 - doc/JA/syntax/20_naming_rule.md | 1 - doc/JA/syntax/21_lambda.md | 1 - doc/JA/syntax/22_subroutine.md | 1 - doc/JA/syntax/23_closure.md | 1 - doc/JA/syntax/24_module.md | 1 - doc/JA/syntax/25_object_system.md | 1 - doc/JA/syntax/26_pattern_matching.md | 1 - doc/JA/syntax/27_comprehension.md | 1 - doc/JA/syntax/28_spread_syntax.md | 1 - doc/JA/syntax/29_decorator.md | 1 - doc/JA/syntax/30_error_handling.md | 1 - doc/JA/syntax/31_pipeline.md | 1 - doc/JA/syntax/32_integration_with_Python.md | 1 - doc/JA/syntax/33_package_system.md | 1 - doc/JA/syntax/34_generator.md | 1 - doc/JA/syntax/SUMMARY.md | 1 - doc/JA/syntax/container_ownership.md | 1 - doc/JA/syntax/indexes.md | 1 - doc/JA/syntax/quick_tour.md | 1 - doc/JA/syntax/type/01_type_system.md | 1 - doc/JA/syntax/type/02_basic.md | 1 - doc/JA/syntax/type/03_trait.md | 1 - doc/JA/syntax/type/04_class.md | 1 - doc/JA/syntax/type/05_inheritance.md | 1 - doc/JA/syntax/type/06_nst_vs_sst.md | 1 - doc/JA/syntax/type/07_patch.md | 1 - doc/JA/syntax/type/08_value.md | 1 - doc/JA/syntax/type/09_attributive.md | 1 - doc/JA/syntax/type/10_interval.md | 1 - doc/JA/syntax/type/11_enum.md | 1 - doc/JA/syntax/type/12_refinement.md | 1 - doc/JA/syntax/type/13_algebraic.md | 1 - doc/JA/syntax/type/14_dependent.md | 1 - doc/JA/syntax/type/15_quantified.md | 1 - doc/JA/syntax/type/16_subtyping.md | 1 - doc/JA/syntax/type/17_type_casting.md | 1 - doc/JA/syntax/type/18_mut.md | 1 - doc/JA/syntax/type/19_bound.md | 1 - doc/JA/syntax/type/advanced.md | 1 - doc/JA/syntax/type/advanced/GADTs.md | 1 - doc/JA/syntax/type/advanced/default_param.md | 1 - doc/JA/syntax/type/advanced/erasure.md | 1 - doc/JA/syntax/type/advanced/existential.md | 1 - doc/JA/syntax/type/advanced/keyword_param.md | 1 - doc/JA/syntax/type/advanced/kind.md | 1 - doc/JA/syntax/type/advanced/marker_trait.md | 1 - doc/JA/syntax/type/advanced/mut_struct.md | 1 - doc/JA/syntax/type/advanced/newtype.md | 1 - doc/JA/syntax/type/advanced/overloading.md | 1 - doc/JA/syntax/type/advanced/phantom.md | 1 - doc/JA/syntax/type/advanced/projection.md | 1 - doc/JA/syntax/type/advanced/quantified_dependent.md | 1 - doc/JA/syntax/type/advanced/shared.md | 1 - doc/JA/syntax/type/advanced/special.md | 1 - doc/JA/tips.md | 1 - 91 files changed, 91 deletions(-) diff --git a/doc/JA/dev_guide/branches.md b/doc/JA/dev_guide/branches.md index 9a327512..1fd16786 100644 --- a/doc/JA/dev_guide/branches.md +++ b/doc/JA/dev_guide/branches.md @@ -1,6 +1,5 @@ # ブランチの命名と運用方針 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/branches.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/branches.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) * 基本的に開発は`main`ブランチ一本で行う(モノレポ開発)。どうしてもブランチを切らないと作業しにくい場合のみ`feature-*`ブランチか`issue-*`ブランチを作成する。 diff --git a/doc/JA/dev_guide/build_features.md b/doc/JA/dev_guide/build_features.md index 58684546..e6dbbf9d 100644 --- a/doc/JA/dev_guide/build_features.md +++ b/doc/JA/dev_guide/build_features.md @@ -1,6 +1,5 @@ # `erg` build features -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/build_features.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/build_features.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## debug diff --git a/doc/JA/dev_guide/directories.md b/doc/JA/dev_guide/directories.md index 5501dc7a..df6f6bb8 100644 --- a/doc/JA/dev_guide/directories.md +++ b/doc/JA/dev_guide/directories.md @@ -1,6 +1,5 @@ # Ergリポジトリのディレクトリ構造 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/directories.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/directories.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ```console └─┬ assets: 画像など diff --git a/doc/JA/dev_guide/doc_guideline.md b/doc/JA/dev_guide/doc_guideline.md index ed0c5594..8aa8ca89 100644 --- a/doc/JA/dev_guide/doc_guideline.md +++ b/doc/JA/dev_guide/doc_guideline.md @@ -1,6 +1,5 @@ # 書式 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/doc_guideline.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/doc_guideline.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 以下のルールに従っていないドキュメントはすべて修正の対象となる。 diff --git a/doc/JA/dev_guide/env.md b/doc/JA/dev_guide/env.md index 2a53b714..49a64042 100644 --- a/doc/JA/dev_guide/env.md +++ b/doc/JA/dev_guide/env.md @@ -1,6 +1,5 @@ # 開発環境 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/env.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/env.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## インストールが必要なもの diff --git a/doc/JA/dev_guide/faq_syntax.md b/doc/JA/dev_guide/faq_syntax.md index 7c5abd83..8f2c615c 100644 --- a/doc/JA/dev_guide/faq_syntax.md +++ b/doc/JA/dev_guide/faq_syntax.md @@ -1,6 +1,5 @@ # Erg design's "Why" and Answers -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/faq_syntax.md%26commit_hash%3D7cace5de15829b4b228a13f8b67e5ee3bf99e4a8)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/faq_syntax.md&commit_hash=7cace5de15829b4b228a13f8b67e5ee3bf99e4a8) ## なぜ所有権システムがあるのにGCも共存させているのですか? diff --git a/doc/JA/dev_guide/i18n_messages.md b/doc/JA/dev_guide/i18n_messages.md index b0b239ba..ddafc18a 100644 --- a/doc/JA/dev_guide/i18n_messages.md +++ b/doc/JA/dev_guide/i18n_messages.md @@ -1,6 +1,5 @@ # メッセージの多言語化 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/i18n_messages.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/i18n_messages.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Ergはメッセージ(スタート、オプション、ドキュメント、ヒント、警告、エラーメッセージなど)の多言語化を進めています。 このプロジェクトは、RustやErgの詳しい知識がなくても参加することができます。ぜひ協力をお願いします。 diff --git a/doc/JA/dev_guide/index.md b/doc/JA/dev_guide/index.md index 0e41be9e..8b137891 100644 --- a/doc/JA/dev_guide/index.md +++ b/doc/JA/dev_guide/index.md @@ -1,2 +1 @@ -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/index.md%26commit_hash%3D7d43acdf0e2b71528b038b9a8e70be6c93831f96)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/index.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96) diff --git a/doc/JA/dev_guide/rust_code_guideline.md b/doc/JA/dev_guide/rust_code_guideline.md index 681ac8e3..e679e8e4 100644 --- a/doc/JA/dev_guide/rust_code_guideline.md +++ b/doc/JA/dev_guide/rust_code_guideline.md @@ -1,6 +1,5 @@ # Rustコードに関するガイドライン -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/rust_code_guideline.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/rust_code_guideline.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## ローカルルール diff --git a/doc/JA/dev_guide/terms.md b/doc/JA/dev_guide/terms.md index b95d3b0a..7c2a8be1 100644 --- a/doc/JA/dev_guide/terms.md +++ b/doc/JA/dev_guide/terms.md @@ -1,6 +1,5 @@ # 用語辞典 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/terms.md%26commit_hash%3D7d43acdf0e2b71528b038b9a8e70be6c93831f96)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/terms.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96) ## 記号 diff --git a/doc/JA/dev_guide/unify_terms.md b/doc/JA/dev_guide/unify_terms.md index daece4cf..76984a3b 100644 --- a/doc/JA/dev_guide/unify_terms.md +++ b/doc/JA/dev_guide/unify_terms.md @@ -1,6 +1,5 @@ # 用語の統一 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/unify_terms.md%26commit_hash%3D7d43acdf0e2b71528b038b9a8e70be6c93831f96)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/unify_terms.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96) ## Accessibility, Visibility (参照性、可視性) diff --git a/doc/JA/faq_general.md b/doc/JA/faq_general.md index f950b405..18c0c6ae 100644 --- a/doc/JA/faq_general.md +++ b/doc/JA/faq_general.md @@ -1,6 +1,5 @@ # Erg FAQ -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/faq_general.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_general.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) このFAQは一般のErg入門者向けです。 個別の(よくある)技術的な問題については[こちら](./faq_technical.md)を、文法の決定経緯(なぜこのような文法になったのか)などについては diff --git a/doc/JA/faq_technical.md b/doc/JA/faq_technical.md index d34e4ea3..8faeee50 100644 --- a/doc/JA/faq_technical.md +++ b/doc/JA/faq_technical.md @@ -1,6 +1,5 @@ # 技術的なFAQ -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/faq_technical.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_technical.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 本項はErg言語を使用する上での技術的な質問に答えるものです。すなわち、WhatやWhichで始まる質問、Yes/Noで答えられる質問を載せています。 diff --git a/doc/JA/improved_points.md b/doc/JA/improved_points.md index 1bf003ca..1e0f6dbb 100644 --- a/doc/JA/improved_points.md +++ b/doc/JA/improved_points.md @@ -1,6 +1,5 @@ # Pythonから改良された点 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/improved_points.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/improved_points.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## 静的解析を行う(静的型チェック、変数・プロパティチェック) diff --git a/doc/JA/index.md b/doc/JA/index.md index fa32a045..0b95fd68 100644 --- a/doc/JA/index.md +++ b/doc/JA/index.md @@ -1,6 +1,5 @@ # Index -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/index.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/index.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## [API/](./API/index.md) diff --git a/doc/JA/migration_from_py.md b/doc/JA/migration_from_py.md index 734f63f5..3ffaf52a 100644 --- a/doc/JA/migration_from_py.md +++ b/doc/JA/migration_from_py.md @@ -1,6 +1,5 @@ # PythonからErgへの移行に関してのTips -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/migration_from_py.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/migration_from_py.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## 文字列をint等に変換したい diff --git a/doc/JA/syntax/00_basic.md b/doc/JA/syntax/00_basic.md index f83f261c..95ba5f6d 100644 --- a/doc/JA/syntax/00_basic.md +++ b/doc/JA/syntax/00_basic.md @@ -1,6 +1,5 @@ # 基本事項 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/00_basic.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) > __Warning__: 本ドキュメントは未完成です。校正(文体、正しいリンクが張られているか、など)がなされていません。また、Ergの文法はバージョン0.*の間に破壊的変更が加えられる可能性があり、それに伴うドキュメントの更新が追いついていない可能性があります。予めご了承ください。 > また、本ドキュメントの誤りを見つけた場合は、[こちらのフォーム](https://forms.gle/HtLYRfYzWCAaeTGb6)または[GitHubリポジトリ](https://github.com/mtshiba/TheErgBook/issues/new)から修正の提案をしていただけると幸いです。 diff --git a/doc/JA/syntax/01_literal.md b/doc/JA/syntax/01_literal.md index cf6d2b5e..a7310dd5 100644 --- a/doc/JA/syntax/01_literal.md +++ b/doc/JA/syntax/01_literal.md @@ -1,6 +1,5 @@ # Literal -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/01_literal.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/01_literal.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## 基本的なリテラル diff --git a/doc/JA/syntax/02_name.md b/doc/JA/syntax/02_name.md index a9012d2e..1e9ee3ba 100644 --- a/doc/JA/syntax/02_name.md +++ b/doc/JA/syntax/02_name.md @@ -1,6 +1,5 @@ # 変数 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/02_name.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 変数は代数の一種です。Ergにおける代数―紛れがなければ単に変数と呼ばれることもあります―とは、オブジェクトを名前付けしてコード中の別の場所から利用できるようにする機能を指します。 diff --git a/doc/JA/syntax/03_declaration.md b/doc/JA/syntax/03_declaration.md index c0cfd70d..9d8638c9 100644 --- a/doc/JA/syntax/03_declaration.md +++ b/doc/JA/syntax/03_declaration.md @@ -1,6 +1,5 @@ # Declaration(宣言) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/03_declaration.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/03_declaration.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 宣言は、使用する変数の型を指定する構文です。 宣言はコード中のどこでも可能ですが、宣言しただけでその変数を参照することはできません。必ず初期化する必要があります。 diff --git a/doc/JA/syntax/04_function.md b/doc/JA/syntax/04_function.md index 1d1bd382..3b88a348 100644 --- a/doc/JA/syntax/04_function.md +++ b/doc/JA/syntax/04_function.md @@ -1,6 +1,5 @@ # 関数 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/04_function.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/04_function.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 関数は「引数」を受け取ってそれを加工し、「戻り値」として返すブロックです。以下のように定義します。 diff --git a/doc/JA/syntax/05_builtin_funcs.md b/doc/JA/syntax/05_builtin_funcs.md index 819a5ddf..edcc2179 100644 --- a/doc/JA/syntax/05_builtin_funcs.md +++ b/doc/JA/syntax/05_builtin_funcs.md @@ -1,6 +1,5 @@ # 組み込み関数 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/05_builtin_funcs.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/05_builtin_funcs.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## if diff --git a/doc/JA/syntax/06_operator.md b/doc/JA/syntax/06_operator.md index 9faa8bd3..b3d6857a 100644 --- a/doc/JA/syntax/06_operator.md +++ b/doc/JA/syntax/06_operator.md @@ -1,6 +1,5 @@ # 演算子 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/06_operator.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/06_operator.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 演算子(オペレーター)は、演算を表す記号です。被演算子(オペランド)は演算子の(左)右にあるもので、Ergでは専らオブジェクトです。 diff --git a/doc/JA/syntax/07_side_effect.md b/doc/JA/syntax/07_side_effect.md index 9bcfe0fb..df1381f2 100644 --- a/doc/JA/syntax/07_side_effect.md +++ b/doc/JA/syntax/07_side_effect.md @@ -1,6 +1,5 @@ # 副作用とプロシージャ -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/07_side_effect.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/07_side_effect.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) これまで`print!`の`!`の意味を説明せずにいましたが、いよいよその意味が明かされます。この!は、ズバリこのオブジェクトが「副作用」のある「プロシージャ」であることを示しています。プロシージャは関数に「副作用」という効果を与えたものです。 diff --git a/doc/JA/syntax/08_procedure.md b/doc/JA/syntax/08_procedure.md index 56bf6675..34729273 100644 --- a/doc/JA/syntax/08_procedure.md +++ b/doc/JA/syntax/08_procedure.md @@ -1,6 +1,5 @@ # プロシージャ -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/08_procedure.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/08_procedure.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) プロシージャは可変オブジェクトを取り扱う際に必要となりますが、可変オブジェクトを引数に持てばプロシージャであるとは限りません。 diff --git a/doc/JA/syntax/09_builtin_procs.md b/doc/JA/syntax/09_builtin_procs.md index 8ac27997..ccdd0a9f 100644 --- a/doc/JA/syntax/09_builtin_procs.md +++ b/doc/JA/syntax/09_builtin_procs.md @@ -1,6 +1,5 @@ # 組み込みプロシージャ -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/09_builtin_procs.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/09_builtin_procs.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## id! diff --git a/doc/JA/syntax/10_array.md b/doc/JA/syntax/10_array.md index 7b74e2a8..7d9c413b 100644 --- a/doc/JA/syntax/10_array.md +++ b/doc/JA/syntax/10_array.md @@ -1,6 +1,5 @@ # 配列 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/10_array.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/10_array.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 配列はもっとも基本的な __コレクション(集約)__ です。 コレクションとは、内部にオブジェクトを複数保持できるオブジェクトのことです。 diff --git a/doc/JA/syntax/11_tuple.md b/doc/JA/syntax/11_tuple.md index 5cb9e0ca..d734d6f7 100644 --- a/doc/JA/syntax/11_tuple.md +++ b/doc/JA/syntax/11_tuple.md @@ -1,6 +1,5 @@ # タプル -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/11_tuple.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/11_tuple.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) タプルは配列と似ていますが、違う型のオブジェクトを保持できます。 このようなコレクションを非等質なコレクションと呼びます。対して等質なコレクションには配列、セットなどがあります。 diff --git a/doc/JA/syntax/12_dict.md b/doc/JA/syntax/12_dict.md index 39726e6a..56859e74 100644 --- a/doc/JA/syntax/12_dict.md +++ b/doc/JA/syntax/12_dict.md @@ -1,6 +1,5 @@ # Dict -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/12_dict.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/12_dict.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Dictはキーと値のペアを持つコレクションです。 diff --git a/doc/JA/syntax/13_record.md b/doc/JA/syntax/13_record.md index 1981c83e..c5711133 100644 --- a/doc/JA/syntax/13_record.md +++ b/doc/JA/syntax/13_record.md @@ -1,6 +1,5 @@ # レコード -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/13_record.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/13_record.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) レコードは、キーでアクセスするDictとコンパイル時にアクセスが検査されるタプルの性質を併せ持つコレクションです。 JavaScriptをやったことがある方ならば、オブジェクトリテラル記法の(より強化された)ようなものと考えてください。 diff --git a/doc/JA/syntax/14_set.md b/doc/JA/syntax/14_set.md index 6b0e0479..d63ace6c 100644 --- a/doc/JA/syntax/14_set.md +++ b/doc/JA/syntax/14_set.md @@ -1,6 +1,5 @@ # セット(Set) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/14_set.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/14_set.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) セットは集合を表し、データ構造的には重複、順序のない配列です。 diff --git a/doc/JA/syntax/15_type.md b/doc/JA/syntax/15_type.md index 40df551e..f8dd29da 100644 --- a/doc/JA/syntax/15_type.md +++ b/doc/JA/syntax/15_type.md @@ -1,6 +1,5 @@ # 型 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/15_type.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/15_type.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 型はErgにおいて非常に重要な機能ですので、[専用のセクション](./type/01_type_system.md)を用意しています。そちらをご覧ください。 diff --git a/doc/JA/syntax/16_iterator.md b/doc/JA/syntax/16_iterator.md index 3923a415..b9a3bf83 100644 --- a/doc/JA/syntax/16_iterator.md +++ b/doc/JA/syntax/16_iterator.md @@ -1,6 +1,5 @@ # イテレータ -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/16_iterator.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/16_iterator.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) イテレータは、コンテナの要素を取り出すためのオブジェクトです。 diff --git a/doc/JA/syntax/17_mutability.md b/doc/JA/syntax/17_mutability.md index 344f0ebe..5f9a3ad9 100644 --- a/doc/JA/syntax/17_mutability.md +++ b/doc/JA/syntax/17_mutability.md @@ -1,6 +1,5 @@ # Mutability -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/17_mutability.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/17_mutability.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) すでに見たように、Ergの変数は全て不変です。しかし、Ergのオブジェクトには可変性という概念があります。 以下のコードを例にします。 diff --git a/doc/JA/syntax/18_ownership.md b/doc/JA/syntax/18_ownership.md index 488a4119..302d17b6 100644 --- a/doc/JA/syntax/18_ownership.md +++ b/doc/JA/syntax/18_ownership.md @@ -1,6 +1,5 @@ # 所有権システム -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/18_ownership.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/18_ownership.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ErgはPythonをホスト言語にした言語であるため、メモリ管理の方法はPythonの処理系に依存しています。 しかし、意味論的にはErgのメモリ管理はPythonのそれとは別物です。顕著な違いは、所有権システムと循環参照の禁止に現れています。 diff --git a/doc/JA/syntax/19_visibility.md b/doc/JA/syntax/19_visibility.md index e87577d2..72309793 100644 --- a/doc/JA/syntax/19_visibility.md +++ b/doc/JA/syntax/19_visibility.md @@ -1,6 +1,5 @@ # 可視性(Visibility) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/19_visibility.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/19_visibility.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Ergの変数には __可視性__ という概念が存在します。 今まで見てきた変数は全て __プライベート変数(非公開変数)__ と呼ばれます。これは、外部から不可視の変数です。 diff --git a/doc/JA/syntax/20_naming_rule.md b/doc/JA/syntax/20_naming_rule.md index f10fe869..78f39931 100644 --- a/doc/JA/syntax/20_naming_rule.md +++ b/doc/JA/syntax/20_naming_rule.md @@ -1,6 +1,5 @@ # 命名規則 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/20_naming_rule.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/20_naming_rule.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 変数を定数式として使いたい場合は、必ず大文字で始めます。二文字以降は小文字でもよいです。 diff --git a/doc/JA/syntax/21_lambda.md b/doc/JA/syntax/21_lambda.md index a2933310..fa1ae96b 100644 --- a/doc/JA/syntax/21_lambda.md +++ b/doc/JA/syntax/21_lambda.md @@ -1,6 +1,5 @@ # 無名関数(anonymous function) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/21_lambda.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/21_lambda.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 無名関数は、関数オブジェクトを名付けずその場で生成するための文法です。 diff --git a/doc/JA/syntax/22_subroutine.md b/doc/JA/syntax/22_subroutine.md index 6d08929d..7ea16d94 100644 --- a/doc/JA/syntax/22_subroutine.md +++ b/doc/JA/syntax/22_subroutine.md @@ -1,6 +1,5 @@ # Subroutine signatures -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/22_subroutine.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/22_subroutine.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## Func diff --git a/doc/JA/syntax/23_closure.md b/doc/JA/syntax/23_closure.md index eb9d89a1..bf4f8bd0 100644 --- a/doc/JA/syntax/23_closure.md +++ b/doc/JA/syntax/23_closure.md @@ -1,6 +1,5 @@ # クロージャ -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/23_closure.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/23_closure.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Ergのサブルーチンには、外部変数を捕捉する「クロージャ」という機能があります。 diff --git a/doc/JA/syntax/24_module.md b/doc/JA/syntax/24_module.md index e857c43d..abc00723 100644 --- a/doc/JA/syntax/24_module.md +++ b/doc/JA/syntax/24_module.md @@ -1,6 +1,5 @@ # モジュール -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/24_module.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/24_module.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Ergでは、ファイル自体を1つのレコードとみなすことができます。これをモジュールと呼びます。 diff --git a/doc/JA/syntax/25_object_system.md b/doc/JA/syntax/25_object_system.md index 2d903ea8..75a967e8 100644 --- a/doc/JA/syntax/25_object_system.md +++ b/doc/JA/syntax/25_object_system.md @@ -1,6 +1,5 @@ # Object(対象体) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/25_object_system.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/25_object_system.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 変数に代入できる全てのデータです。`Object`クラスの持つ属性は以下の通りです。 diff --git a/doc/JA/syntax/26_pattern_matching.md b/doc/JA/syntax/26_pattern_matching.md index 92dca505..d6d9bd23 100644 --- a/doc/JA/syntax/26_pattern_matching.md +++ b/doc/JA/syntax/26_pattern_matching.md @@ -1,6 +1,5 @@ # パターンマッチ、論駁可能性 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/26_pattern_matching.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/26_pattern_matching.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## Ergで使用可能なパターン diff --git a/doc/JA/syntax/27_comprehension.md b/doc/JA/syntax/27_comprehension.md index 9adfe66a..99312cb0 100644 --- a/doc/JA/syntax/27_comprehension.md +++ b/doc/JA/syntax/27_comprehension.md @@ -1,6 +1,5 @@ # Comprehension(内包表記) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/27_comprehension.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/27_comprehension.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) `[expr | (name <- iterable)+ (predicate)*]`で配列、 `{expr | (name <- iterable)+ (predicate)*}`でセット、 diff --git a/doc/JA/syntax/28_spread_syntax.md b/doc/JA/syntax/28_spread_syntax.md index 13ba1160..e5bcdfa8 100644 --- a/doc/JA/syntax/28_spread_syntax.md +++ b/doc/JA/syntax/28_spread_syntax.md @@ -1,6 +1,5 @@ # Spread assignment (展開代入) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/28_spread_syntax.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/28_spread_syntax.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 分解代入において、変数の前に`...`を置くと残りの要素を全てその変数に展開できます。これを展開代入と呼びます。 diff --git a/doc/JA/syntax/29_decorator.md b/doc/JA/syntax/29_decorator.md index 713a95a1..ed9f1705 100644 --- a/doc/JA/syntax/29_decorator.md +++ b/doc/JA/syntax/29_decorator.md @@ -1,6 +1,5 @@ # デコレータ(修飾子) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/29_decorator.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/29_decorator.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) デコレータは型や関数に特定の状態や振る舞いを追加したり明示するために使われます。 デコレータの文法は以下の通りです。 diff --git a/doc/JA/syntax/30_error_handling.md b/doc/JA/syntax/30_error_handling.md index 76602cdf..e8713e96 100644 --- a/doc/JA/syntax/30_error_handling.md +++ b/doc/JA/syntax/30_error_handling.md @@ -1,6 +1,5 @@ # エラーハンドリングシステム -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/30_error_handling.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/30_error_handling.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 主にResult型を使用します。 ErgではError型オブジェクトを捨てる(トップレベルで対応しない)とエラーが発生します。 diff --git a/doc/JA/syntax/31_pipeline.md b/doc/JA/syntax/31_pipeline.md index d2e6f8df..7faf14a2 100644 --- a/doc/JA/syntax/31_pipeline.md +++ b/doc/JA/syntax/31_pipeline.md @@ -1,6 +1,5 @@ # パイプライン演算子 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/31_pipeline.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/31_pipeline.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) パイプライン演算子は、次のように使います。 diff --git a/doc/JA/syntax/32_integration_with_Python.md b/doc/JA/syntax/32_integration_with_Python.md index dfe3dcfd..438ecd45 100644 --- a/doc/JA/syntax/32_integration_with_Python.md +++ b/doc/JA/syntax/32_integration_with_Python.md @@ -1,6 +1,5 @@ # Pythonとの連携 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/32_integration_with_Python.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/32_integration_with_Python.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## Pythonへのexport diff --git a/doc/JA/syntax/33_package_system.md b/doc/JA/syntax/33_package_system.md index 68ff74ea..b9e46e10 100644 --- a/doc/JA/syntax/33_package_system.md +++ b/doc/JA/syntax/33_package_system.md @@ -1,6 +1,5 @@ # パッケージシステム -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/33_package_system.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/33_package_system.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Ergのパッケージはアプリケーションであるappパッケージとライブラリであるlibパッケージに大別できます。 appパッケージのエントリポイントは`src/app.er`です。`app.er`内に定義された`main`関数が実行されます。 diff --git a/doc/JA/syntax/34_generator.md b/doc/JA/syntax/34_generator.md index c4bd6282..868412a2 100644 --- a/doc/JA/syntax/34_generator.md +++ b/doc/JA/syntax/34_generator.md @@ -1,6 +1,5 @@ # ジェネレータ -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/34_generator.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/34_generator.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ジェネレータは、ブロック中で`yield!`プロシージャを使う特殊なプロシージャです。 diff --git a/doc/JA/syntax/SUMMARY.md b/doc/JA/syntax/SUMMARY.md index de5dfd3d..3c2772e9 100644 --- a/doc/JA/syntax/SUMMARY.md +++ b/doc/JA/syntax/SUMMARY.md @@ -1,6 +1,5 @@ # Summary -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/SUMMARY.md%26commit_hash%3D2ce482b1c8407332b3b74f4c3e5596f373f9a657)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/SUMMARY.md&commit_hash=2ce482b1c8407332b3b74f4c3e5596f373f9a657) - [Basics](./00_basic.md) - [Literal](./01_literal.md) diff --git a/doc/JA/syntax/container_ownership.md b/doc/JA/syntax/container_ownership.md index 0d01d0cd..28ce256d 100644 --- a/doc/JA/syntax/container_ownership.md +++ b/doc/JA/syntax/container_ownership.md @@ -1,6 +1,5 @@ # Subscript(添字アクセス) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/34_generator.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/34_generator.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) `[]`は通常のメソッドとは異なっています。 diff --git a/doc/JA/syntax/indexes.md b/doc/JA/syntax/indexes.md index 748cc676..7c56e81c 100644 --- a/doc/JA/syntax/indexes.md +++ b/doc/JA/syntax/indexes.md @@ -1,6 +1,5 @@ # 索引 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/indexes.md%26commit_hash%3D592671af96ff3f517746841e55b8bc835b39af3a)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/indexes.md&commit_hash=592671af96ff3f517746841e55b8bc835b39af3a) この索引にないAPIについては[こちら](../API/index.md)を参照してください。 用語の意味については[こちら](../dev_guide/terms.md)を参照。 diff --git a/doc/JA/syntax/quick_tour.md b/doc/JA/syntax/quick_tour.md index 38d7b23a..18944eae 100644 --- a/doc/JA/syntax/quick_tour.md +++ b/doc/JA/syntax/quick_tour.md @@ -1,6 +1,5 @@ # Quick Tour -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/34_generator.md%26commit_hash%3D7d43acdf0e2b71528b038b9a8e70be6c93831f96)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/quick_tour.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96) `syntax`以下のドキュメントは、概ねプログラミング初心者でも理解できることを目指して書かれています。 すでにPythonやRust, Haskellなどの言語を習得されている方にとっては、少し冗長であるかもしれません。 diff --git a/doc/JA/syntax/type/01_type_system.md b/doc/JA/syntax/type/01_type_system.md index 050aea15..9803c681 100644 --- a/doc/JA/syntax/type/01_type_system.md +++ b/doc/JA/syntax/type/01_type_system.md @@ -1,6 +1,5 @@ # Ergの型システム -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/01_type_system.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/01_type_system.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 以下では、Ergの型システムを概略的に説明します。詳細については他の項で解説します。 diff --git a/doc/JA/syntax/type/02_basic.md b/doc/JA/syntax/type/02_basic.md index dea4a974..49ec720d 100644 --- a/doc/JA/syntax/type/02_basic.md +++ b/doc/JA/syntax/type/02_basic.md @@ -1,6 +1,5 @@ # 型に関する基本的な文法 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/02_basic.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/02_basic.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## 型指定 diff --git a/doc/JA/syntax/type/03_trait.md b/doc/JA/syntax/type/03_trait.md index 2854b5b3..d5ac7550 100644 --- a/doc/JA/syntax/type/03_trait.md +++ b/doc/JA/syntax/type/03_trait.md @@ -1,6 +1,5 @@ # トレイト -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/03_trait.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/03_trait.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) トレイトは、レコード型に型属性の要求を追加した記名型です。 Pythonでいう抽象基底クラス(Abstract Base Class, ABC)に類似しますが、代数的演算を行えるという特徴があります。 diff --git a/doc/JA/syntax/type/04_class.md b/doc/JA/syntax/type/04_class.md index 20c6f42e..ea41ff0d 100644 --- a/doc/JA/syntax/type/04_class.md +++ b/doc/JA/syntax/type/04_class.md @@ -1,6 +1,5 @@ # Class -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/04_class.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/04_class.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Ergにおけるクラスは、大まかには自身の要素(インスタンス)を生成できる型と言えます。 以下は単純なクラスの例です。 diff --git a/doc/JA/syntax/type/05_inheritance.md b/doc/JA/syntax/type/05_inheritance.md index 15df7fbc..4722b60a 100644 --- a/doc/JA/syntax/type/05_inheritance.md +++ b/doc/JA/syntax/type/05_inheritance.md @@ -1,6 +1,5 @@ # 継承(Inheritance) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/05_inheritance.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/05_inheritance.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 継承を使うと、既存のクラスに機能を加えたり特化したりした新しいクラスを定義できます。 継承はトレイトにおける包摂に似ています。継承してできたクラスは、もとのクラスのサブタイプになります。 diff --git a/doc/JA/syntax/type/06_nst_vs_sst.md b/doc/JA/syntax/type/06_nst_vs_sst.md index 953bb1dd..7643a49d 100644 --- a/doc/JA/syntax/type/06_nst_vs_sst.md +++ b/doc/JA/syntax/type/06_nst_vs_sst.md @@ -1,6 +1,5 @@ # 記名的部分型 vs. 構造的部分型 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/06_nst_vs_sst.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/06_nst_vs_sst.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ```python Months = 0..12 diff --git a/doc/JA/syntax/type/07_patch.md b/doc/JA/syntax/type/07_patch.md index fac491be..5bf1b40e 100644 --- a/doc/JA/syntax/type/07_patch.md +++ b/doc/JA/syntax/type/07_patch.md @@ -1,6 +1,5 @@ # Patch -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/07_patch.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/07_patch.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Ergでは、既存の型・クラスに手を加えることはできません。 クラスにメソッドを追加で定義することはできず、特殊化(specialization, 多相に宣言された型を単相化し専用のメソッドを定義する機能。C++などが持つ)も行えません。 diff --git a/doc/JA/syntax/type/08_value.md b/doc/JA/syntax/type/08_value.md index 438f60da..ad50a386 100644 --- a/doc/JA/syntax/type/08_value.md +++ b/doc/JA/syntax/type/08_value.md @@ -1,6 +1,5 @@ # 値型(Value types) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/08_value.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/08_value.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 値型はErg組み込み型のうちコンパイル時評価が可能な型で、具体的には以下のものです。 diff --git a/doc/JA/syntax/type/09_attributive.md b/doc/JA/syntax/type/09_attributive.md index b57a8f09..c9d470b6 100644 --- a/doc/JA/syntax/type/09_attributive.md +++ b/doc/JA/syntax/type/09_attributive.md @@ -1,6 +1,5 @@ # 属性型(Attributive Type) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/09_attributive.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/09_attributive.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 属性型は、レコードおよびデータクラス、パッチ、モジュールなどが含まれる型です。 属性型に属する型は値型ではありません。 diff --git a/doc/JA/syntax/type/10_interval.md b/doc/JA/syntax/type/10_interval.md index 84e4127d..4786c8f4 100644 --- a/doc/JA/syntax/type/10_interval.md +++ b/doc/JA/syntax/type/10_interval.md @@ -1,6 +1,5 @@ # Interval Type -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/10_interval.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/10_interval.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) `Range`オブジェクトの最も基本的な使い方は、イテレータとしての使用です。 diff --git a/doc/JA/syntax/type/11_enum.md b/doc/JA/syntax/type/11_enum.md index 12e9ba23..3decde83 100644 --- a/doc/JA/syntax/type/11_enum.md +++ b/doc/JA/syntax/type/11_enum.md @@ -1,6 +1,5 @@ # Enumerative Type(列挙型) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/11_enum.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/11_enum.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 列挙型(Enum type)はSetによって生成されます。 列挙型はそのままでも型指定で使えますが、クラス化したりパッチを定義することで更にメソッドを定義できます。 diff --git a/doc/JA/syntax/type/12_refinement.md b/doc/JA/syntax/type/12_refinement.md index fc4045af..24a1a7ca 100644 --- a/doc/JA/syntax/type/12_refinement.md +++ b/doc/JA/syntax/type/12_refinement.md @@ -1,6 +1,5 @@ # 篩型(Refinement Type) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/12_refinement.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/12_refinement.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Refinement type(篩型、ふるいがた)は、述語式によって制約付けられた型です。列挙型や区間型は篩型の一種です。 diff --git a/doc/JA/syntax/type/13_algebraic.md b/doc/JA/syntax/type/13_algebraic.md index fac8c3f8..bf7e2c04 100644 --- a/doc/JA/syntax/type/13_algebraic.md +++ b/doc/JA/syntax/type/13_algebraic.md @@ -1,6 +1,5 @@ # Algebraic type (代数演算型) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/13_algebraic.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/13_algebraic.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 代数演算型は、型を代数のようにみなして演算することで生成される型のことです。 代数演算型が扱う演算は、Union, Intersection, Diff, Complementなどがあります。 diff --git a/doc/JA/syntax/type/14_dependent.md b/doc/JA/syntax/type/14_dependent.md index fce744d3..ba923522 100644 --- a/doc/JA/syntax/type/14_dependent.md +++ b/doc/JA/syntax/type/14_dependent.md @@ -1,6 +1,5 @@ # 依存型 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/14_dependent.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/14_dependent.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 依存型はErgの最大の特徴とも言っても良い機能です。 依存型とは、値を引数に取る型です。通常の多相型は型のみを引数に取れますが、その制限を緩めたのが依存型といえます。 diff --git a/doc/JA/syntax/type/15_quantified.md b/doc/JA/syntax/type/15_quantified.md index 86599bd7..c5dd0f2a 100644 --- a/doc/JA/syntax/type/15_quantified.md +++ b/doc/JA/syntax/type/15_quantified.md @@ -1,6 +1,5 @@ # 型変数(Type Variable)、量化型 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/15_quantified.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/15_quantified.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 型変数はサブルーチン引数の型指定などに使用する変数で、その型が任意である(単相化しない)ことを示します。 まず、型変数を導入するモチベーションとして、入力をそのまま返す`id`関数について考えましょう。 diff --git a/doc/JA/syntax/type/16_subtyping.md b/doc/JA/syntax/type/16_subtyping.md index fc2c1dd7..d425f6fd 100644 --- a/doc/JA/syntax/type/16_subtyping.md +++ b/doc/JA/syntax/type/16_subtyping.md @@ -1,6 +1,5 @@ # 部分型付け -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/16_subtyping.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/16_subtyping.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Ergでは、クラス同士の包含関係は比較演算子`<`, `>`で判定可能です。 diff --git a/doc/JA/syntax/type/17_type_casting.md b/doc/JA/syntax/type/17_type_casting.md index df15efd6..24046b67 100644 --- a/doc/JA/syntax/type/17_type_casting.md +++ b/doc/JA/syntax/type/17_type_casting.md @@ -1,6 +1,5 @@ # キャスト -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/17_type_casting.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/17_type_casting.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## アップキャスト diff --git a/doc/JA/syntax/type/18_mut.md b/doc/JA/syntax/type/18_mut.md index 99bcc2f5..fbc3fd6c 100644 --- a/doc/JA/syntax/type/18_mut.md +++ b/doc/JA/syntax/type/18_mut.md @@ -1,6 +1,5 @@ # 可変型(Mutable Type) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/18_mut.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/18_mut.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) > __Warning__: この項の情報は古く、一部に間違いを含みます。 diff --git a/doc/JA/syntax/type/19_bound.md b/doc/JA/syntax/type/19_bound.md index 0fb2139f..2bc125a5 100644 --- a/doc/JA/syntax/type/19_bound.md +++ b/doc/JA/syntax/type/19_bound.md @@ -1,6 +1,5 @@ # 型境界 (Type Bound) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/19_bound.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/19_bound.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 型境界は型指定に条件を加えるものである。これを実現する機能がガード(ガード節)である。 関数シグニチャ、無名関数シグニチャのほか、篩型でもこの機能を利用できる。 diff --git a/doc/JA/syntax/type/advanced.md b/doc/JA/syntax/type/advanced.md index 38ee588e..11816bd0 100644 --- a/doc/JA/syntax/type/advanced.md +++ b/doc/JA/syntax/type/advanced.md @@ -1,3 +1,2 @@ 以降は更に高度な型システムを解説します。入門者の方はすべての項を読まなくても問題ありません。 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) diff --git a/doc/JA/syntax/type/advanced/GADTs.md b/doc/JA/syntax/type/advanced/GADTs.md index f6e0c639..40790c18 100644 --- a/doc/JA/syntax/type/advanced/GADTs.md +++ b/doc/JA/syntax/type/advanced/GADTs.md @@ -1,6 +1,5 @@ # 一般化代数的データ型(Generalized Algebraic Data Types, GADTs) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/GADTs.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/GADTs.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ErgはOr型をクラス化することで一般化代数的データ型(GADTs)を作成出来ます。 diff --git a/doc/JA/syntax/type/advanced/default_param.md b/doc/JA/syntax/type/advanced/default_param.md index 3d4af4ab..4e2568f1 100644 --- a/doc/JA/syntax/type/advanced/default_param.md +++ b/doc/JA/syntax/type/advanced/default_param.md @@ -1,6 +1,5 @@ # デフォルト引数付きの関数型 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/default_param.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/default_param.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) まず、デフォルト引数の使用例を見る。 diff --git a/doc/JA/syntax/type/advanced/erasure.md b/doc/JA/syntax/type/advanced/erasure.md index ea1cfdbb..fd41b4c5 100644 --- a/doc/JA/syntax/type/advanced/erasure.md +++ b/doc/JA/syntax/type/advanced/erasure.md @@ -1,6 +1,5 @@ # 型消去(Type erasure) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/erasure.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/erasure.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 型消去とは、型引数に`_`を指定し、その情報をあえて捨てることです。型消去は多相型を持つ言語の多くが併せて持つ機能ですが、Ergの文法に即して言えば型引数消去といった方が正確でしょう。 diff --git a/doc/JA/syntax/type/advanced/existential.md b/doc/JA/syntax/type/advanced/existential.md index cbcb2d04..b81cd7ea 100644 --- a/doc/JA/syntax/type/advanced/existential.md +++ b/doc/JA/syntax/type/advanced/existential.md @@ -1,6 +1,5 @@ # 存在型 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/existential.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/existential.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ∀に対応する全称型があるならば、∃に対応する存在型があると考えるのが自然です。 存在型は難しいものではありません。そうと意識していないだけで、既にあなたは存在型を知っています。 diff --git a/doc/JA/syntax/type/advanced/keyword_param.md b/doc/JA/syntax/type/advanced/keyword_param.md index 65f0a2e0..2fa54313 100644 --- a/doc/JA/syntax/type/advanced/keyword_param.md +++ b/doc/JA/syntax/type/advanced/keyword_param.md @@ -1,6 +1,5 @@ # キーワード引数付き関数型 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/keyword_param.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/keyword_param.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ```python h(f) = f(y: 1, x: 2) diff --git a/doc/JA/syntax/type/advanced/kind.md b/doc/JA/syntax/type/advanced/kind.md index ac11c63b..bfbce7e2 100644 --- a/doc/JA/syntax/type/advanced/kind.md +++ b/doc/JA/syntax/type/advanced/kind.md @@ -1,6 +1,5 @@ # カインド(Kind) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/kind.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/kind.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Ergでは全てが型付けられている。型自体も例外ではない。「型の型」を表すのが __カインド(種)__ である。例えば`1`が`Int`に属しているように、`Int`は`Type`に属している。`Type`は最もシンプルなカインドである __原子カインド(Atomic kind)__ である。型理論的の記法では、`Type`は`*`に対応する。 diff --git a/doc/JA/syntax/type/advanced/marker_trait.md b/doc/JA/syntax/type/advanced/marker_trait.md index c90e5497..d06105ac 100644 --- a/doc/JA/syntax/type/advanced/marker_trait.md +++ b/doc/JA/syntax/type/advanced/marker_trait.md @@ -1,6 +1,5 @@ # Marker Trait -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/marker_trait.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/marker_trait.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) マーカートレイトは、要求属性のないトレイトである。すなわち、メソッドを実装せずにImplすることができる。 要求属性がないと意味がないように思えるが、そのトレイトに属しているという情報が登録されるので、パッチメソッドを使ったり、コンパイラが特別扱いしたりできる。 diff --git a/doc/JA/syntax/type/advanced/mut_struct.md b/doc/JA/syntax/type/advanced/mut_struct.md index 317d50f1..3389c229 100644 --- a/doc/JA/syntax/type/advanced/mut_struct.md +++ b/doc/JA/syntax/type/advanced/mut_struct.md @@ -1,6 +1,5 @@ # 可変構造型 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/mut_struct.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/mut_struct.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) `T!`型は任意の`T`型オブジェクトを入れられて差し替え可能なボックス型であると説明した。 diff --git a/doc/JA/syntax/type/advanced/newtype.md b/doc/JA/syntax/type/advanced/newtype.md index 4d57cc88..f7703a5e 100644 --- a/doc/JA/syntax/type/advanced/newtype.md +++ b/doc/JA/syntax/type/advanced/newtype.md @@ -1,6 +1,5 @@ # Newtype pattern -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/newtype.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/newtype.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ここでは、Rustでよく使われるnewtypeパターンのErg版を紹介します。 diff --git a/doc/JA/syntax/type/advanced/overloading.md b/doc/JA/syntax/type/advanced/overloading.md index 7431ad9e..80cead4e 100644 --- a/doc/JA/syntax/type/advanced/overloading.md +++ b/doc/JA/syntax/type/advanced/overloading.md @@ -1,6 +1,5 @@ # オーバーロード -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/overloading.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/overloading.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Ergでは __アドホック多相__ をサポートしない。すなわち、関数・カインドの多重定義(オーバーロード)ができない。が、トレイトクラスとパッチを組み合わせることでオーバーロードの挙動を再現できる。 トレイトクラスのかわりにトレイトを使用しても良いが、その場合`.add1`を実装している型全てが対象になってしまう。 diff --git a/doc/JA/syntax/type/advanced/phantom.md b/doc/JA/syntax/type/advanced/phantom.md index fc5c79f3..15280cd7 100644 --- a/doc/JA/syntax/type/advanced/phantom.md +++ b/doc/JA/syntax/type/advanced/phantom.md @@ -1,6 +1,5 @@ # 幽霊型(Phantom class) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/phantom.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/phantom.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 幽霊型は、コンパイラに注釈を与えるためだけに存在するマーカートレイトである。 幽霊型の使い方として、リストの構成をみる。 diff --git a/doc/JA/syntax/type/advanced/projection.md b/doc/JA/syntax/type/advanced/projection.md index 8e353637..e12ef9ae 100644 --- a/doc/JA/syntax/type/advanced/projection.md +++ b/doc/JA/syntax/type/advanced/projection.md @@ -1,6 +1,5 @@ # Projection Type(射影型) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/projection.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/projection.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 射影型は、次のコードにおける`Self.AddO`のような型を表します。 diff --git a/doc/JA/syntax/type/advanced/quantified_dependent.md b/doc/JA/syntax/type/advanced/quantified_dependent.md index a9cd5b32..00a62c2d 100644 --- a/doc/JA/syntax/type/advanced/quantified_dependent.md +++ b/doc/JA/syntax/type/advanced/quantified_dependent.md @@ -1,6 +1,5 @@ # 量化依存型 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/quantified_dependent.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/quantified_dependent.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) Ergには量化型、依存型が存在します。すると当然、その二つを組み合わせた型を作ることができます。それが量化依存型です。 diff --git a/doc/JA/syntax/type/advanced/shared.md b/doc/JA/syntax/type/advanced/shared.md index b0c4df32..cb2dbaa1 100644 --- a/doc/JA/syntax/type/advanced/shared.md +++ b/doc/JA/syntax/type/advanced/shared.md @@ -1,6 +1,5 @@ # 共有参照(Shared Reference) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/shared.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/shared.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) 共有参照は気をつけて扱わねばならない言語機能の一つです。 例えばTypeScriptでは以下のようなコードが型検査を通ってしまいます。 diff --git a/doc/JA/syntax/type/advanced/special.md b/doc/JA/syntax/type/advanced/special.md index 89ed6b2f..b6cd401c 100644 --- a/doc/JA/syntax/type/advanced/special.md +++ b/doc/JA/syntax/type/advanced/special.md @@ -1,6 +1,5 @@ # 特殊型(Self, Super) -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/special.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/special.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) `Self`は自身の型を表します。単にエイリアスとして使うことも出来ますが、派生型中では意味が変わる(自身の型を指す)ので注意してください。 diff --git a/doc/JA/tips.md b/doc/JA/tips.md index d0a6da05..b21ca905 100644 --- a/doc/JA/tips.md +++ b/doc/JA/tips.md @@ -1,6 +1,5 @@ # Tips -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tips.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tips.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) ## エラーの表示言語を変えたい From fea61cc93bc4444a9cb8d7540f5959183031dfa2 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Mon, 5 Sep 2022 21:02:22 +0800 Subject: [PATCH 22/42] translate save --- doc/zh_CN/python/class_system.md | 6 +- doc/zh_CN/syntax/00_basic.md | 12 +- doc/zh_CN/syntax/02_name.md | 16 +- doc/zh_CN/syntax/03_declaration.md | 4 +- doc/zh_CN/syntax/04_function.md | 14 +- doc/zh_CN/syntax/06_operator.md | 4 +- doc/zh_CN/syntax/07_side_effect.md | 8 +- doc/zh_CN/syntax/08_procedure.md | 2 +- doc/zh_CN/syntax/10_array.md | 4 +- doc/zh_CN/syntax/11_tuple.md | 6 +- doc/zh_CN/syntax/12_dict.md | 2 +- doc/zh_CN/syntax/13_record.md | 14 +- doc/zh_CN/syntax/16_iterator.md | 6 +- doc/zh_CN/syntax/17_mutability.md | 4 +- doc/zh_CN/syntax/18_ownership.md | 2 +- doc/zh_CN/syntax/19_visibility.md | 6 +- doc/zh_CN/syntax/20_naming_rule.md | 2 +- doc/zh_CN/syntax/21_lambda.md | 2 +- doc/zh_CN/syntax/22_subroutine.md | 6 +- doc/zh_CN/syntax/25_object_system.md | 20 +- doc/zh_CN/syntax/26_pattern_matching.md | 8 +- doc/zh_CN/syntax/27_comprehension.md | 6 +- doc/zh_CN/syntax/29_decorator.md | 2 +- doc/zh_CN/syntax/30_error_handling.md | 12 +- doc/zh_CN/syntax/33_package_system.md | 4 +- doc/zh_CN/syntax/34_generator.md | 2 +- doc/zh_CN/syntax/SUMMARY.md | 132 ++--- doc/zh_CN/syntax/container_ownership.md | 6 +- doc/zh_CN/syntax/grammar.md | 2 +- doc/zh_CN/syntax/indexes.md | 520 +++++++++--------- doc/zh_CN/syntax/quick_tour.md | 124 ++--- doc/zh_CN/syntax/type/01_type_system.md | 32 +- doc/zh_CN/syntax/type/02_basic.md | 8 +- doc/zh_CN/syntax/type/03_trait.md | 4 +- doc/zh_CN/syntax/type/04_class.md | 24 +- doc/zh_CN/syntax/type/05_inheritance.md | 14 +- doc/zh_CN/syntax/type/06_nst_vs_sst.md | 2 +- doc/zh_CN/syntax/type/07_patch.md | 14 +- doc/zh_CN/syntax/type/11_enum.md | 2 +- doc/zh_CN/syntax/type/12_refinement.md | 6 +- doc/zh_CN/syntax/type/14_dependent.md | 4 +- doc/zh_CN/syntax/type/15_quantified.md | 26 +- doc/zh_CN/syntax/type/17_type_casting.md | 2 +- doc/zh_CN/syntax/type/18_mut.md | 12 +- doc/zh_CN/syntax/type/19_bound.md | 4 +- doc/zh_CN/syntax/type/advanced/_rank2type.md | 14 +- doc/zh_CN/syntax/type/advanced/erasure.md | 8 +- doc/zh_CN/syntax/type/advanced/kind.md | 8 +- doc/zh_CN/syntax/type/advanced/mut_struct.md | 4 +- doc/zh_CN/syntax/type/advanced/overloading.md | 4 +- doc/zh_CN/syntax/type/advanced/phantom.md | 4 +- doc/zh_CN/syntax/type/advanced/shared.md | 2 +- doc/zh_CN/syntax/type/advanced/special.md | 4 +- doc/zh_CN/syntax/type/advanced/typeof.md | 8 +- doc/zh_CN/syntax/type/advanced/variance.md | 12 +- doc/zh_CN/syntax/type/advanced/widening.md | 6 +- 56 files changed, 593 insertions(+), 593 deletions(-) diff --git a/doc/zh_CN/python/class_system.md b/doc/zh_CN/python/class_system.md index 68383b60..6623395d 100644 --- a/doc/zh_CN/python/class_system.md +++ b/doc/zh_CN/python/class_system.md @@ -1,10 +1,10 @@ -# Python 类系统(与 Erg 比较) +# Python 类系统(与 Erg 比较) ## 方法 方法可以被前向引用,但这不是一种特殊的技术。 这是因为动态检查方法的存在。 -(在 Erg 中,方法存在是静态检查的。对于前向引用,函数必须是常量。) +(在 Erg 中,方法存在是静态检查的。对于前向引用,函数必须是常量。) ```python >>> class C: @@ -45,7 +45,7 @@ Traceback (most recent call last): File "", line 1, in ", line 3, in g -类型错误:只能将str(不是“int”)连接到str +类型错误:只能将str(不是“int”)连接到str ``` Erg 静态检查与父类的一致性。 diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md index 1a86adf8..b640f7fc 100644 --- a/doc/zh_CN/syntax/00_basic.md +++ b/doc/zh_CN/syntax/00_basic.md @@ -1,9 +1,9 @@ # 基本 -> __Warning__:本文档不完整。 它未经校对(样式、正确链接、误译等)。 此外,Erg 的语法可能在版本 0.* 期间发生破坏性更改,并且文档可能没有相应更新。 请事先了解这一点。 -> 如果您在本文档中发现任何错误,请报告至 [此处的表单](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我们将不胜感激您的建议。 +> __Warning__:本文档不完整。 它未经校对(样式、正确链接、误译等)。 此外,Erg 的语法可能在版本 0.* 期间发生破坏性更改,并且文档可能没有相应更新。 请事先了解这一点。 +> 如果您在本文档中发现任何错误,请报告至 [此处的表单](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我们将不胜感激您的建议。 > -> [Erg原版(日文)](http://mtshiba.me/TheErgBook/) +> [Erg原版(日文)](http://mtshiba.me/TheErgBook/) 本文档描述 Erg 的基本语法。 [标准 API](./API/index.md) 和 [Erg 贡献者的内部文档](./dev_guide/index.md) 位于另一个目录中。 @@ -30,8 +30,8 @@ print!(f(x, y)) # OK print! f(x, y) # OK print! f(x, g y) # OK print! f x, y # NG, 可以理解为 `print!(f(x), y)` 或 `print!(f(x, y))` print! -print!(f x, y) # NG, 可以表示“print!(f(x),y)”或“print!(f(x,y))” -print! f(x, g y, z) # NG, 可以表示“print!(x,g(y),z)”或“print!(x,g(y,z))” +print!(f x, y) # NG, 可以表示“print!(f(x),y)”或“print!(f(x,y))” +print! f(x, g y, z) # NG, 可以表示“print!(x,g(y),z)”或“print!(x,g(y,z))” ``` ## 脚本 @@ -110,7 +110,7 @@ i = (x = 1; x + 1) # 语法错误:不能在括号中使用 `;` ## 缩进 -Erg 和 Python 一样,使用缩进来表示块。 有五个运算符(特殊形式)触发块的开始:`=`、`->`、`=>`、`do` 和 `do!`(此外,`:` 和 `|` ,虽然不是运算符,但也会产生缩进)。 每个的含义将在后面描述。 +Erg 和 Python 一样,使用缩进来表示块。 有五个运算符(特殊形式)触发块的开始:`=`、`->`、`=>`、`do` 和 `do!`(此外,`:` 和 `|` ,虽然不是运算符,但也会产生缩进)。 每个的含义将在后面描述。 ```python f x, y = diff --git a/doc/zh_CN/syntax/02_name.md b/doc/zh_CN/syntax/02_name.md index a4f8a26f..cbb0ef36 100644 --- a/doc/zh_CN/syntax/02_name.md +++ b/doc/zh_CN/syntax/02_name.md @@ -3,17 +3,17 @@ 变量是一种代数; Erg 中的代数 - 如果没有混淆,有时简称为变量 - 指的是命名对象并使它们可从代码的其他地方引用的功能。 变量定义如下。 -`n` 部分称为变量名(或标识符),`=` 是赋值运算符,`1` 部分是赋值。 +`n` 部分称为变量名(或标识符),`=` 是赋值运算符,`1` 部分是赋值。 ```python n = 1 ``` -以这种方式定义的“n”此后可以用作表示整数对象“1”的变量。 该系统称为分配(或绑定)。 -我们刚刚说过`1`是一个对象。 稍后我们将讨论对象是什么,但现在我们假设它是可以赋值的,即在赋值运算符的右侧(`=` 等)。 +以这种方式定义的“n”此后可以用作表示整数对象“1”的变量。 该系统称为分配(或绑定)。 +我们刚刚说过`1`是一个对象。 稍后我们将讨论对象是什么,但现在我们假设它是可以赋值的,即在赋值运算符的右侧(`=` 等)。 如果要指定变量的“类型”,请执行以下操作。 类型大致是一个对象所属的集合,后面会解释。 -这里我们指定`n`是自然数(`Nat`)类型。 +这里我们指定`n`是自然数(`Nat`)类型。 ```python n: Nat = 1 @@ -62,7 +62,7 @@ assert x == 0 ## 常量 常数也是一种代数。 如果标识符以大写字母开头,则将其视为常量。 它们被称为常量,因为一旦定义,它们就不会改变。 -`N` 部分称为常量名(或标识符)。 否则,它与变量相同。 +`N` 部分称为常量名(或标识符)。 否则,它与变量相同。 ```python N = 0 @@ -75,7 +75,7 @@ if True, do: 例如,常量用于数学常量、有关外部资源的信息和其他不可变值。 -除了 [types](./type/01_type_system.md) 之外的对象标识符使用全大写(所有字母大写的样式)是常见的做法。 +除了 [types](./type/01_type_system.md) 之外的对象标识符使用全大写(所有字母大写的样式)是常见的做法。 ```python PI = 3.141592653589793 @@ -102,7 +102,7 @@ X = !1 # 类型错误:无法定义 Int! 对象作为常量 ## 删除变量 -您可以使用 `Del` 函数删除变量。 依赖于变量的所有其他变量(即直接引用变量值的变量)也将被删除。 +您可以使用 `Del` 函数删除变量。 依赖于变量的所有其他变量(即直接引用变量值的变量)也将被删除。 ```python x = 1 @@ -114,7 +114,7 @@ assert f(2) == 3 Del x Del y, Z -f(2) # 名称错误:f 未定义(在第 6 行中删除) +f(2) # 名称错误:f 未定义(在第 6 行中删除) ``` 注意 `Del` 只能删除用户自定义模块中定义的变量。 无法删除诸如“True”之类的内置常量。 diff --git a/doc/zh_CN/syntax/03_declaration.md b/doc/zh_CN/syntax/03_declaration.md index 5dda32df..458c4097 100644 --- a/doc/zh_CN/syntax/03_declaration.md +++ b/doc/zh_CN/syntax/03_declaration.md @@ -1,4 +1,4 @@ -# 宣言(Declaration) +# 宣言(Declaration) 声明是用于指定要使用的变量类型的语法。 可以在代码中的任何地方进行声明,但单独的声明并不引用变量。 它们必须被初始化。 @@ -21,7 +21,7 @@ i: {2} i = (-1..10).sample! assert i in Nat # 这可能会通过 i: Int # 这会通过 -i: Nat # 这不会通过(-1 不是 Nat 的元素) +i: Nat # 这不会通过(-1 不是 Nat 的元素) ``` 函数可以用两种不同的方式声明。 diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md index 21c016cd..3dd6143c 100644 --- a/doc/zh_CN/syntax/04_function.md +++ b/doc/zh_CN/syntax/04_function.md @@ -11,7 +11,7 @@ add(x, y) = x + y 在函数名之后指定的名称称为参数。 相反,传递给函数的对象称为参数。 函数 `add` 是一个以 `x` 和 `y` 作为参数并返回它们之和的函数,`x + y`。 -可以按如下方式调用(应用/调用)定义的函数。 +可以按如下方式调用(应用/调用)定义的函数。 ```python add 1, 2 @@ -21,7 +21,7 @@ add(1, 2) ## 冒号应用风格 -函数像`f x, y, ...`一样被调用,但是如果单行参数太多,可以使用`:`(冒号)来应用它们。 +函数像`f x, y, ...`一样被调用,但是如果单行参数太多,可以使用`:`(冒号)来应用它们。 ```python f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4 @@ -82,7 +82,7 @@ f x: 当某些参数大部分是固定的并且您希望能够省略它们时,使用默认参数。 -默认参数由`:=`(walrus运算符)指定。 如果未指定 `base`,则将 `math.E` 分配给 `base`。 +默认参数由`:=`(walrus运算符)指定。 如果未指定 `base`,则将 `math.E` 分配给 `base`。 ```python math_log x: Ratio, base := math.E = ... @@ -107,7 +107,7 @@ math_log x, base: Ratio := math.E = ... f [x, y] := [1, 2] = ... ``` -但是,在默认参数中,不能调用过程(稍后描述)或分配可变对象 +但是,在默认参数中,不能调用过程(稍后描述)或分配可变对象 ```python f x := p! 1 = ... # NG @@ -121,7 +121,7 @@ f x := 1, y := x = ... # NG ## 可变长度参数 -输出其参数的日志(记录)的 `log` 函数可以采用任意数量的参数。 +输出其参数的日志(记录)的 `log` 函数可以采用任意数量的参数。 ```蟒蛇 记录“你好”、“世界”、“!” # 你好世界 ! @@ -156,7 +156,7 @@ fib 1 = 1 fib(n: Nat): Nat = fib(n - 1) + fib(n - 2) ``` -注意一个函数定义有多个模式不是所谓的重载(multiple definition); 一个函数只有一个定义。 在上面的示例中,“n”必须与“0”或“1”属于同一类型。 此外,与 `match` 一样,模式匹配是从上到下完成的。 +注意一个函数定义有多个模式不是所谓的重载(multiple definition); 一个函数只有一个定义。 在上面的示例中,“n”必须与“0”或“1”属于同一类型。 此外,与 `match` 一样,模式匹配是从上到下完成的。 如果不同类的实例混合在一起,最后一个定义必须指定函数参数的类型为`Or` @@ -224,7 +224,7 @@ factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ... ## 编译时函数 函数名以大写字母开头,表示编译时函数。 用户定义的编译时函数必须将所有参数作为常量,并且必须指定它们的类型。 -编译时函数的功能有限。 在编译时函数中只能使用常量表达式,即只有一些运算符(例如求积、比较和类型构造操作)和编译时函数。 要传递的参数也必须是常量表达式。 +编译时函数的功能有限。 在编译时函数中只能使用常量表达式,即只有一些运算符(例如求积、比较和类型构造操作)和编译时函数。 要传递的参数也必须是常量表达式。 作为回报,优点是计算可以在编译时完成。 ```python diff --git a/doc/zh_CN/syntax/06_operator.md b/doc/zh_CN/syntax/06_operator.md index 7f733b4a..a7c8955e 100644 --- a/doc/zh_CN/syntax/06_operator.md +++ b/doc/zh_CN/syntax/06_operator.md @@ -1,9 +1,9 @@ # 运算符 -运算符是表示操作的符号。 操作数是运算符(左)右侧的东西。 +运算符是表示操作的符号。 操作数是运算符(左)右侧的东西。 运算符是一种函数,因此它们本身就是可以绑定到变量的一流对象。 绑定时,需要用```括起来。 -对于`+`(和`-`),有一元和二元运算符,所以必须指定`_+_`(二元运算)/`+_`(一元运算)。 +对于`+`(和`-`),有一元和二元运算符,所以必须指定`_+_`(二元运算)/`+_`(一元运算)。 ```python add = `+` # 语法错误:指定 `_+_` 或 `+_` diff --git a/doc/zh_CN/syntax/07_side_effect.md b/doc/zh_CN/syntax/07_side_effect.md index bbae2ecd..3b7d414a 100644 --- a/doc/zh_CN/syntax/07_side_effect.md +++ b/doc/zh_CN/syntax/07_side_effect.md @@ -33,12 +33,12 @@ C!. ```python n = 1 s = n.into(Str) # '1' -n # 值错误:n 被 .into 移动(第 2 行) +n # 值错误:n 被 .into 移动(第 2 行) ``` 在任何给定时间,只有一种程序方法可以具有可变引用。 此外,在获取可变引用时,不能从原始对象获取更多可变引用。 从这个意义上说,`ref!` 会对`self` 产生副作用。 -但是请注意,可以从可变引用创建(不可变/可变)引用。 这允许在程序方法中递归和 `print!` 的`self`。 +但是请注意,可以从可变引用创建(不可变/可变)引用。 这允许在程序方法中递归和 `print!` 的`self`。 ```python T -> T # OK (move) @@ -59,7 +59,7 @@ T => Ref! 但是,对于那些想了解该语言的确切规范的人,以下是对副作用的更详细说明。 首先,必须声明返回值的等价与 Erg 中的副作用无关。 -有些过程对于任何给定的 `x` 都会导致 `p!(x) == p!(x)`(例如,总是返回 `None`),并且有些函数会导致 `f(x) ! = f(x)`。 +有些过程对于任何给定的 `x` 都会导致 `p!(x) == p!(x)`(例如,总是返回 `None`),并且有些函数会导致 `f(x) ! = f(x)`。 前者的一个例子是`print!`,后者的一个例子是下面的函数。 @@ -101,7 +101,7 @@ image = cam.shot!() n = ocr.read_num(image) # n = 3.141592 ``` -将“camera”模块视为为特定相机产品提供 API 的外部库,将“ocr”视为用于 OCR(光学字符识别)的库。 +将“camera”模块视为为特定相机产品提供 API 的外部库,将“ocr”视为用于 OCR(光学字符识别)的库。 直接的副作用是由 `cam.shot!()` 引起的,但显然这些信息是从 `f` 泄露的。 因此,`print!` 本质上不可能是一个函数。 然而,在某些情况下,您可能希望临时检查函数中的值,而不想为此目的在相关函数中添加 `!`。 在这种情况下,可以使用 `log` 函数。 diff --git a/doc/zh_CN/syntax/08_procedure.md b/doc/zh_CN/syntax/08_procedure.md index a9a9652e..3ce9e05a 100644 --- a/doc/zh_CN/syntax/08_procedure.md +++ b/doc/zh_CN/syntax/08_procedure.md @@ -1,7 +1,7 @@ # 程序 处理可变对象时需要过程,但将可变对象作为参数并不一定使其成为过程。 -这是一个函数接受一个可变对象(不是过程)。 +这是一个函数接受一个可变对象(不是过程)。 ```python peek_str s: Str! = log s diff --git a/doc/zh_CN/syntax/10_array.md b/doc/zh_CN/syntax/10_array.md index cecdeb58..c77cc7cd 100644 --- a/doc/zh_CN/syntax/10_array.md +++ b/doc/zh_CN/syntax/10_array.md @@ -1,6 +1,6 @@ # Array -数组是最基本的__collection(聚合)__。 +数组是最基本的__collection(聚合)__。 集合是一个可以在其中包含多个对象的对象。 ```python @@ -41,7 +41,7 @@ assert l[1..1] == [2] assert l[..].step(2) == [2, 4] ``` -通过切片获得的对象是数组的(不可变的)副本 +通过切片获得的对象是数组的(不可变的)副本 ```python print! Typeof l[1..2] # [Int; 4] diff --git a/doc/zh_CN/syntax/11_tuple.md b/doc/zh_CN/syntax/11_tuple.md index 4548eca3..95f2502a 100644 --- a/doc/zh_CN/syntax/11_tuple.md +++ b/doc/zh_CN/syntax/11_tuple.md @@ -10,7 +10,7 @@ assert(i == 1 and b == True and s == "a") ``` 元组`t`可以以`t.n`的形式检索第n个元素; 请注意,与 Python 不同,它不是 `t[n]`。 -这是因为访问元组元素更像是一个属性(在编译时检查元素的存在,并且类型可以根据 `n` 改变)而不是方法(数组的 `[]` 是一种方法)。 +这是因为访问元组元素更像是一个属性(在编译时检查元素的存在,并且类型可以根据 `n` 改变)而不是方法(数组的 `[]` 是一种方法)。 ```python assert t.0 == 1 @@ -35,7 +35,7 @@ t: (Int; 3) = (1, 2, 3) assert (Int; 3) == (Int, Int, Int) ``` -但是,非同质集合(如元组)可以通过向上转换、相交等方式转换为同质集合(如数组)。 +但是,非同质集合(如元组)可以通过向上转换、相交等方式转换为同质集合(如数组)。 这称为均衡。 ```python @@ -77,7 +77,7 @@ p!: () => () ``` 但是,在这种情况下,Python 倾向于使用“无”而不是单位。 -在 Erg 中,当您从一开始就确定操作不会返回有意义的值(例如在过程中)时,您应该使用 `()`,并且当操作可能失败并且您可能会返回 `None` 将一无所获,例如在检索元素时。 +在 Erg 中,当您从一开始就确定操作不会返回有意义的值(例如在过程中)时,您应该使用 `()`,并且当操作可能失败并且您可能会返回 `None` 将一无所获,例如在检索元素时。 ## 参数和元组 diff --git a/doc/zh_CN/syntax/12_dict.md b/doc/zh_CN/syntax/12_dict.md index 747b27e6..08938fcd 100644 --- a/doc/zh_CN/syntax/12_dict.md +++ b/doc/zh_CN/syntax/12_dict.md @@ -10,7 +10,7 @@ assert ids["Alice"] == 145 如果键是“哈希”对象,则键不必是字符串。 ```python -# 不推荐使用范围对象作为键(与切片混淆) +# 不推荐使用范围对象作为键(与切片混淆) r = {1..3: "1~3", 4..6: "4~6", 7..9: "7~9"} assert r[1..3] == "1~3" l = {[]: "empty", [1]: "1"} diff --git a/doc/zh_CN/syntax/13_record.md b/doc/zh_CN/syntax/13_record.md index e855b998..2990ed55 100644 --- a/doc/zh_CN/syntax/13_record.md +++ b/doc/zh_CN/syntax/13_record.md @@ -1,7 +1,7 @@ # 记录(Record) 记录是一个集合,它结合了通过键访问的 Dict 和在编译时检查其访问的元组的属性。 -如果您了解 JavaScript,请将其视为一种(更增强的)对象字面量表示法。 +如果您了解 JavaScript,请将其视为一种(更增强的)对象字面量表示法。 ```python john = {.name = "John"; .age = 21} @@ -52,7 +52,7 @@ o.inc!() assert o.i == 1 ``` -关于记录有一个值得注意的语法。 当记录的所有属性值都是类(不是结构类型)时,记录本身表现为一个类型,其自身的属性作为必需属性。 +关于记录有一个值得注意的语法。 当记录的所有属性值都是类(不是结构类型)时,记录本身表现为一个类型,其自身的属性作为必需属性。 这种类型称为记录类型。 有关详细信息,请参阅 [记录] 部分。 ```python @@ -132,10 +132,10 @@ empty_record: Structural {=} {x = 3; y = 5}: Structural {=} ``` -空记录不同于空 Dict `{:}` 或空集 `{}`。 特别要注意的是,它与 `{}` 的含义相反(在 Python 中,`{}` 是一个空字典,而在 Erg 中它是 Erg 中的 `!{:}`)。 +空记录不同于空 Dict `{:}` 或空集 `{}`。 特别要注意的是,它与 `{}` 的含义相反(在 Python 中,`{}` 是一个空字典,而在 Erg 中它是 Erg 中的 `!{:}`)。 作为枚举类型,`{}` 是一个空类型,其元素中不包含任何内容。 `Never` 类型是这种类型的一个分类。 相反,记录类 `{=}` 没有必需的实例属性,因此所有对象都是它的元素。 `Object` 是 this 的别名。 -一个`Object`(`Object`的一个补丁)是`的一个元素。 __sizeof__` 和其他非常基本的提供方法。 +一个`Object`(`Object`的一个补丁)是`的一个元素。 __sizeof__` 和其他非常基本的提供方法。 ```python AnyPatch = Patch Structural {=} @@ -147,7 +147,7 @@ Never = Class {} 请注意,没有其他类型或类在结构上与 `{}`、`Never` 类型等效,如果用户在右侧使用 `{}`、`Class {}` 定义类型,则会出错。 这意味着,例如,`1..10 或 -10。 -1`,但 `1..10 和 -10... -1`。 例如,当它应该是 1..10 或 -10...-1 时是 `-1`。 -此外,如果您定义的类型(例如 `Int 和 Str`)会导致组合 `Object`,则会警告您只需将其设置为 `Object`。 +此外,如果您定义的类型(例如 `Int 和 Str`)会导致组合 `Object`,则会警告您只需将其设置为 `Object`。 ## 即时封锁 @@ -166,7 +166,7 @@ y = ## 数据类 -如果您尝试自己实现方法,则必须直接在实例中定义裸记录(由记录文字生成的记录)。 +如果您尝试自己实现方法,则必须直接在实例中定义裸记录(由记录文字生成的记录)。 这是低效的,并且随着属性数量的增加,错误消息等变得难以查看和使用。 ```python @@ -177,7 +177,7 @@ john = { .inc_age! ref! self = self::age.update! x -> x + 1 } john + 1 -# 类型错误:{name = Str; 没有实现 + 年龄=诠释; 。迎接! =参考(自我)。 () => 无; inc_age! =参考! () => 无}, 整数 +# 类型错误:{name = Str; 没有实现 + 年龄=诠释; 。迎接! =参考(自我)。 () => 无; inc_age! =参考! () => 无}, 整数 ``` 因此,在这种情况下,您可以继承一个记录类。 这样的类称为数据类。 diff --git a/doc/zh_CN/syntax/16_iterator.md b/doc/zh_CN/syntax/16_iterator.md index 57121153..a2733c5c 100644 --- a/doc/zh_CN/syntax/16_iterator.md +++ b/doc/zh_CN/syntax/16_iterator.md @@ -8,7 +8,7 @@ for! 0..9, i => ``` 此代码打印数字 0 到 9。 -每个数字(=Int 对象)都分配给`i`,并执行以下操作(=`print!i`)。 这种重复执行称为__iteration__。 +每个数字(=Int 对象)都分配给`i`,并执行以下操作(=`print!i`)。 这种重复执行称为__iteration__。 现在让我们看看 `for!` 过程的类型签名。 @@ -27,7 +27,7 @@ Iterable T = Trait { } ``` -`.Iterator` 属性的类型 `{Iterator}` 是所谓的 set-kind(kind 在 [here](./type/advanced/kind.md) 中描述) +`.Iterator` 属性的类型 `{Iterator}` 是所谓的 set-kind(kind 在 [here](./type/advanced/kind.md) 中描述) ```python assert [1, 2, 3] in Iterable(Int) @@ -78,7 +78,7 @@ classDiagram Range <-- RangeIterator ``` -诸如 `Iterable` 之类的以静态分派但统一的方式提供用于处理特征(在本例中为 `Iterator`)的接口的类型称为伴生类适配器。 +诸如 `Iterable` 之类的以静态分派但统一的方式提供用于处理特征(在本例中为 `Iterator`)的接口的类型称为伴生类适配器。 --- diff --git a/doc/zh_CN/syntax/17_mutability.md b/doc/zh_CN/syntax/17_mutability.md index 7dff9f30..25145f88 100644 --- a/doc/zh_CN/syntax/17_mutability.md +++ b/doc/zh_CN/syntax/17_mutability.md @@ -84,7 +84,7 @@ match! x: 让我们理清一些与 Erg 中的变量相关的术语。 -变量是一种为对象赋予名称以便可以重用(或指向该名称)的机制。 +变量是一种为对象赋予名称以便可以重用(或指向该名称)的机制。 标识符是指定变量的语法元素。 符号是表示名称的语法元素、记号。 @@ -95,7 +95,7 @@ match! x: `x[y]` 形式的标识符称为下标访问器。 变量和标识符之间的区别在于,如果我们在 Erg 的语法理论意义上谈论变量,则两者实际上是相同的。 -在 C 中,类型和函数不能分配给变量; int 和 main 是标识符,而不是变量(严格来说可以赋值,但有限制)。 +在 C 中,类型和函数不能分配给变量; int 和 main 是标识符,而不是变量(严格来说可以赋值,但有限制)。 然而,在尔格语中,“一切都是对象”。不仅函数和类型,甚至运算符都可以分配给变量。

diff --git a/doc/zh_CN/syntax/18_ownership.md b/doc/zh_CN/syntax/18_ownership.md index 6f432ae4..0f473a8f 100644 --- a/doc/zh_CN/syntax/18_ownership.md +++ b/doc/zh_CN/syntax/18_ownership.md @@ -91,7 +91,7 @@ steal_str ref(s: Str!) = ```python steal_str ref(s: Str!) = - # 这也不好(=消耗右边) + # 这也不好(=消耗右边) x = s # OwnershipError: 不能消费借来的值 x ``` diff --git a/doc/zh_CN/syntax/19_visibility.md b/doc/zh_CN/syntax/19_visibility.md index d0af6a68..0e79c0e0 100644 --- a/doc/zh_CN/syntax/19_visibility.md +++ b/doc/zh_CN/syntax/19_visibility.md @@ -29,7 +29,7 @@ foo = import "foo" assert foo.x == "this is a visible variable" ``` -您不需要向私有变量添加任何内容,但您也可以添加 `::` 或 `self::`(用于类型等的`Self::`)以表明它们是私有的。 增加。 如果它是一个模块,它也可以是 `module::` +您不需要向私有变量添加任何内容,但您也可以添加 `::` 或 `self::`(用于类型等的`Self::`)以表明它们是私有的。 增加。 如果它是一个模块,它也可以是 `module::` ```python ::x = "this is an invisible variable" @@ -79,7 +79,7 @@ f1# 0 1 x = 0 C = Class {x = Int} C. - # 顶级 x 被引用(警告使用 module::x) + # 顶级 x 被引用(警告使用 module::x) f1 self = x # 实例属性 x 被引用 f2 self = self::x @@ -118,7 +118,7 @@ Foo. {Foo; ...} = import "foo" foo = Foo.new() -foo.public() # 属性错误:“Foo”没有属性“public”(“public”在模块“bar”中定义) +foo.public() # 属性错误:“Foo”没有属性“public”(“public”在模块“bar”中定义) ``` 此外,方法不能在要重新导出的类型中定义。 diff --git a/doc/zh_CN/syntax/20_naming_rule.md b/doc/zh_CN/syntax/20_naming_rule.md index 221c7a4c..7847b7ce 100644 --- a/doc/zh_CN/syntax/20_naming_rule.md +++ b/doc/zh_CN/syntax/20_naming_rule.md @@ -30,7 +30,7 @@ o = {x = 1; .x = 2} # 语法错误:同名的私有变量和公共变量不能 可以通过将字符串括在单引号 ('') 中来规避上述规则。 也就是说,程序对象也可以在没有 `!` 的情况下分配。 但是,在这种情况下,即使该值是常量表达式,也不会被视为常量。 像这样用单引号括起来的字符串称为文字标识符。 -这在调用Python等其他语言的API(FFI)时使用。 +这在调用Python等其他语言的API(FFI)时使用。 ```python bar! = pyimport("foo").'bar' diff --git a/doc/zh_CN/syntax/21_lambda.md b/doc/zh_CN/syntax/21_lambda.md index 8cac3bea..c7252620 100644 --- a/doc/zh_CN/syntax/21_lambda.md +++ b/doc/zh_CN/syntax/21_lambda.md @@ -57,7 +57,7 @@ now = if! True: ``` 您还可以键入和模式匹配。 正因为如此,`match` 函数大多是借助匿名函数的力量来实现的。 -作为 `match` 函数的参数给出的匿名函数从顶部开始按顺序尝试。 因此,您应该在顶部描述特殊情况,在底部描述更一般的情况。 如果你弄错了顺序,编译器会发出警告(如果可能的话) +作为 `match` 函数的参数给出的匿名函数从顶部开始按顺序尝试。 因此,您应该在顶部描述特殊情况,在底部描述更一般的情况。 如果你弄错了顺序,编译器会发出警告(如果可能的话) ```python diff --git a/doc/zh_CN/syntax/22_subroutine.md b/doc/zh_CN/syntax/22_subroutine.md index 78728e20..38fafc51 100644 --- a/doc/zh_CN/syntax/22_subroutine.md +++ b/doc/zh_CN/syntax/22_subroutine.md @@ -24,18 +24,18 @@ some_proc!: (T, U) => V .some_method: Ref(Self). (T, U) => () ``` -## 过程方法(依赖) +## 过程方法(依赖) 在下文中,假设类型 `T!` 采用类型参数 `N: Nat`。 要在外部指定它,请使用类型变量 ```python T!: Nat -> Type -# ~> 表示应用前后类型参数的状态(此时self必须是变量引用) +# ~> 表示应用前后类型参数的状态(此时self必须是变量引用) T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => () ``` 注意,`.some_method` 的类型是 `Ref!(T(N ~> N+X))。 ({X}) => () | N,X:Nat`。 -对于没有 `ref!` 的方法,即在应用后被剥夺所有权,不能使用类型参数转换(`~>`)。 +对于没有 `ref!` 的方法,即在应用后被剥夺所有权,不能使用类型参数转换(`~>`)。 如果取得所有权,则如下所示。 diff --git a/doc/zh_CN/syntax/25_object_system.md b/doc/zh_CN/syntax/25_object_system.md index ffb97156..116cd662 100644 --- a/doc/zh_CN/syntax/25_object_system.md +++ b/doc/zh_CN/syntax/25_object_system.md @@ -2,17 +2,17 @@ 可以分配给变量的所有数据。 `Object` 类的属性如下。 -* `.__repr__`:返回对象的(非丰富)字符串表示 -* `.__sizeof__`:返回对象的大小(包括堆分配) +* `.__repr__`:返回对象的(非丰富)字符串表示 +* `.__sizeof__`:返回对象的大小(包括堆分配) * `.__dir__`: 返回对象属性列表 * `.__hash__`:返回对象的哈希值 * `.__getattribute__`: 获取并返回对象的属性 -* `.clone`:创建并返回一个对象的克隆(在内存中有一个独立的实体) -* `.copy`:返回对象的副本(指向内存中的同一事物) +* `.clone`:创建并返回一个对象的克隆(在内存中有一个独立的实体) +* `.copy`:返回对象的副本(指向内存中的同一事物) ## 记录 -由记录文字(`{attr = value; ...}`)生成的对象。 +由记录文字(`{attr = value; ...}`)生成的对象。 这个对象有基本的方法,比如`.clone`和`.__sizeof__`。 ```python @@ -37,12 +37,12 @@ assert record.method() == 3 ## 元素 -属于特定类型的对象(例如,“1”是“Int”类型的元素)。所有对象至少是`{=}`类型的元素。 +属于特定类型的对象(例如,“1”是“Int”类型的元素)。所有对象至少是`{=}`类型的元素。 类的元素有时称为实例。 ## 子程序 -表示作为函数或过程(包括方法)实例的对象。代表子程序的类是“子程序”。 +表示作为函数或过程(包括方法)实例的对象。代表子程序的类是“子程序”。 实现 `.__call__` 的对象通常称为 `Callable`。 ## 可调用 @@ -53,7 +53,7 @@ assert record.method() == 3 定义需求属性并使对象通用化的对象。 主要有两种类型:多态类型和单态类型。典型的单态类型有`Int`、`Str`等,多态类型有`Option Int`、`[Int; 3]`等 -此外,定义改变对象状态的方法的类型称为 Mutable 类型,需要在变量属性中添加 `!`(例如动态数组:`[T; !_]`)。 +此外,定义改变对象状态的方法的类型称为 Mutable 类型,需要在变量属性中添加 `!`(例如动态数组:`[T; !_]`)。 ## 班级 @@ -61,7 +61,7 @@ assert record.method() == 3 ## 功能 -对外部变量(不包括静态变量)有读权限但对外部变量没有读/写权限的子程序。换句话说,它没有外部副作用。 +对外部变量(不包括静态变量)有读权限但对外部变量没有读/写权限的子程序。换句话说,它没有外部副作用。 Erg 函数的定义与 Python 的不同,因为它们不允许副作用。 ## 程序 @@ -75,7 +75,7 @@ Erg 函数的定义与 Python 的不同,因为它们不允许副作用。 ## 实体 不是子例程和类型的对象。 -单态实体(`1`、`"a"` 等)也称为值对象,多态实体(`[1, 2, 3], {"a": 1}`)也称为容器对象。 +单态实体(`1`、`"a"` 等)也称为值对象,多态实体(`[1, 2, 3], {"a": 1}`)也称为容器对象。

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/26_pattern_matching.md b/doc/zh_CN/syntax/26_pattern_matching.md index 1b5b9bc9..047fc29d 100644 --- a/doc/zh_CN/syntax/26_pattern_matching.md +++ b/doc/zh_CN/syntax/26_pattern_matching.md @@ -16,7 +16,7 @@ i: {1, 2, 3} = 2 fn x = x + 1 # 等于 fn x: Add(Int) = x + 1 -# (匿名)函数 +# (匿名)函数 fn = x -> x + 1 fn: Int -> Int = x -> x + 1 @@ -70,10 +70,10 @@ Array(T, N: {N | N >= 3}) Array(T, N | N >= 3) f M, N | M >= 0, N >= 1 = ... -f(1, 0) # 类型错误:N(第二个参数)必须为 1 或更多 +f(1, 0) # 类型错误:N(第二个参数)必须为 1 或更多 ``` -### 丢弃(通配符)模式 +### 丢弃(通配符)模式 ```python _ = 1 @@ -98,7 +98,7 @@ assert first(1, 2, 3) == 1 ```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) -# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) +# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) m, n = 1, 2 f(x, y) = ... diff --git a/doc/zh_CN/syntax/27_comprehension.md b/doc/zh_CN/syntax/27_comprehension.md index 359be021..6e301665 100644 --- a/doc/zh_CN/syntax/27_comprehension.md +++ b/doc/zh_CN/syntax/27_comprehension.md @@ -4,7 +4,7 @@ Array 和 `[expr | (name <- iterable)+ (predicate)*]`, set 和 `{expr | (name <- iterable)+ (predicate)*}`, 你可以创建一个字典 `{key: value | (name <- iterable)+ (predicate)*}`. -由`|`分隔的子句的第一部分称为布局子句(位置子句),第二部分称为绑定子句(绑定子句),第三部分称为保护子句(条件子句)。 +由`|`分隔的子句的第一部分称为布局子句(位置子句),第二部分称为绑定子句(绑定子句),第三部分称为保护子句(条件子句)。 保护子句可以省略,但绑定子句不能省略,保护子句不能在绑定子句之前。 理解示例 @@ -50,8 +50,8 @@ assert [(i, j) for i in range(1, 3) for j in range(3, 5)] == [(i, j) for j in ra ## 筛子类型 -与推导类似的是筛类型。 筛子类型是以`{Name: Type | Predicate}`创建的(枚举类型) -sieve类型的情况下,只能指定一个Name,不能指定布局(但是如果是tuple类型可以处理多个值),Predicate可以在编译时计算,即 ,只能指定一个常量表达式。 +与推导类似的是筛类型。 筛子类型是以`{Name: Type | Predicate}`创建的(枚举类型) +sieve类型的情况下,只能指定一个Name,不能指定布局(但是如果是tuple类型可以处理多个值),Predicate可以在编译时计算,即 ,只能指定一个常量表达式。 ```python Nat = {I: Int | I >= 0} diff --git a/doc/zh_CN/syntax/29_decorator.md b/doc/zh_CN/syntax/29_decorator.md index 66c9a07e..9046f20c 100644 --- a/doc/zh_CN/syntax/29_decorator.md +++ b/doc/zh_CN/syntax/29_decorator.md @@ -1,4 +1,4 @@ -# 装饰器(修饰符) +# 装饰器(修饰符) 装饰器用于向类型或函数添加或演示特定状态或行为。 装饰器的语法如下。 diff --git a/doc/zh_CN/syntax/30_error_handling.md b/doc/zh_CN/syntax/30_error_handling.md index 2280a5ae..5b64a6f8 100644 --- a/doc/zh_CN/syntax/30_error_handling.md +++ b/doc/zh_CN/syntax/30_error_handling.md @@ -1,14 +1,14 @@ # 错误处理系统 主要使用Result类型。 -在 Erg 中,如果您丢弃 Error 类型的对象(顶层不支持),则会发生错误。 +在 Erg 中,如果您丢弃 Error 类型的对象(顶层不支持),则会发生错误。 ## 异常,与 Python 互操作 -Erg 没有异常机制(Exception)。 导入 Python 函数时 +Erg 没有异常机制(Exception)。 导入 Python 函数时 * 将返回值设置为 `T 或 Error` 类型 -* `T or Panic` 类型(可能导致运行时错误) +* `T or Panic` 类型(可能导致运行时错误) 有两个选项,`pyimport` 默认为后者。 如果要作为前者导入,请使用 在 `pyimport` `exception_type` 中指定 `Error` (`exception_type: {Error, Panic}`)。 @@ -44,11 +44,11 @@ try!: 另一方面,在这个例子中,我们可以看到 `foo!` 和 `qux!` 会引发错误。 确切地说,`y` 也可能是 `Result` 类型,但您最终必须处理它才能使用里面的值。 -使用 `Result` 类型的好处不止于此。 `Result` 类型也是线程安全的。 这意味着错误信息可以(轻松)在并行执行之间传递。 +使用 `Result` 类型的好处不止于此。 `Result` 类型也是线程安全的。 这意味着错误信息可以(轻松)在并行执行之间传递。 ## 语境 -由于 `Error`/`Result` 类型本身不会产生副作用,不像异常,它不能有发送位置(Context)等信息,但是如果使用 `.context` 方法,可以将信息放在 `错误`对象。 可以添加。 `.context` 方法是一种使用 `Error` 对象本身并创建新的 `Error` 对象的方法。 它们是可链接的,并且可以包含多个上下文。 +由于 `Error`/`Result` 类型本身不会产生副作用,不像异常,它不能有发送位置(Context)等信息,但是如果使用 `.context` 方法,可以将信息放在 `错误`对象。 可以添加。 `.context` 方法是一种使用 `Error` 对象本身并创建新的 `Error` 对象的方法。 它们是可链接的,并且可以包含多个上下文。 ```python f() = todo() \ @@ -67,7 +67,7 @@ f() `Result` 类型由于其方便性在其他语言中经常使用,但与异常机制相比,它的缺点是难以理解错误的来源。 因此,在 Erg 中,`Error` 对象具有名为 `.stack` 的属性,并再现了类似伪异常机制的堆栈跟踪。 -`.stack` 是调用者对象的数组。 每次 Error 对象被`return`(包括通过`?`)时,它都会将它的调用子例程推送到`.stack`。 +`.stack` 是调用者对象的数组。 每次 Error 对象被`return`(包括通过`?`)时,它都会将它的调用子例程推送到`.stack`。 如果它是 `?`ed 或 `.unwrap`ed 在一个不可能 `return` 的上下文中,它会因为回溯而恐慌。 ```python diff --git a/doc/zh_CN/syntax/33_package_system.md b/doc/zh_CN/syntax/33_package_system.md index c3453333..a2a817fd 100644 --- a/doc/zh_CN/syntax/33_package_system.md +++ b/doc/zh_CN/syntax/33_package_system.md @@ -6,7 +6,7 @@ lib 包的入口点是`src/lib.er`。导入包相当于导入 `lib.er`。 一个包有一个称为模块的子结构,在 Erg 中是一个 Erg 文件或由 Erg 文件组成的目录。外部 Erg 文件/目录是作为模块对象的可操作对象。 -为了将目录识别为模块,有必要在目录中放置一个“(目录名称).er”文件。 +为了将目录识别为模块,有必要在目录中放置一个“(目录名称).er”文件。 这类似于 Python 的 `__init__.py`,但与 `__init__.py` 不同的是,它放在目录之外。 例如,考虑以下目录结构。 @@ -38,7 +38,7 @@ main args = 请注意用于访问子模块的 `/` 分隔符。 这是因为可以有诸如 `bar.baz.er` 之类的文件名。 不鼓励使用此类文件名,因为 `.er` 前缀在 Erg 中是有意义的。 -例如,用于测试的模块。 以 `.test.er` 结尾的文件是一个(白盒)测试模块,它在运行测试时执行一个用 `@Test` 修饰的子例程。 +例如,用于测试的模块。 以 `.test.er` 结尾的文件是一个(白盒)测试模块,它在运行测试时执行一个用 `@Test` 修饰的子例程。 ```console └─┬ ./src diff --git a/doc/zh_CN/syntax/34_generator.md b/doc/zh_CN/syntax/34_generator.md index 5c807345..8d260ba1 100644 --- a/doc/zh_CN/syntax/34_generator.md +++ b/doc/zh_CN/syntax/34_generator.md @@ -10,7 +10,7 @@ g!() = ``` `yield!` 是在调用`self!.yield!` 的子程序块中定义的过程。 和`return`一样,它把传递给它的值作为返回值返回,但它具有保存block当前执行状态,再次调用时从头开始执行的特性。 -生成器既是过程又是迭代器; Python 生成器是一个创建迭代器的函数,而 Erg 直接迭代。 过程本身通常不是可变对象(没有`!`),但生成器是可变对象,因为它自己的内容可以随着每次执行而改变。 +生成器既是过程又是迭代器; Python 生成器是一个创建迭代器的函数,而 Erg 直接迭代。 过程本身通常不是可变对象(没有`!`),但生成器是可变对象,因为它自己的内容可以随着每次执行而改变。 ```python # Generator! diff --git a/doc/zh_CN/syntax/SUMMARY.md b/doc/zh_CN/syntax/SUMMARY.md index 774c354b..f9486625 100644 --- a/doc/zh_CN/syntax/SUMMARY.md +++ b/doc/zh_CN/syntax/SUMMARY.md @@ -1,69 +1,69 @@ -# 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) +- [基础](./00_basic.md) +- [文字](./01_literal.md) +- [名称](02_name.md) +- [声明](./03_declaration.md) +- [函数](./04_function.md) +- [内置函数](./05_builtin_funcs.md) +- [操作员](./06_operator.md) +- [副作用](./07_side_effect.md) +- [程序](./08_procedure.md) +- [内置程序](./09_builtin_procs.md) +- [数组](./10_array.md) +- [元组](./11_tuple.md) +- [字典](./12_dict.md) +- [记录](./13_record.md) +- [设置](./14_set.md) +- [类型](./15_type.md) + - [类型系统](./type/01_type_system.md) + - [基础](./type/02_basic.md) + - [特质](./type/03_trait.md) + - [类](./type/04_class.md) + - [继承](./type/05_inheritance.md) + - [NST 与 SST](./type/06_nst_vs_sst.md) + - [补丁](./type/07_patch.md) + - [值类型](./type/08_value.md) + - [属性类型](./type/09_attributive.md) + - [间隔类型](./type/10_interval.md) + - [枚举类型](./type/11_enum.md) + - [细化类型](./type/12_refinement.md) + - [代数类型](./type/13_algebraic.md) + - [依赖类型](./type/14_dependent.md) + - [量化类型](./type/15_quantified.md) + - [子类型](./type/16_subtyping.md) + - [类型转换](./type/17_type_casting.md) + - [可变类型](./type/18_mut.md) + - [高级](./type/advanced.md) + - [默认参数](./type/advanced/default_param.md) + - [类型擦除](./type/advanced/erasure.md) + - [存在](./type/advanced/existential.md) - [GADTs](./type/advanced/GADTs.md) - - [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) + - [关键字参数](./type/advanced/keyword_param.md) + - [种类](./type/advanced/kind.md) + - [标记特征](./type/advanced/marker_trait.md) + - [可变结构](./type/advanced/mut_struct.md) + - [幻象类型](./type/advanced/phantom.md) + - [投影类型](./type/advanced/projection.md) + - [量化依赖类型](./type/advanced/quantified_dependent.md) + - [共享](./type/advanced/shared.md) +- [迭代器](./16_iterator.md) +- [可变性](./17_mutability.md) +- [所有权](./18_ownership.md) +- [可见性](./19_visibility.md) +- [命名规则](20_naming_rule.md) - [Lambda](./21_lambda.md) -- [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) +- [子程序](./22_subroutine.md) +- [关闭](./23_closure.md) +- [模块](./24_module.md) +- [对象系统](./25_object_system.md) +- [模式匹配](./26_pattern_matching.md) +- [理解](./27_comprehension.md) +- [扩展语法](./28_spread_syntax.md) +- [装饰器](./29_decorator.md) +- [错误处理](./30_error_handling.md) +- [管道](./31_pipeline.md) +- [与 Python 集成](./32_integration_with_python.md) +- [包系统](./33_package_system.md) +- [发电机](./34_generator.md) +- [索引](./indexes.md) \ No newline at end of file diff --git a/doc/zh_CN/syntax/container_ownership.md b/doc/zh_CN/syntax/container_ownership.md index da50a3d2..09bbfb3c 100644 --- a/doc/zh_CN/syntax/container_ownership.md +++ b/doc/zh_CN/syntax/container_ownership.md @@ -1,4 +1,4 @@ -# 下标(索引访问) +# 下标(索引访问) `[]` 不同于普通的方法。 @@ -9,14 +9,14 @@ assert a == [2, 2] ``` 回想一下,子例程的返回值不能是引用。 -这里的 `a[0]` 的类型显然应该是 `Ref!(Int!)`(`a[0]` 的类型取决于上下文)。 +这里的 `a[0]` 的类型显然应该是 `Ref!(Int!)`(`a[0]` 的类型取决于上下文)。 所以 `[]` 实际上是特殊语法的一部分,就像 `.` 一样。 与 Python 不同,它不能被重载。 也无法在方法中重现 `[]` 的行为。 ```python C = Class {i = Int!} C. get(ref self) = - self::i # 类型错误:`self::i` 是 `Int!`(需要所有权)但 `get` 不拥有 `self` + self::i # 类型错误:`self::i` 是 `Int!`(需要所有权)但 `get` 不拥有 `self` C.steal(self) = self::i #NG diff --git a/doc/zh_CN/syntax/grammar.md b/doc/zh_CN/syntax/grammar.md index 5e5ab93d..8e4e8a06 100644 --- a/doc/zh_CN/syntax/grammar.md +++ b/doc/zh_CN/syntax/grammar.md @@ -1,4 +1,4 @@ -# Erg 的语法(版本 0.1.0, 临时) +# Erg 的语法(版本 0.1.0, 临时) ``` special_op ::= '=' | '->' | '=>' | '.' | ',' | ':' | '::' | '|>' | '&' separator ::= ';' | '\n' diff --git a/doc/zh_CN/syntax/indexes.md b/doc/zh_CN/syntax/indexes.md index 5d3d19df..54ba47a3 100644 --- a/doc/zh_CN/syntax/indexes.md +++ b/doc/zh_CN/syntax/indexes.md @@ -1,12 +1,12 @@ -# index +# 指数 -See [here](../API/index.md) for APIs not in this index. -See [here](../dev_guide/terms.md) for terminology. +有关不在此索引中的 API,请参阅 [此处](../API/index.md)。 +有关术语,请参见 [此处](../dev_guide/terms.md)。 -## symbol +## 符号 * ! - * !-type → [mutable type](./type/mut.md) + * !-type → [可变性](./type/mut.md) * [#](./00_basic.md/#comment) * $ * % @@ -16,18 +16,18 @@ See [here](../dev_guide/terms.md) for terminology. * () * * * [*-less multiplication](./01_literal.md/#less-multiplication) -* + (prefix) - * +_ → + (prefix) -* + (infix) +* + (前置) + * +_ → + (前置) +* + (中置) * , -* − (prefix) - * −_ → − (prefix) -* − (infix) +* − (前置) + * −_ → − (前置) +* − (中置) * −> -* . → [Visibility] +* . → [可见性] * / * : - * :: → [visibility] + * :: → [可见性] * ; * < * <: @@ -58,7 +58,7 @@ See [here](../dev_guide/terms.md) for terminology. * || * ~ -## alphabet +## 字母 ### A @@ -177,276 +177,276 @@ See [here](../dev_guide/terms.md) for terminology. ## A line -* 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) +* 断言 +* 值对象 +* [附件补丁](./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) ## Ka line -* [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 → [,] +* [种类](./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 line -* 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] +* 递归 + * 递归 + * [递归函数](./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) + * 封闭式通用 + * 打开通用 + * 通用函数 → 多相关函数 + * 通用量化 +* 前缀运算符 +* 相互递归 +* 下标 → [索引] +* [属性] + * [属性子类型] ## Ta line -* [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) +* [代数](./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) -## na line +## 没有一行 -* [Comprehension](./27_comprehension.md) -* ~~Infix operator~~ → [Infix operator] -* [namespace] +* [理解](./27_comprehension.md) +* ~~中缀运算符~~ → [中缀运算符] +* [命名空间] ## is a line -* [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] +* [数组](./10_array.md) +* [派生类型](./type/variances.md/#用户定义的类型变体) +* [模式(匹配)](./26_pattern_matching.md) +* [包](./33_package_ssystem.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) +* 底部 + * 底部类型 → [{}] + * 底层 → [从不] +* [多态性] ## ma line -* ~~ prefix operator ~~ → prefix operator -* [Marker type](./type/advanced/marker_trait.md) -* [anonymous function](./21_lambda.md) -* mutable → [mutable] -* [Move] +* ~~ 前缀运算符 ~~ → 前缀运算符 +* [标记类型](./type/advanced/marker_trait.md) +* [匿名函数](./21_lambda.md) +* 可变 → [可变] +* [移动] * 方法 -* Metacharacter -* [module](./24_module.md) -* [String] → [Str] - * [String interpolation](./01_literal.md/#str literal) -* Return value +* 元字符 +* [模块](./24_module.md) +* [字符串] → [字符串] + * [字符串插值](./01_literal.md/#str字面量) +* 返回值 ## or line -* [Ghost type](./type/advanced/phantom.md) -* request attributes -* [element] -* [call] +* [幽灵类型](./type/advanced/phantom.md) +* 请求属性 +* [元素] +* [称呼] ## Ra line -* [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) +* [图书馆] +* 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) ## line -* Wildcard \ No newline at end of file +* 通配符 \ 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 4bd39ad7..886c4f8c 100644 --- a/doc/zh_CN/syntax/quick_tour.md +++ b/doc/zh_CN/syntax/quick_tour.md @@ -1,14 +1,14 @@ -# Quick Tour +# 快速浏览 -The documentation below `syntax` is written with the aim of being understandable even for programming beginners. -For those who have already mastered languages ​​such as Python, Rust, Haskell, etc., it may be a bit verbose. +`syntax` 下面的文档是为了让编程初学者也能理解而编写的。 +对于已经掌握 Python、Rust、Haskell 等语言的人来说,可能有点啰嗦。 -So, here's an overview of the Erg grammar. -Please think that the parts not mentioned are the same as Python. +所以,这里是 Erg 语法的概述。 +请认为未提及的部分与 Python 相同。 -## variables, constants +## 变量,常量 -Variables are defined with `=`. As with Haskell, variables once defined cannot be changed. However, it can be shadowed in another scope. +变量用 `=` 定义。 与 Haskell 一样,变量一旦定义就不能更改。 但是,它可以在另一个范围内被遮蔽。 ```python i = 0 @@ -17,8 +17,8 @@ if True: assert i == 0 ``` -Anything starting with an uppercase letter is a constant. Only things that can be computed at compile time can be constants. -Also, a constant is identical in all scopes since its definition. +任何以大写字母开头的都是常数。 只有可以在编译时计算的东西才能是常量。 +此外,自定义以来,常量在所有范围内都是相同的。 ```python PI = 3.141592653589793 @@ -27,19 +27,19 @@ match random.random!(0..10): log "You get PI, it's a miracle!" ``` -## declaration +## 类型声明 -Unlike Python, only the variable type can be declared first. -Of course, the declared type and the type of the object actually assigned to must be compatible. +与 Python 不同的是,只能先声明变量类型。 +当然,声明的类型和实际分配的对象的类型必须兼容。 ```python i: Int i = 10 ``` -## Functions +## 函数 -You can define it just like in Haskell. +你可以像在 Haskell 中一样定义它。 ```python fib0 = 0 @@ -47,20 +47,20 @@ fib1 = 1 fibn = fib(n - 1) + fib(n - 2) ``` -An anonymous function can be defined like this: +匿名函数可以这样定义: ```python i -> i + 1 assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4] ``` -## operator +## 运算符 -The Erg-specific operators are: +特定于 Erg 的运算符是: -### mutating operator (!) +### 变异运算符 (!) -It's like `ref` in Ocaml. +这就像 Ocaml 中的`ref`。 ```python i = !0 @@ -68,15 +68,15 @@ i.update! x -> x + 1 assert i == 1 ``` -## procedures +## 程序 -Subroutines with side effects are called procedures and are marked with `!`. +具有副作用的子例程称为过程,并标有`!`。 ```python print! 1 # 1 ``` -## generic function (polycorrelation) +## 泛型函数(多相关) ```python id|T|(x: T): T = x @@ -84,30 +84,30 @@ id(1): Int id("a"): Str ``` -## Records +## 记录 -You can use the equivalent of records in ML-like languages ​​(or object literals in JS). +您可以使用类似 ML 的语言中的记录等价物(或 JS 中的对象字面量)。 ```python p = {x = 1; y = 2} ``` -## Ownership +## 所有权 -Ergs are owned by mutable objects (objects mutated with the `!` operator) and cannot be rewritten from multiple places. +Ergs 由可变对象(使用 `!` 运算符突变的对象)拥有,并且不能从多个位置重写。 ```python i = !0 j = i assert j == 0 -i#MoveError +i#移动错误 ``` -Immutable objects, on the other hand, can be referenced from multiple places. +另一方面,不可变对象可以从多个位置引用。 -## Visibility +## 可见性 -Prefixing a variable with `.` makes it a public variable and allows it to be referenced from external modules. +使用 `.` 前缀变量使其成为公共变量并允许从外部模块引用它。 ```python # foo.er @@ -118,41 +118,41 @@ y = 1 ```python foo = import "foo" assert foo.x == 1 -foo.y # VisibilityError +foo.y # 可见性错误 ``` -## pattern matching +## 模式匹配 -### variable pattern +### 变量模式 ```python -# basic assignments +# 基本任务 i = 1 -# with type +# with 类型 i: Int = 1 -# functions +# 函数 fn x = x + 1 fn: Int -> Int = x -> x + 1 ``` -### Literal patterns +### 文字模式 ```python -# if `i` cannot be determined to be 1 at compile time, TypeError occurs. -# shorthand of `_: {1} = i` +# 如果 `i` 在编译时无法确定为 1,则发生 类型错误 +# 简写:`_ {1} = i` 1 = i -# simple pattern matching +# 简单的模式匹配 match x: 1 -> "1" 2 -> "2" _ -> "other" -# fibonacci function +# 斐波那契函数 fib0 = 0 fib1 = 1 fibn: Nat = fibn-1 + fibn-2 ``` -### constant pattern +### 常量模式 ```python PI = 3.141592653589793 @@ -164,7 +164,7 @@ name = match num: _ -> "unnamed" ``` -### discard (wildcard) pattern +### 丢弃(通配符)模式 ```python _ = 1 @@ -172,9 +172,9 @@ _: Int = 1 right(_, r) = r ``` -### Variable length patterns +### 可变长度模式 -Used in combination with the tuple/array/record pattern described later. +与稍后描述的元组/数组/记录模式结合使用。 ```python [i,...j] = [1, 2, 3, 4] @@ -183,27 +183,27 @@ first|T|(fst: T, ...rest: T) = fst assert first(1, 2, 3) == 1 ``` -### Tuple pattern +### 元组模式 ```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) -# If not nested, () can be omitted (1, 2 are treated as (1, 2)) +# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) m, n = 1, 2 ``` -### array pattern +### 数组模式 ```python length[] = 0 length[_, ...rest] = 1 + lengthrest ``` -#### record pattern +#### 记录模式 ```python {sin; cos; tan; ...} = import "math" -{*} = import "math" # import all +{*} = import "math" # 全部导入 person = {name = "John Smith"; age = 20} age = match person: @@ -211,7 +211,7 @@ age = match person: {_; age} -> age ``` -### Data class pattern +### 数据类模式 ```python Point = Inherit {x = Int; y = Int} @@ -219,20 +219,20 @@ p = Point::{x = 1; y = 2} Point::{x; y} = p ``` -## Comprehensions +## 理解(Comprehensions) ```python odds = [i | i <- 1..100; i % 2 == 0] ``` -## class +## 班级 -Erg does not support multiple/multilevel inheritance. +Erg 不支持多级/多级继承。 -## Traits +## 特质 -They are similar to Rust traits, but in a more literal sense, allowing composition and decoupling, and treating attributes and 方法 as equals. -Also, it does not involve implementation. +它们类似于 Rust 特征,但在更字面意义上,允许组合和解耦,并将属性和方法视为平等。 +此外,它不涉及实施。 ```python XY = Trait {x = Int; y = Int} @@ -246,19 +246,19 @@ Point. ... ``` -## patch +## 修补 -You can give implementations to classes and traits. +您可以为类和特征提供实现。 -## Sieve type +## 筛子类型 -A predicate expression can be type-restricted. +谓词表达式可以是类型限制的。 ```python Nat = {I: Int | I >= 0} ``` -## parametric type with value (dependent type) +## 带值的参数类型(依赖类型) ```python a: [Int; 3] diff --git a/doc/zh_CN/syntax/type/01_type_system.md b/doc/zh_CN/syntax/type/01_type_system.md index b5aa76e2..7ed2b019 100644 --- a/doc/zh_CN/syntax/type/01_type_system.md +++ b/doc/zh_CN/syntax/type/01_type_system.md @@ -4,7 +4,7 @@ ## 如何定义 -Erg 的独特功能之一是(普通)变量、函数(子例程)和类型(Kind)定义之间的语法没有太大区别。 所有都是根据普通变量和函数定义的语法定义的。 +Erg 的独特功能之一是(普通)变量、函数(子例程)和类型(Kind)定义之间的语法没有太大区别。 所有都是根据普通变量和函数定义的语法定义的。 ```python f i: Int = i + 1 @@ -26,16 +26,16 @@ o2 = D.new {.public = 2} # 初始化错误:类 'D' 需要属性 'private'(: In ## Classification Erg 中的所有对象都是强类型的。 -顶层类型是`{=}`,实现了`__repr__`、`__hash__`、`clone`等(不是必须的方法,这些属性不能被覆盖)。 +顶层类型是`{=}`,实现了`__repr__`、`__hash__`、`clone`等(不是必须的方法,这些属性不能被覆盖)。 Erg 的类型系统包含结构子类型 (SST)。 该系统类型化的类型称为结构类型。 -结构类型主要分为三种:Attributive(属性类型)、Refinement(细化类型)和Algebraic(代数类型)。 +结构类型主要分为三种:Attributive(属性类型)、Refinement(细化类型)和Algebraic(代数类型)。 | | Record | Enum | Interval | Union | Intersection | Diff | | --------- | ----------- | ---------- | -------------- | ----------- | ------------ | ------------ | | kind | Attributive | Refinement | Refinement | Algebraic | Algebraic | Algebraic | | generator | record | set | range operator | or operator | and operator | not operator | -也可以使用名义子类型(NST),将 SST 类型转换为 NST 类型称为类型的名义化。 结果类型称为名义类型。 +也可以使用名义子类型(NST),将 SST 类型转换为 NST 类型称为类型的名义化。 结果类型称为名义类型。 在 Erg 中,名义类型是类和特征。 当我们简单地说类/特征时,我们通常指的是记录类/特征。 | | Type | Abstraction | Subtyping procedure | @@ -43,24 +43,24 @@ Erg 的类型系统包含结构子类型 (SST)。 该系统类型化的类型称 | NST | NominalType | Trait | Inheritance | | SST | StructuralType | Structural Trait | (Implicit) | -整个名义类型的类型(`NominalType`)和整个结构类型的类型(`StructuralType`)是整个类型(`Type`)的类型的子类型。 +整个名义类型的类型(`NominalType`)和整个结构类型的类型(`StructuralType`)是整个类型(`Type`)的类型的子类型。 -Erg 可以将参数(类型参数)传递给类型定义。带有类型参数的 `Option`、`Array` 等称为多项式类型。这些本身不是类型,但它们通过应用参数成为类型。诸如 `Int`、`Str` 等没有参数的类型称为简单类型(标量类型)。 +Erg 可以将参数(类型参数)传递给类型定义。带有类型参数的 `Option`、`Array` 等称为多项式类型。这些本身不是类型,但它们通过应用参数成为类型。诸如 `Int`、`Str` 等没有参数的类型称为简单类型(标量类型)。 一个类型可以看成一个集合,并且存在包含关系。例如,“Num”包含“Add”、“Sub”等,“Int”包含“Nat”。 所有类的上类是`Object == Class {:}`,所有类型的下类是`Never == Class {}`。这在下面描述。 ## 类型 -像 `Array T` 这样的类型可以看作是 `Type -> Type` 类型的函数,它以 `T` 类型为参数并返回 `Array T` 类型(在类型论中也称为 Kind)。像 `Array T` 这样的类型专门称为多态类型,而 `Array` 本身称为一元 Kind。 +像 `Array T` 这样的类型可以看作是 `Type -> Type` 类型的函数,它以 `T` 类型为参数并返回 `Array T` 类型(在类型论中也称为 Kind)。像 `Array T` 这样的类型专门称为多态类型,而 `Array` 本身称为一元 Kind。 已知参数和返回类型的函数的类型表示为`(T, U) -> V`。如果要指定同一类型的整个双参数函数,可以使用 `|T| (T, T) -> T`,如果要指定整个 N 参数函数,可以使用 `Func N`。但是,`Func N` 类型没有关于参数数量或其类型的信息,因此所有返回值在调用时都是`Obj` 类型。 `Proc` 类型表示为 `() => Int` 等等。此外,`Proc` 类型实例的名称必须以 `!` 结尾。 -`Method` 类型是一个函数/过程,其第一个参数是它所属的对象 `self`(通过引用)。对于依赖类型,也可以在应用方法后指定自己的类型。这是 `T!(!N)` 类型和 `T!(N ~> N-1)。 () => Int` 等等。 +`Method` 类型是一个函数/过程,其第一个参数是它所属的对象 `self`(通过引用)。对于依赖类型,也可以在应用方法后指定自己的类型。这是 `T!(!N)` 类型和 `T!(N ~> N-1)。 () => Int` 等等。 -Erg 的数组(Array)就是 Python 所说的列表。 `[诠释; 3]`是一个数组类,包含三个`Int`类型的对象。 +Erg 的数组(Array)就是 Python 所说的列表。 `[诠释; 3]`是一个数组类,包含三个`Int`类型的对象。 > __Note__: `(Type; N)` 既是类型又是值,所以可以这样使用。 > @@ -112,7 +112,7 @@ Point2D = {.x = Int; .y = Int} 如前所述,Erg 中的“类型”大致表示一组对象。 -下面是 `Add` 类型的定义,需要 `+`(中间运算符)。 `R, O` 是所谓的类型参数,可以是真正的类型(类),例如 `Int` 或 `Str`。 在其他语言中,类型参数被赋予特殊的符号(泛型、模板等),但在 Erg 中,它们可以像普通参数一样定义。 +下面是 `Add` 类型的定义,需要 `+`(中间运算符)。 `R, O` 是所谓的类型参数,可以是真正的类型(类),例如 `Int` 或 `Str`。 在其他语言中,类型参数被赋予特殊的符号(泛型、模板等),但在 Erg 中,它们可以像普通参数一样定义。 类型参数也可以用于类型对象以外的类型。 例如数组类型`[Int; 3]` 是 `Array Int, 3` 的语法糖。 如果类型实现重叠,用户必须明确选择一个。 ```python @@ -132,7 +132,7 @@ NumImpl. ... ``` -多态类型可以像函数一样对待。 通过将它们指定为 `Mul Int、Str` 等,它们可以是单态的(在许多情况下,它们是用实际参数推断出来的,而没有指定它们)。 +多态类型可以像函数一样对待。 通过将它们指定为 `Mul Int、Str` 等,它们可以是单态的(在许多情况下,它们是用实际参数推断出来的,而没有指定它们)。 ```python 1 + 1 @@ -141,7 +141,7 @@ Nat.`_+_` 1, 1 Int.`_+_` 1, 1 ``` -前四行返回相同的结果(准确地说,底部的返回 `Int`),但通常使用顶部的。 +前四行返回相同的结果(准确地说,底部的返回 `Int`),但通常使用顶部的。 `Ratio.`_+_`(1, 1)` 将返回 `2.0` 而不会出错。 这是因为 `Int <: Ratio`,所以 `1` 向下转换为 `Ratio`。 但这不是演员。 @@ -164,7 +164,7 @@ f x, y = x + y ``` 在上面的代码中,带有 `+` 的类型,即 `Add` 是自动推断的; Erg 首先推断出最小的类型。如果`f 0, 1`,它将推断`f x:{0},y:{1}`,如果`n:Nat; f n, 1`,它会推断`f x: Nat, y: {1}`。最小化之后,增加类型直到找到实现。在 `{0}, {1}` 的情况下,`Nat` 与 `Nat` 是单态的,因为 `Nat` 是具有 `+` 实现的最小类型。 -如果是 `{0}, {-1}`,它与 `Int` 是单态的,因为它不匹配 `Nat`。如果子类型和超类型之间没有关系,则首先尝试具有最低浓度(实例数)(或者在多态类型的情况下参数更少)的那个。 +如果是 `{0}, {-1}`,它与 `Int` 是单态的,因为它不匹配 `Nat`。如果子类型和超类型之间没有关系,则首先尝试具有最低浓度(实例数)(或者在多态类型的情况下参数更少)的那个。 `{0}` 和 `{1}` 是枚举类型,它们是部分类型,例如 `Int` 和 `Nat`。 例如,可以为枚举类型指定名称和请求/实现方法。在有权访问该类型的命名空间中,满足请求的对象可以使用实现方法。 @@ -182,7 +182,7 @@ Binary. 1 -> True ``` -此后,代码“0.to_bool()”是可能的(尽管“0 as Bool == False”是内置定义的)。 +此后,代码“0.to_bool()”是可能的(尽管“0 as Bool == False”是内置定义的)。 这是一个实际上可以重写 `self` 的类型的示例,如代码所示。 ```python @@ -197,7 +197,7 @@ b.switch!() print! b # => 0 ``` -## 结构类型(匿名类型) +## 结构类型(匿名类型) ```python Binary = {0, 1} @@ -205,7 +205,7 @@ Binary = {0, 1} 上面代码中的 `Binary` 是一个类型,其元素是 `0` 和 `1`。 它也是 `Int` 类型的子类型,它同时具有 `0` 和 `1`。 像 `{}` 这样的对象本身就是一种类型,可以在分配或不分配给上述变量的情况下使用。 -这样的类型称为结构类型。 当我们想强调它作为后者而不是类(命名类型)的用途时,它也被称为未命名类型。 `{0, 1}`这样的结构类型称为枚举类型,还有区间类型、记录类型等。 +这样的类型称为结构类型。 当我们想强调它作为后者而不是类(命名类型)的用途时,它也被称为未命名类型。 `{0, 1}`这样的结构类型称为枚举类型,还有区间类型、记录类型等。 ### 类型标识 diff --git a/doc/zh_CN/syntax/type/02_basic.md b/doc/zh_CN/syntax/type/02_basic.md index 8e34ccea..adca8428 100644 --- a/doc/zh_CN/syntax/type/02_basic.md +++ b/doc/zh_CN/syntax/type/02_basic.md @@ -47,7 +47,7 @@ f x: _, y: Int = x + y # 类型错误:Object 和 Int 之间没有实现 + ## 子类型规范 -除了 `:`(类型声明运算符),Erg 还允许您使用 `<:`(部分类型声明运算符)来指定类型之间的关系。 +除了 `:`(类型声明运算符),Erg 还允许您使用 `<:`(部分类型声明运算符)来指定类型之间的关系。 `<:` 的左边只能指定一个类。 使用 `Subtypeof` 或类似的运算符来比较结构类型。 这也经常在定义子例程或类型时使用,而不是简单地指定变量。 @@ -56,7 +56,7 @@ f x: _, y: Int = x + y # 类型错误:Object 和 Int 之间没有实现 + # 参数的子类型规范 f X <: T = ... -# 所需属性的子类型规范(.Iterator 属性必须是 Iterator 类型的子类型) +# 所需属性的子类型规范(.Iterator 属性必须是 Iterator 类型的子类型) Iterable T = Trait { .Iterator = {Iterator} # {Iterator} == {I: Type | I <: Iterator} .iter = Self.() -> Self.Iterator T @@ -89,7 +89,7 @@ K(Int). ```python C = Class Object -C.shoe self = ... # Show 由于 Typo 没有实现(它被认为只是一种独特的方法) +C.shoe self = ... # Show 由于 Typo 没有实现(它被认为只是一种独特的方法) ``` ## 属性定义 @@ -134,7 +134,7 @@ IorS = Int or Str Vector = Array Int ``` -此外,当显示错误时,如果定义了复合类型(在上面的示例中,右侧类型不是第一个类型),编译器将为它们使用别名。 +此外,当显示错误时,如果定义了复合类型(在上面的示例中,右侧类型不是第一个类型),编译器将为它们使用别名。 但是,每个模块只允许一个相同类型的别名,多个别名将导致警告。 这意味着应将具有不同用途的类型定义为单独的类型。 diff --git a/doc/zh_CN/syntax/type/03_trait.md b/doc/zh_CN/syntax/type/03_trait.md index 5f6b1287..0fbca1ef 100644 --- a/doc/zh_CN/syntax/type/03_trait.md +++ b/doc/zh_CN/syntax/type/03_trait.md @@ -9,7 +9,7 @@ Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int} 特质不区分属性和方法。 -注意,trait 只能声明,不能实现(实现是通过一个叫做 patching 的特性来实现的,后面会讨论)。 +注意,trait 只能声明,不能实现(实现是通过一个叫做 patching 的特性来实现的,后面会讨论)。 可以通过指定部分类型来检查特征在类中的实现。 ```python @@ -25,7 +25,7 @@ Point2D <: Norm # 类型错误:Point2D 不是 Norm 的子类型 Point2D = Class {.x = Int; .y = Int} ``` -特征与结构类型一样,可以应用组合、替换和消除等操作(例如“T 和 U”)。 由此产生的特征称为即时特征。 +特征与结构类型一样,可以应用组合、替换和消除等操作(例如“T 和 U”)。 由此产生的特征称为即时特征。 ```python T = Trait {.x = Int} diff --git a/doc/zh_CN/syntax/type/04_class.md b/doc/zh_CN/syntax/type/04_class.md index 2d0e5715..a95fabe5 100644 --- a/doc/zh_CN/syntax/type/04_class.md +++ b/doc/zh_CN/syntax/type/04_class.md @@ -1,6 +1,6 @@ # Class -Erg 中的类大致是一种可以创建自己的元素(实例)的类型。 +Erg 中的类大致是一种可以创建自己的元素(实例)的类型。 这是一个简单类的示例。 ```python @@ -14,7 +14,7 @@ print! john # print! classof(john) # Person ``` -赋予“Class”的类型(通常是记录类型)称为需求类型(在本例中为“{.name = Str; .age = Nat}”)。 +赋予“Class”的类型(通常是记录类型)称为需求类型(在本例中为“{.name = Str; .age = Nat}”)。 可以使用 `::__new__ { = ; 创建实例 ...}` 可以创建。 `{.name = "约翰·史密斯"; .age = 25}` 只是一条记录,但它通过传递 `Person.new` 转换为 `Person` 实例。 创建此类实例的子例程称为构造函数。 @@ -40,7 +40,7 @@ class Person: ``` ```python -# 在Erg中,这个符号意味着类属性的声明(不是实例属性) +# 在Erg中,这个符号意味着类属性的声明(不是实例属性) Person = Class() Person. name: Str @@ -55,7 +55,7 @@ Person = Class { } ``` -元素属性(在记录中定义的属性)和类型属性(也称为实例/类属性,尤其是在类的情况下)是完全不同的东西。 类型属性是类型本身的属性。 当一个类型的元素本身没有所需的属性时,它指的是一个类型属性。 元素属性是元素直接拥有的唯一属性。 +元素属性(在记录中定义的属性)和类型属性(也称为实例/类属性,尤其是在类的情况下)是完全不同的东西。 类型属性是类型本身的属性。 当一个类型的元素本身没有所需的属性时,它指的是一个类型属性。 元素属性是元素直接拥有的唯一属性。 为什么要进行这种区分? 如果所有属性都是元素属性,那么在创建对象时复制和初始化所有属性将是低效的。 此外,以这种方式划分属性明确了诸如“该属性是共享的”和“该属性是分开持有的”之类的角色。 @@ -99,8 +99,8 @@ C.i = 1 # 属性错误:`.i` 已在实例字段中定义 对象可以使用补丁方法以及类方法。 Erg 不允许您添加类方法,但您可以使用 [patch](./07_patch.md) 来扩展类。 -您还可以从现有类([Inheritable](./../27_decorator.md/#inheritable) 类)继承。 -您可以使用 `Inherit` 创建一个继承类。 左侧的类型称为派生类,右侧的“继承”的参数类型称为基类(继承类)。 +您还可以从现有类([Inheritable](./../27_decorator.md/#inheritable) 类)继承。 +您可以使用 `Inherit` 创建一个继承类。 左侧的类型称为派生类,右侧的“继承”的参数类型称为基类(继承类)。 ```python MyStr = Inherit Str @@ -113,7 +113,7 @@ abc = MyStr.new("abc") assert abc - "b" == "ac" ``` -与 Python 不同,默认情况下,定义的 Erg 类是 `final`(不可继承的)。 +与 Python 不同,默认情况下,定义的 Erg 类是 `final`(不可继承的)。 要使类可继承,必须将 `Inheritable` 装饰器附加到该类。 Str` 是可继承的类之一。 @@ -161,9 +161,9 @@ john = Person.new("John Smith", 25) ``` 使用类有四个优点。 -第一个是构造函数经过有效性检查,第二个是它的性能更高,第三个是您可以使用符号子类型(NST),第四个是您可以继承和覆盖。 +第一个是构造函数经过有效性检查,第二个是它的性能更高,第三个是您可以使用符号子类型(NST),第四个是您可以继承和覆盖。 -我们之前看到记录类型 + 补丁也可以定义一个构造函数(某种意义上),但这当然不是一个合法的构造函数。 这当然不是一个合法的构造函数,因为它可以返回一个完全不相关的对象,即使它调用自己`.new`。 在类的情况下,`.new` 被静态检查以查看它是否生成满足要求的对象。 +我们之前看到记录类型 + 补丁也可以定义一个构造函数(某种意义上),但这当然不是一个合法的构造函数。 这当然不是一个合法的构造函数,因为它可以返回一个完全不相关的对象,即使它调用自己`.new`。 在类的情况下,`.new` 被静态检查以查看它是否生成满足要求的对象。 ~ @@ -204,7 +204,7 @@ john.bark() # 类型错误: `Person` 对象没有方法 `.bark`。 ``` 另一个特点是补丁添加的类型属性是虚拟的,实现类不作为实体保存。 -也就是说,`T.x`、`T.bar` 是可以通过与 `{i = Int}` 兼容的类型访问(编译时绑定)的对象,并且未在 `{i = Int}` 或 ` C`。 +也就是说,`T.x`、`T.bar` 是可以通过与 `{i = Int}` 兼容的类型访问(编译时绑定)的对象,并且未在 `{i = Int}` 或 ` C`。 相反,类属性由类本身持有。 因此,它们不能被不处于继承关系的类访问,即使它们具有相同的结构。 ```python @@ -229,7 +229,7 @@ C.new({i = 1}).bar # <方法 bar> ## 与数据类的区别 -有两种类型的类:常规类,通过`Class`成为记录类,以及从记录类继承(`Inherit`)的数据类。 +有两种类型的类:常规类,通过`Class`成为记录类,以及从记录类继承(`Inherit`)的数据类。 数据类继承了记录类的功能,具有分解赋值、默认实现的`==`和`hash`等特性。另一方面,数据类有自己的等价关系和格式展示。 另一方面,如果要定义自己的等价关系或格式显示,则应使用普通类。 @@ -268,7 +268,7 @@ assert x1 == x2 ## 类关系 -类是需求类型的子类型。 类中可以使用需求类型的方法(包括补丁方法)。 +类是需求类型的子类型。 类中可以使用需求类型的方法(包括补丁方法)。 ```python T = Trait {.foo = Foo} diff --git a/doc/zh_CN/syntax/type/05_inheritance.md b/doc/zh_CN/syntax/type/05_inheritance.md index e87ac090..c4efa961 100644 --- a/doc/zh_CN/syntax/type/05_inheritance.md +++ b/doc/zh_CN/syntax/type/05_inheritance.md @@ -31,7 +31,7 @@ Erg 的特殊设计不允许继承“Never”类型。 Erg 的特殊设计不允 ## 枚举类的继承 -[Or 类型](./13_algebraic.md) 也可以被继承。 在这种情况下,您可以通过指定可选参数 `Excluding` 来删除任何选项(可以使用 `or` 进行多项选择)。 +[Or 类型](./13_algebraic.md) 也可以被继承。 在这种情况下,您可以通过指定可选参数 `Excluding` 来删除任何选项(可以使用 `or` 进行多项选择)。 不能添加其他选项。 添加选项的类不是原始类的子类型。 ```python @@ -117,18 +117,18 @@ Inherited! 然而,这个规范并没有完全解决覆盖问题。 然而,这个规范并没有完全解决覆盖问题,因为编译器无法检测覆盖是否解决了问题。 创建派生类的程序员有责任纠正覆盖的影响。 只要有可能,尝试定义一个别名方法。 -### 替换特征(或看起来像什么) +### 替换特征(或看起来像什么) 尽管无法在继承时替换特征,但有一些示例似乎可以这样做。 -例如,`Int`,`Real` 的子类型(实现了 `Add()`),似乎重新实现了 `Add()`。 +例如,`Int`,`Real` 的子类型(实现了 `Add()`),似乎重新实现了 `Add()`。 ```python Int = Class ... , Impl := Add() and ... ``` 但实际上 `Real` 中的 `Add()` 代表 `Add(Real, Real)`,而在 `Int` 中它只是被 `Add(Int, Int)` 覆盖。 -它们是两个不同的特征(`Add` 是一个 [covariate](./advanced/variance.md),所以`Add(Real, Real) :> Add(Int, Int)`)。 +它们是两个不同的特征(`Add` 是一个 [covariate](./advanced/variance.md),所以`Add(Real, Real) :> Add(Int, Int)`)。 ## 多重继承 @@ -145,7 +145,7 @@ IntAndStr = Inherit Int and Str # 语法错误:不允许类的多重继承 但是,可以使用多个继承的 Python 类。 -## 多层(多级)继承 +## 多层(多级)继承 Erg 继承也禁止多层继承。 也就是说,您不能定义从另一个类继承的类。 从“Object”继承的可继承类可能会异常继承。 @@ -176,7 +176,7 @@ Inherited! # 覆盖错误:`.inc_pub!` 必须是 `Self! 的子类型! () => ()` ``` -第二个是对继承源的(变量)实例属性的更新操作。 这也是被禁止的。 基类的实例属性只能从基类提供的方法中更新。 +第二个是对继承源的(变量)实例属性的更新操作。 这也是被禁止的。 基类的实例属性只能从基类提供的方法中更新。 无论属性的可见性如何,都无法直接更新。 但是,它们可以被读取。 ```python @@ -205,7 +205,7 @@ Inherited! Erg 禁止多重和多层继承的原因是为了降低这种风险,并且引入了类补丁功能以降低依赖关系的复杂性,同时保留继承的“添加功能”方面。 那么,反过来说,应该在哪里使用继承呢?一个指标是何时需要“基类的语义子类型”。 -Erg 允许类型系统自动进行部分子类型确定(例如,Nat,其中 Int 大于或等于 0)。 +Erg 允许类型系统自动进行部分子类型确定(例如,Nat,其中 Int 大于或等于 0)。 但是,例如,仅依靠 Erg 的类型系统很难创建“表示有效电子邮件地址的字符串类型”。您可能应该对普通字符串执行验证。然后,我们想为已通过验证的字符串对象添加某种“保证”。这相当于向下转换为继承的类。将 `Str object` 向下转换为 `ValidMailAddressStr` 与验证字符串是否采用正确的电子邮件地址格式是一一对应的。 ```python 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 7c79df2c..7d0393eb 100644 --- a/doc/zh_CN/syntax/type/06_nst_vs_sst.md +++ b/doc/zh_CN/syntax/type/06_nst_vs_sst.md @@ -36,7 +36,7 @@ assert MonthsClass.new(2).name() == "february" ## 最后,我应该使用哪个,NST 还是 SST? 如果您无法决定使用哪一个,我们的建议是 NST。 -SST 需要抽象技能来编写在任何用例中都不会崩溃的代码。 好的抽象可以带来高生产力,但错误的抽象(外观上的共性)会导致适得其反的结果。(NST 可以通过故意将抽象保持在最低限度来降低这种风险。如果您不是库实现者,那么仅使用 NST 进行编码并不是一个坏主意。 +SST 需要抽象技能来编写在任何用例中都不会崩溃的代码。 好的抽象可以带来高生产力,但错误的抽象(外观上的共性)会导致适得其反的结果。(NST 可以通过故意将抽象保持在最低限度来降低这种风险。如果您不是库实现者,那么仅使用 NST 进行编码并不是一个坏主意。

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/type/07_patch.md b/doc/zh_CN/syntax/type/07_patch.md index 6a02c067..20adf0c8 100644 --- a/doc/zh_CN/syntax/type/07_patch.md +++ b/doc/zh_CN/syntax/type/07_patch.md @@ -1,7 +1,7 @@ # 修补 Erg 不允许修改现有类型和类。 -这意味着,不可能在类中定义额外的方法,也不能执行特化(一种语言特性,单态化多态声明的类型并定义专用方法,如在 C++ 中)。 +这意味着,不可能在类中定义额外的方法,也不能执行特化(一种语言特性,单态化多态声明的类型并定义专用方法,如在 C++ 中)。 但是,在许多情况下,您可能希望向现有类型或类添加功能,并且有一个称为“修补”的功能允许您执行此操作。 ```python @@ -13,10 +13,10 @@ assert "abc".reverse() == "cba" ``` 补丁的名称应该是要添加的主要功能的简单描述。 -这样,被修补类型的对象(`Str`)可以使用修补程序的方法(`StrReverse`)。 +这样,被修补类型的对象(`Str`)可以使用修补程序的方法(`StrReverse`)。 实际上,内置方法`.reverse`并不是`Str`的方法,而是`StrRReverse`中添加的方法。 -但是,补丁方法的优先级低于名义类型(类/特质)的方法,并且不能覆盖现有类型。 +但是,补丁方法的优先级低于名义类型(类/特质)的方法,并且不能覆盖现有类型。 ```python StrangeInt = Patch Int @@ -119,7 +119,7 @@ StrReverse. 每个类型/特征对只能定义一个胶水补丁。 这是因为如果多个胶水修复程序同时“可见”,就不可能唯一确定选择哪个实现。 -但是,当移动到另一个范围(模块)时,您可以交换维修程序。 +但是,当移动到另一个范围(模块)时,您可以交换维修程序。 ```python NumericStr = Inherit Str @@ -130,12 +130,12 @@ NumStrRev = Patch NumericStr, Impl := Reverse NumStrRev. ... # 重复修补程序错误:数值Str已与“反向”关联` -# 提示:'Str'(NumericStr'的超类)通过'StrReverse'与'Reverse'关联 +# 提示:'Str'(NumericStr'的超类)通过'StrReverse'与'Reverse'关联 ``` ## 附录:与 Rust 特征的关系 -Erg 修复程序相当于 Rust 的(改造的)`impl` 块。 +Erg 修复程序相当于 Rust 的(改造的)`impl` 块。 ```rust // Rust @@ -186,7 +186,7 @@ fn iter(i: I) -> impl Iterator where I: IntoIterator { ## 通用补丁 补丁不仅可以为一种特定类型定义,还可以为“一般功能类型”等定义。 -在这种情况下,要给出自由度的项作为参数给出(在下面的情况下,`T:Type`)。 以这种方式定义的补丁称为全对称补丁。 +在这种情况下,要给出自由度的项作为参数给出(在下面的情况下,`T:Type`)。 以这种方式定义的补丁称为全对称补丁。 如您所见,全对称补丁正是一个返回补丁的函数,但它本身也可以被视为补丁。 ```python diff --git a/doc/zh_CN/syntax/type/11_enum.md b/doc/zh_CN/syntax/type/11_enum.md index 7066fdc5..50fd9fe9 100644 --- a/doc/zh_CN/syntax/type/11_enum.md +++ b/doc/zh_CN/syntax/type/11_enum.md @@ -37,7 +37,7 @@ enum Status { Ok, Error } Status = {"Ok", "Error"} ``` -Rust 的不同之处在于它使用了结构子类型(SST)。 +Rust 的不同之处在于它使用了结构子类型(SST)。 ```rust // Status 和 ExtraStatus 之间没有关系。 diff --git a/doc/zh_CN/syntax/type/12_refinement.md b/doc/zh_CN/syntax/type/12_refinement.md index ed5ae22c..7c51a5fb 100644 --- a/doc/zh_CN/syntax/type/12_refinement.md +++ b/doc/zh_CN/syntax/type/12_refinement.md @@ -2,7 +2,7 @@ 细化类型是受谓词表达式约束的类型。 枚举类型和区间类型是细化类型的语法糖。 -细化类型的标准形式是`{Elem: Type | (预)*}`。 这意味着该类型是其元素为满足 `Pred` 的 `Elem` 的类型。 +细化类型的标准形式是`{Elem: Type | (预)*}`。 这意味着该类型是其元素为满足 `Pred` 的 `Elem` 的类型。 可用于筛选类型的类型仅为 [Const type](./advanced/const.md)。 ```python @@ -19,7 +19,7 @@ Array3OrMore == {A: Array _, N | N >= 3} `Odd` 的元素是 `1, 3, 5, 7, 9, ...`。 它被称为细化类型,因为它的元素是现有类型的一部分,就好像它是细化一样。 -`Pred` 被称为(左侧)谓词表达式。 和赋值表达式一样,它不返回有意义的值,左侧只能放置一个模式。 +`Pred` 被称为(左侧)谓词表达式。 和赋值表达式一样,它不返回有意义的值,左侧只能放置一个模式。 也就是说,诸如`X**2 - 5X + 6 == 0`之类的表达式不能用作细化类型的谓词表达式。 在这方面,它不同于右侧的谓词表达式。 ```python @@ -66,7 +66,7 @@ match i: ## 细化模式 -正如 `_: {X}` 可以重写为 `X`(常量模式),`_: {X: T | Pred}` 可以重写为`X: T | Pred` +正如 `_: {X}` 可以重写为 `X`(常量模式),`_: {X: T | Pred}` 可以重写为`X: T | Pred` ```python # 方法 `.m` 是为长度为 3 或更大的数组定义的 diff --git a/doc/zh_CN/syntax/type/14_dependent.md b/doc/zh_CN/syntax/type/14_dependent.md index 6a7c8627..70ef8633 100644 --- a/doc/zh_CN/syntax/type/14_dependent.md +++ b/doc/zh_CN/syntax/type/14_dependent.md @@ -3,7 +3,7 @@ 依赖类型是一个特性,可以说是 Erg 的最大特性。 依赖类型是将值作为参数的类型。 普通的多态类型只能将类型作为参数,但依赖类型放宽了这个限制。 -依赖类型等价于`[T; N]`(`数组(T,N)`)。 +依赖类型等价于`[T; N]`(`数组(T,N)`)。 这种类型不仅取决于内容类型“T”,还取决于内容数量“N”。 `N` 包含一个`Nat` 类型的对象。 ```python @@ -51,7 +51,7 @@ VM!(). self.initialize_something!() self::set_phantom!("running") -# 你也可以按类型参数切出(仅在定义它的模块中) +# 你也可以按类型参数切出(仅在定义它的模块中) VM!.new() = VM!(!"stopped", 1).new() VM!("running" ~> "running").stop!ref!self = self.close_something!() diff --git a/doc/zh_CN/syntax/type/15_quantified.md b/doc/zh_CN/syntax/type/15_quantified.md index 3acba232..fb4af5b7 100644 --- a/doc/zh_CN/syntax/type/15_quantified.md +++ b/doc/zh_CN/syntax/type/15_quantified.md @@ -1,6 +1,6 @@ # 类型变量,量化类型 -类型变量是用于例如指定子程序参数类型的变量,它的类型是任意的(不是单态的)。 +类型变量是用于例如指定子程序参数类型的变量,它的类型是任意的(不是单态的)。 首先,作为引入类型变量的动机,考虑 `id` 函数,它按原样返回输入。 ```python @@ -27,7 +27,7 @@ id(1) + 1 # 类型错误:无法添加 `Object` 和 `Int ``` 要确保输入的类型与返回值的类型相同,请使用 __type 变量__。 -类型变量在`||`(类型变量列表)中声明。 +类型变量在`||`(类型变量列表)中声明。 ```python id|T: Type| x: T = x @@ -36,8 +36,8 @@ assert id("foo") == "foo" assert id(True) == True ``` -这称为函数的 __universal quantification(泛化)__。 有细微的差别,但它对应于其他语言中称为泛型的函数。 泛化函数称为__多态函数__。 -定义一个多态函数就像为所有类型定义一个相同形式的函数(Erg 禁止重载,所以下面的代码真的不能写)。 +这称为函数的 __universal quantification(泛化)__。 有细微的差别,但它对应于其他语言中称为泛型的函数。 泛化函数称为__多态函数__。 +定义一个多态函数就像为所有类型定义一个相同形式的函数(Erg 禁止重载,所以下面的代码真的不能写)。 ```python id|T: Type| x: T = x @@ -51,7 +51,7 @@ id x: NoneType = x ``` 此外,类型变量“T”可以推断为“Type”类型,因为它在类型规范中使用。 所以 `|T: Type|` 可以简单地缩写为 `|T|`。 -你也可以省略`|T, N| 脚; N]` 如果可以推断它不是类型对象(`T: Type, N: Nat`)。 +你也可以省略`|T, N| 脚; N]` 如果可以推断它不是类型对象(`T: Type, N: Nat`)。 如果类型对于任意类型来说太大,您也可以提供约束。 约束也有优势,例如,子类型规范允许使用某些方法。 @@ -86,7 +86,7 @@ f|X, Y, Z| x: X, y: Y, z: Z = x + y + z + x ``` -与许多具有泛型的语言不同,所有声明的类型变量都必须在临时参数列表(`x: X, y: Y, z: Z` 部分)或其他类型变量的参数中使用。 +与许多具有泛型的语言不同,所有声明的类型变量都必须在临时参数列表(`x: X, y: Y, z: Z` 部分)或其他类型变量的参数中使用。 这是 Erg 语言设计的一个要求,即所有类型变量都可以从真实参数中推断出来。 因此,无法推断的信息,例如返回类型,是从真实参数传递的; Erg 允许从实参传递类型。 @@ -121,7 +121,7 @@ f 1 f: Int -> Int = id|Int| ``` -在这种情况下,指定的类型优先于实际参数的类型(匹配失败将导致类型错误,即实际参数的类型错误)。 +在这种情况下,指定的类型优先于实际参数的类型(匹配失败将导致类型错误,即实际参数的类型错误)。 即如果传递的实际对象可以转换为指定的类型,则进行转换; 否则会导致编译错误。 ```python @@ -181,13 +181,13 @@ L(M). .bar(self, x) = ... ``` -每个类型参数不能有多个定义,但可以定义具有相同名称的方法,因为未分配类型参数的依赖类型(非原始类型)和分配的依赖类型(原始类型)之间没有关系 )。 +每个类型参数不能有多个定义,但可以定义具有相同名称的方法,因为未分配类型参数的依赖类型(非原始类型)和分配的依赖类型(原始类型)之间没有关系 )。 ```python K(I: Int) = ... K. - # K 不是真正的类型(atomic Kind),所以我们不能定义方法 - # 这不是方法(更像是静态方法) + # K 不是真正的类型(atomic Kind),所以我们不能定义方法 + # 这不是方法(更像是静态方法) foo(x) = ... K(0). foo(self, x): Nat = ... @@ -211,7 +211,7 @@ print! classof(id) # |T: Type| T -> T assert (|T: Type| T -> T) == (|U: Type| U -> U) ``` -当存在 alpha 等价时,等式得到满足,就像在 lambda 演算中一样。 由于对类型的操作有一些限制,所以总是可以确定等价的(如果我们不考虑 stoppage 属性)。 +当存在 alpha 等价时,等式得到满足,就像在 lambda 演算中一样。 由于对类型的操作有一些限制,所以总是可以确定等价的(如果我们不考虑 stoppage 属性)。 ## 多态函数类型的子类型化 @@ -258,12 +258,12 @@ id_int_fn(f3: Int -> Int): (Int -> Int) = f ## 量化类型和依赖类型 -依赖类型和量化类型(多态函数类型)之间有什么关系,它们之间有什么区别? +依赖类型和量化类型(多态函数类型)之间有什么关系,它们之间有什么区别? 我们可以说依赖类型是一种接受参数的类型,而量化类型是一种赋予参数任意性的类型。 重要的一点是封闭的多态类型本身没有类型参数。例如,多态函数类型`|T| T -> T` 是一个接受多态函数 __only__ 的类型,它的定义是封闭的。您不能使用其类型参数`T`来定义方法等。 -在 Erg 中,类型本身也是一个值,因此带参数的类型(例如函数类型)可能是依赖类型。换句话说,多态函数类型既是量化类型又是依赖类型。 +在 Erg 中,类型本身也是一个值,因此带参数的类型(例如函数类型)可能是依赖类型。换句话说,多态函数类型既是量化类型又是依赖类型。 ```python PolyFn = Patch(|T| T -> T) diff --git a/doc/zh_CN/syntax/type/17_type_casting.md b/doc/zh_CN/syntax/type/17_type_casting.md index bd6abbb1..5fd31369 100644 --- a/doc/zh_CN/syntax/type/17_type_casting.md +++ b/doc/zh_CN/syntax/type/17_type_casting.md @@ -6,7 +6,7 @@ 但是,Erg 是静态类型的,因此有时必须进行强制转换。 一个简单的例子是 `1 + 2.0`:`+`(Int, Ratio) 或 Int(<: Add(Ratio, Ratio)) 操作在 Erg 语言规范中没有定义。这是因为 `Int <: Ratio`,所以 1 向上转换为 1.0,即 Ratio 的一个实例。 -~~ Erg扩展字节码在BINARY_ADD中增加了类型信息,此时类型信息为Ratio-Ratio。在这种情况下,BINARY_ADD 指令执行 Int 的转换,因此没有插入指定转换的特殊指令。因此,例如,即使您在子类中重写了某个方法,如果您将父类指定为类型,则会执行类型强制,并在父类的方法中执行该方法(在编译时执行名称修改以引用父母的方法)。编译器只执行类型强制验证和名称修改。运行时不强制转换对象(当前。可以实现强制转换指令以优化执行)。 ~~ +~~ Erg扩展字节码在BINARY_ADD中增加了类型信息,此时类型信息为Ratio-Ratio。在这种情况下,BINARY_ADD 指令执行 Int 的转换,因此没有插入指定转换的特殊指令。因此,例如,即使您在子类中重写了某个方法,如果您将父类指定为类型,则会执行类型强制,并在父类的方法中执行该方法(在编译时执行名称修改以引用父母的方法)。编译器只执行类型强制验证和名称修改。运行时不强制转换对象(当前。可以实现强制转换指令以优化执行)。 ~~ ```python @Inheritable diff --git a/doc/zh_CN/syntax/type/18_mut.md b/doc/zh_CN/syntax/type/18_mut.md index 02c3dbd4..30f660a2 100644 --- a/doc/zh_CN/syntax/type/18_mut.md +++ b/doc/zh_CN/syntax/type/18_mut.md @@ -60,7 +60,7 @@ K!T: Type = Class ... ## 可变类型 [T; N] # 可以一一改变内容 [T; !N] # 可变长度,内容不可变但可以通过添加/删除元素来修改 -[!T; N] # 内容是不可变的对象,但是可以替换成不同的类型(实际上可以通过不改变类型来替换) +[!T; N] # 内容是不可变的对象,但是可以替换成不同的类型(实际上可以通过不改变类型来替换) [!T; !N] # 类型和长度可以改变 [T; !N] # 内容和长度可以改变 [!T!; N] # 内容和类型可以改变 @@ -99,7 +99,7 @@ a: [!Str; 3] (T, U) # 元素个数不变,内容不能变 ## 可变类型 (T!, U) # 元素个数不变,第一个元素可以改变 -(T,U)! # 元素个数不变,内容可以替换 +(T,U)! # 元素个数不变,内容可以替换 ... ``` @@ -108,7 +108,7 @@ a: [!Str; 3] ## 不可变类型 {T; N} # 不可变元素个数,内容不能改变 ## 可变类型 -{T!; N} # 不可变元素个数,内容可以改变(一个一个) +{T!; N} # 不可变元素个数,内容可以改变(一个一个) {T; N}! # 可变元素个数,内容不能改变 {T!; N}! # 可变元素个数,内容可以改变 ... @@ -119,7 +119,7 @@ a: [!Str; 3] ## 不可变类型 {K: V} # 长度不可变,内容不能改变 ## 可变类型 -{K:V!} # 恒定长度,值可以改变(一一) +{K:V!} # 恒定长度,值可以改变(一一) {K:V}! # 可变长度,内容不能改变,但可以通过添加或删除元素来增加或删除,内容类型也可以改变 ... ``` @@ -134,7 +134,7 @@ a: [!Str; 3] ... ``` -一个类型 `(...)` 简单地变成了 `T! = (...)!` 当 `T = (...)` 被称为简单结构化类型。 简单的结构化类型也可以(语义上)说是没有内部结构的类型。 +一个类型 `(...)` 简单地变成了 `T! = (...)!` 当 `T = (...)` 被称为简单结构化类型。 简单的结构化类型也可以(语义上)说是没有内部结构的类型。 数组、元组、集合、字典和记录类型都是非简单的结构化类型,但 Int 和 Sieve 类型是。 ```python @@ -145,7 +145,7 @@ a: [!Str; 3] ##区间类型 1..12 #1到12,不能改 1..12! # 1-12中的任意一个,你可以改变 -##筛型(普通型) +##筛型(普通型) {I: Int | I % 2 == 0} #偶数类型,不可变 {I: Int | I % 2 == 0} #偶数类型,可以改变 {I: Int | I % 2 == 0}! # 与上面完全相同的类型,但上面的表示法是首选 diff --git a/doc/zh_CN/syntax/type/19_bound.md b/doc/zh_CN/syntax/type/19_bound.md index a7876319..d6aecf50 100644 --- a/doc/zh_CN/syntax/type/19_bound.md +++ b/doc/zh_CN/syntax/type/19_bound.md @@ -1,12 +1,12 @@ # 类型绑定 -类型边界为类型规范添加条件。 实现这一点的函数是守卫(守卫子句)。 +类型边界为类型规范添加条件。 实现这一点的函数是守卫(守卫子句)。 此功能可用于函数签名、匿名函数签名以及筛选类型。 守卫写在返回类型之后。 ## 谓词 -您可以使用返回 `Bool` 的表达式(谓词表达式)指定变量满足的条件。 +您可以使用返回 `Bool` 的表达式(谓词表达式)指定变量满足的条件。 只能使用 [值对象](./08_value.md) 和运算符。 未来版本可能会支持编译时函数 ```python diff --git a/doc/zh_CN/syntax/type/advanced/_rank2type.md b/doc/zh_CN/syntax/type/advanced/_rank2type.md index 40723063..596df334 100644 --- a/doc/zh_CN/syntax/type/advanced/_rank2type.md +++ b/doc/zh_CN/syntax/type/advanced/_rank2type.md @@ -4,7 +4,7 @@ Erg 允许您定义接受各种类型的函数,例如 `id|T|(x: T): T = x`,即多相关。 那么,我们可以定义一个接受多相关的函数吗? -比如这样的函数(注意这个定义是错误的): +比如这样的函数(注意这个定义是错误的): ```python # 我想要 tuple_map(i -> i * 2, (1, "a")) == (2, "aa") @@ -20,7 +20,7 @@ arr = [1, 2, 3] arr.map i -> i + 1 ``` -上面代码中的 `arr` 和 `i` 是不同作用域的变量。 因此,每个寿命都是不同的(`i` 更短)。 +上面代码中的 `arr` 和 `i` 是不同作用域的变量。 因此,每个寿命都是不同的(`i` 更短)。 到目前为止,所有类型变量的类型都具有相同的生命周期。 换句话说,‘T’、‘X’和‘Y’必须同时确定,之后保持不变。 反之,如果我们可以将 `T` 视为“内部作用域”中的类型变量,我们可以组成一个 `tuple_map` 函数。 __Rank 2 type__ 就是为此目的而准备的。 @@ -31,7 +31,7 @@ tuple_map f: (|T: Type| T -> T), tup: (Int, Str) = (f(tup.0), f(tup.1)) assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa") ``` -`{(type) | 形式的类型 (类型变量列表)}` 被称为通用类型(详见[通用类型](./../quantified.md))。 +`{(type) | 形式的类型 (类型变量列表)}` 被称为通用类型(详见[通用类型](./../quantified.md))。 目前我们看到的`id`函数是一个典型的通用函数=多相关函数。 ```python @@ -47,7 +47,7 @@ id: |T: Type| T -> T f1: (T -> T) -> 整数 | T # 接受任何函数并返回 Int 的函数 f2: (|T: Type| T -> T) -> Int # 接收多相关并返回 Int 的函数 f3: Int -> (|T: Type| T -> T) # 一个函数,接受一个 Int 并返回一个封闭的通用函数 -f4: |T: Type|(Int -> (T -> T)) # 同上(首选) +f4: |T: Type|(Int -> (T -> T)) # 同上(首选) ``` `f1` 和 `f2` 不同,而 `f3` 和 `f4` 相同,这似乎很奇怪。 让我们实际构造一个这种类型的函数。 @@ -84,7 +84,7 @@ assert f2 == g2 ``` 开放的多相关函数类型具体称为 __任意函数类型__。 任意函数类型有无数种可能性:`Int -> Int`、`Str -> Str`、`Bool -> Bool`、`|T: Type| T -> T`, ... 是。 -另一方面,只有一个封闭的(返回与参数相同类型的对象)多态类型`|T:Type| T -> T`。 这种类型被专门称为 __多态函数类型__。 +另一方面,只有一个封闭的(返回与参数相同类型的对象)多态类型`|T:Type| T -> T`。 这种类型被专门称为 __多态函数类型__。 也就是说,`f1`可以通过`x: Int -> x+1`、`x: Bool -> not x`、`x -> x`等=`f1`是一个多相关数是的, 但是您只能将 `x -> x` 等传递给 `f2` = `f2` 不是 __多元相关__。 但是像`f2`这样的函数类型明显不同于普通类型,我们需要新的概念来处理它们。 那是类型的“等级”。 @@ -96,7 +96,7 @@ R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0) ``` 接下来,具有一阶全称的类型,例如`|T| T -> T`,或者在返回值类型中包含它们的类型是“rank 1”。 -此外,具有二阶全称量化的类型(具有 rank 1 类型作为参数的类型,例如 `(|T| T -> T) -> Int`)或将它们包含在返回类型中的类型称为“rank 2 ”。 +此外,具有二阶全称量化的类型(具有 rank 1 类型作为参数的类型,例如 `(|T| T -> T) -> Int`)或将它们包含在返回类型中的类型称为“rank 2 ”。 重复上述以定义“Rank N”类型。 此外,秩-N 类型包括秩为N 或更少的所有类型。 因此,混合等级的类型与其中最高的等级相同。 ```python @@ -130,7 +130,7 @@ tuple_map: => R2 ``` -Erg 最多可以处理 rank 2 的类型(因为 rank N 类型包括所有 rank N 或更少的类型,确切地说,所有 Erg 类型都是 rank 2 类型)。 试图构造更多类型的函数是错误的。 +Erg 最多可以处理 rank 2 的类型(因为 rank N 类型包括所有 rank N 或更少的类型,确切地说,所有 Erg 类型都是 rank 2 类型)。 试图构造更多类型的函数是错误的。 例如,所有处理多相关的函数都需要指定其他参数类型。 而且,这样的功能是不可配置的。 ```python diff --git a/doc/zh_CN/syntax/type/advanced/erasure.md b/doc/zh_CN/syntax/type/advanced/erasure.md index 3c751caf..99532ba9 100644 --- a/doc/zh_CN/syntax/type/advanced/erasure.md +++ b/doc/zh_CN/syntax/type/advanced/erasure.md @@ -3,18 +3,18 @@ 类型擦除是将类型参数设置为 `_` 并故意丢弃其信息的过程。类型擦除是许多多态语言的特性,但在 Erg 的语法上下文中,将其称为类型参数擦除更为准确。 类型擦除的最常见示例是 `[T, _]`。数组在编译时并不总是知道它们的长度。例如,引用命令行参数的 `sys.argv` 的类型为 `[Str, _]`。由于 Erg 的编译器无法知道命令行参数的长度,因此必须放弃有关其长度的信息。 -然而,一个已经被类型擦除的类型变成了一个未被擦除的类型的超类型(例如`[T; N] <: [T; _]`),所以它可以接受更多的对象。 +然而,一个已经被类型擦除的类型变成了一个未被擦除的类型的超类型(例如`[T; N] <: [T; _]`),所以它可以接受更多的对象。 类型的对象`[T; N]` 当然可以使用 `[T; _]`,但使用后会删除`N`信息。如果长度没有改变,那么可以使用`[T; N]` 在签名中。如果长度保持不变,则必须由签名指示。 ```python -# 保证不改变数组长度的函数(例如,排序) +# 保证不改变数组长度的函数(例如,排序) f: [T; N] -> [T; N] # 没有的函数 (f: [T; N]) -# 没有的功能(例如过滤器) +# 没有的功能(例如过滤器) g: [T; n] -> [T; _] ``` 如果您在类型规范本身中使用 `_`,则类型将向上转换为 `Object`。 -对于非类型类型参数(Int、Bool 等),带有 `_` 的参数将是未定义的。 +对于非类型类型参数(Int、Bool 等),带有 `_` 的参数将是未定义的。 ```python i: _ # i: Object diff --git a/doc/zh_CN/syntax/type/advanced/kind.md b/doc/zh_CN/syntax/type/advanced/kind.md index 41fa24fe..f0da4035 100644 --- a/doc/zh_CN/syntax/type/advanced/kind.md +++ b/doc/zh_CN/syntax/type/advanced/kind.md @@ -2,7 +2,7 @@ 一切都在 Erg 中输入。类型本身也不例外。 __kind__ 表示“类型的类型”。例如,`Int` 属于 `Type`,就像 `1` 属于 `Int`。 `Type` 是最简单的一种,__atomic kind__。在类型论符号中,`Type` 对应于 `*`。 -在Kind的概念中,实际上重要的是一种或多种Kind(多项式Kind)。单项类型,例如`Option`,属于它。一元Kind表示为 `Type -> Type` [1](#1)。诸如 `Array` 或 `Option` 之类的 __container__ 特别是一种以类型作为参数的多项式类型。 +在Kind的概念中,实际上重要的是一种或多种Kind(多项式Kind)。单项类型,例如`Option`,属于它。一元Kind表示为 `Type -> Type` [1](#1)。诸如 `Array` 或 `Option` 之类的 __container__ 特别是一种以类型作为参数的多项式类型。 正如符号 `Type -> Type` 所表明的,`Option` 实际上是一个接收类型 `T` 并返回类型 `Option T` 的函数。但是,由于这个函数不是通常意义上的函数,所以通常称为一元类。 注意`->`本身,它是一个匿名函数操作符,当它接收一个类型并返回一个类型时,也可以看作是一Kind型。 @@ -134,10 +134,10 @@ Fn2(T, U). 在这种情况下,根据以下优先标准选择修复程序。 -* 任何 `K(T)`(例如 `T or NoneType`)优先匹配 `Type -> Type` 而不是 `Type`。 -* 任何 `K(T, U)`(例如 `T -> U`)优先匹配 `(Type, Type) -> Type` 而不是 `Type`。 +* 任何 `K(T)`(例如 `T or NoneType`)优先匹配 `Type -> Type` 而不是 `Type`。 +* 任何 `K(T, U)`(例如 `T -> U`)优先匹配 `(Type, Type) -> Type` 而不是 `Type`。 * 类似的标准适用于种类 3 或更多。 -* 选择需要较少类型变量来替换的那个。例如,`Int -> Int` 是 `T -> T` 而不是 `K(T, T)`(替换类型变量:K, T)或 `T -> U`(替换类型变量:T, U )。(替换类型变量:T)优先匹配。 +* 选择需要较少类型变量来替换的那个。例如,`Int -> Int` 是 `T -> T` 而不是 `K(T, T)`(替换类型变量:K, T)或 `T -> U`(替换类型变量:T, U )。(替换类型变量:T)优先匹配。 * 如果更换的次数也相同,则报错为不可选择。 --- diff --git a/doc/zh_CN/syntax/type/advanced/mut_struct.md b/doc/zh_CN/syntax/type/advanced/mut_struct.md index 871c8754..e17faa08 100644 --- a/doc/zh_CN/syntax/type/advanced/mut_struct.md +++ b/doc/zh_CN/syntax/type/advanced/mut_struct.md @@ -10,14 +10,14 @@ Particle! ``` `T!` 类型可以替换数据,但不能改变其结构。 -更像是一个真实程序的行为,它不能改变它的大小(在堆上)。 这样的类型称为不可变结构(mutable)类型。 +更像是一个真实程序的行为,它不能改变它的大小(在堆上)。 这样的类型称为不可变结构(mutable)类型。 事实上,有些数据结构不能用不变的结构类型来表示。 例如,可变长度数组。 `[T; N]!`类型可以包含任何`[T; N]`,但不能被`[T; N+1]` 等等。 换句话说,长度不能改变。 要改变长度,必须改变类型本身的结构。 -这是通过可变结构(可变)类型实现的。 +这是通过可变结构(可变)类型实现的。 ```python v = [Str; !0].new() diff --git a/doc/zh_CN/syntax/type/advanced/overloading.md b/doc/zh_CN/syntax/type/advanced/overloading.md index 3d75b07e..373585b0 100644 --- a/doc/zh_CN/syntax/type/advanced/overloading.md +++ b/doc/zh_CN/syntax/type/advanced/overloading.md @@ -1,6 +1,6 @@ # 重载 -Erg 不支持 __ad hoc 多态性__。 也就是说,函数和种类(重载)的多重定义是不可能的。 但是,您可以通过使用特征和补丁的组合来重现重载行为。 +Erg 不支持 __ad hoc 多态性__。 也就是说,函数和种类(重载)的多重定义是不可能的。 但是,您可以通过使用特征和补丁的组合来重现重载行为。 您可以使用特征而不是特征类,但随后将涵盖所有实现 `.add1` 的类型。 ```python @@ -21,7 +21,7 @@ assert add1(1.0) == 2.0 这种接受一个类型的所有子类型的多态称为__subtyping polymorphism__。 -如果每种类型的过程完全相同,则可以编写如下。 当行为从类到类(但返回类型相同)时,使用上述内容。 +如果每种类型的过程完全相同,则可以编写如下。 当行为从类到类(但返回类型相同)时,使用上述内容。 使用类型参数的多态称为 __parametric polymorphism__。 参数多态性通常与子类型结合使用,如下所示,在这种情况下,它是参数和子类型多态性的组合。 ```python diff --git a/doc/zh_CN/syntax/type/advanced/phantom.md b/doc/zh_CN/syntax/type/advanced/phantom.md index 84efb272..14c95749 100644 --- a/doc/zh_CN/syntax/type/advanced/phantom.md +++ b/doc/zh_CN/syntax/type/advanced/phantom.md @@ -19,7 +19,7 @@ List T, N: Nat = Class {head = T; rest = List(T, N-1)} ``` 此错误是在使用 `List(_, 0).new Nil.new()` 时无法推断 `T` 的抱怨。 -在这种情况下,无论 `T` 类型是什么,它都必须在右侧使用。 大小为零的类型(例如长度为零的元组)很方便,因为它没有运行时开销。 +在这种情况下,无论 `T` 类型是什么,它都必须在右侧使用。 大小为零的类型(例如长度为零的元组)很方便,因为它没有运行时开销。 ```python Nil T = Class((T; 0)) List T, 0 = Inherit Nil T @@ -53,4 +53,4 @@ VM!("stopped"). ``` `state` 是通过 `update_phantom!` 或 `set_phantom!` 方法更新的。 -这是标准补丁为`Phantom!`(`Phantom`的变量版本)提供的方法,其用法与变量`update!`和`set!`相同。 \ No newline at end of file +这是标准补丁为`Phantom!`(`Phantom`的变量版本)提供的方法,其用法与变量`update!`和`set!`相同。 \ No newline at end of file diff --git a/doc/zh_CN/syntax/type/advanced/shared.md b/doc/zh_CN/syntax/type/advanced/shared.md index 6b9d34a3..ec294166 100644 --- a/doc/zh_CN/syntax/type/advanced/shared.md +++ b/doc/zh_CN/syntax/type/advanced/shared.md @@ -59,7 +59,7 @@ assert $p3 == 1 ```python $vip_area = SharedCell!.new([].into [VIPMember; !_]) -$normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() #类型错误:预期 SharedCell!([NormalMember;!_]),但得到 SharedCell!([VIPMember;!_]) +$normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() #类型错误:预期 SharedCell!([NormalMember;!_]),但得到 SharedCell!([VIPMember;!_]) # 提示:SharedCell!(T) 是非变体的,这意味着它不能有超类型或子类型。 ``` diff --git a/doc/zh_CN/syntax/type/advanced/special.md b/doc/zh_CN/syntax/type/advanced/special.md index e4a48af6..92cbeb0b 100644 --- a/doc/zh_CN/syntax/type/advanced/special.md +++ b/doc/zh_CN/syntax/type/advanced/special.md @@ -1,6 +1,6 @@ -# 特殊类型(Self、Super) +# 特殊类型(Self、Super) -`Self` 代表它自己的类型。 您可以将其用作别名,但请注意派生类型的含义会发生变化(指的是自己的类型)。 +`Self` 代表它自己的类型。 您可以将其用作别名,但请注意派生类型的含义会发生变化(指的是自己的类型)。 ```python @Inheritable diff --git a/doc/zh_CN/syntax/type/advanced/typeof.md b/doc/zh_CN/syntax/type/advanced/typeof.md index 029cfc94..7fd520cd 100644 --- a/doc/zh_CN/syntax/type/advanced/typeof.md +++ b/doc/zh_CN/syntax/type/advanced/typeof.md @@ -28,15 +28,15 @@ s: Str = ... assert Typeof(s) == {__valueclass_tag__ = Phantom Str} ``` -`Typeof` 仅输出结构化类型。 我解释说结构化类型包括属性类型、筛类型和(真正的)代数类型。 -这些是独立的类型(存在推理优先级),不会发生推理冲突。 +`Typeof` 仅输出结构化类型。 我解释说结构化类型包括属性类型、筛类型和(真正的)代数类型。 +这些是独立的类型(存在推理优先级),不会发生推理冲突。 属性类型和代数类型可以跨越多个类,而筛类型是单个类的子类型。 -Erg 尽可能将对象类型推断为筛类型,如果不可能,则将筛基类扩展为结构化类型(见下文)。 +Erg 尽可能将对象类型推断为筛类型,如果不可能,则将筛基类扩展为结构化类型(见下文)。 ## 结构化的 所有类都可以转换为派生类型。 这称为 __结构化__。 类的结构化类型可以通过 `Structure` 函数获得。 -如果一个类是用`C = Class T`定义的(所有类都以这种形式定义),那么`Structure(C) == T`。 +如果一个类是用`C = Class T`定义的(所有类都以这种形式定义),那么`Structure(C) == T`。 ```python C = Class {i = Int} diff --git a/doc/zh_CN/syntax/type/advanced/variance.md b/doc/zh_CN/syntax/type/advanced/variance.md index 56b0c938..26943813 100644 --- a/doc/zh_CN/syntax/type/advanced/variance.md +++ b/doc/zh_CN/syntax/type/advanced/variance.md @@ -26,7 +26,7 @@ Erg 可以对多态类型进行子类型化,但有一些注意事项。 方法 前者可能看起来很奇怪。即使是 `Str < Object`,包含关系在将其作为参数的函数中也是相反的。 -在类型论中,这种关系(`.push!` 的类型关系)称为逆变,反之,`.pop!` 的类型关系称为协变。 +在类型论中,这种关系(`.push!` 的类型关系)称为逆变,反之,`.pop!` 的类型关系称为协变。 换句话说,函数类型就其参数类型而言是逆变的,而就其返回类型而言是协变的。 这听起来很复杂,但正如我们之前看到的,如果将其应用于实际示例,这是一个合理的规则。 如果您仍然不明白,请考虑以下内容。 @@ -81,9 +81,9 @@ List(T). `List T` 的例子很棘手,所以让我们更详细一点。 要理解上面的代码,你需要了解多态类型退化。 [this section](./variance.md) 中详细讨论了方差,但现在我们需要三个事实: -* 普通的多态类型,例如`List T`,与`T`是协变的(`List U > List T` when `U > T`) -* 函数 `T -> U` 对于参数类型 `T` 是逆变的(`(S -> U) < (T -> U)` when `S > T`) -* 函数 `T -> U` 与返回类型 `U` 是协变的(`(T -> U) > (T -> S)` 当 `U > S` 时) +* 普通的多态类型,例如`List T`,与`T`是协变的(`List U > List T` when `U > T`) +* 函数 `T -> U` 对于参数类型 `T` 是逆变的(`(S -> U) < (T -> U)` when `S > T`) +* 函数 `T -> U` 与返回类型 `U` 是协变的(`(T -> U) > (T -> S)` 当 `U > S` 时) 例如,`List Int` 可以向上转换为 `List Object`,而 `Obj -> Obj` 可以向上转换为 `Int -> Obj`。 @@ -102,8 +102,8 @@ List(T). 即使在这种情况下,Erg 编译器也能很好地推断 `U` 的上下类型。 但是请注意,Erg 编译器不理解方法的语义。编译器只是根据变量和类型变量的使用方式机械地推断和派生类型关系。 -正如评论中所写,放在`List T`的`head`中的`U`类型是`T`的子类(`T:Int`,例如`Nat`)。也就是说,它被推断为 `U <: T`。此约束将 `.push{U}` upcast `(List(T), U) -> List(T) 的参数类型更改为 (List(T), T) -> List(T)`(例如 disallow `列表(整数).push{对象}`)。但是请注意,`U <: T` 约束不会改变函数的类型包含。 `(List(Int), Object) -> List(Int) to (List(Int), Int) -> List(Int)` 的事实并没有改变,只是在 `.push` 方法中表示强制转换无法执行。 -类似地,从 `List T` 到​​ `List U` 的转换可能会受到约束 `U :> T` 的约束,因此可以推断出变体规范。此约束将 `.upcast(U)` 的返回类型更改为向上转换 `List(T) -> List(T) 到 List(T) -> List(T)`(例如 `List(Object) .upcast(Int )`) 被禁止。 +正如评论中所写,放在`List T`的`head`中的`U`类型是`T`的子类(`T:Int`,例如`Nat`)。也就是说,它被推断为 `U <: T`。此约束将 `.push{U}` upcast `(List(T), U) -> List(T) 的参数类型更改为 (List(T), T) -> List(T)`(例如 disallow `列表(整数).push{对象}`)。但是请注意,`U <: T` 约束不会改变函数的类型包含。 `(List(Int), Object) -> List(Int) to (List(Int), Int) -> List(Int)` 的事实并没有改变,只是在 `.push` 方法中表示强制转换无法执行。 +类似地,从 `List T` 到​​ `List U` 的转换可能会受到约束 `U :> T` 的约束,因此可以推断出变体规范。此约束将 `.upcast(U)` 的返回类型更改为向上转换 `List(T) -> List(T) 到 List(T) -> List(T)`(例如 `List(Object) .upcast(Int )`) 被禁止。 现在让我们看看如果我们允许这种向上转换会发生什么。 让我们反转变性名称。 diff --git a/doc/zh_CN/syntax/type/advanced/widening.md b/doc/zh_CN/syntax/type/advanced/widening.md index 282fcb73..91e13f34 100644 --- a/doc/zh_CN/syntax/type/advanced/widening.md +++ b/doc/zh_CN/syntax/type/advanced/widening.md @@ -24,7 +24,7 @@ j: Int or NoneType ids(i, j) # ? ``` -在解释这一点之前,我们必须关注 Erg 的类型系统实际上并不关注(运行时)类这一事实。 +在解释这一点之前,我们必须关注 Erg 的类型系统实际上并不关注(运行时)类这一事实。 ```python 1: {__valueclass_tag__ = Phantom Int} @@ -47,7 +47,7 @@ ids(1, "a"): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phanto i: Int or Str j: Int or NoneType ids(i, j) # 类型错误:i 和 j 的类型不匹配 -# 提示:尝试扩大类型(例如 ids) +# 提示:尝试扩大类型(例如 ids) ids(i, j) # OK ``` @@ -61,7 +61,7 @@ ids(i, j) # OK * `A 或 B == A`:当`A :> B` 或`A == B` 时。 * `A or B == B`:当`A <: B`或`A == B`时。 -* `A 或 B` 是不可约的(独立类型):如果 `!(A :> B)` 和 `!(A <: B)`。 +* `A 或 B` 是不可约的(独立类型):如果 `!(A :> B)` 和 `!(A <: B)`。 ## 子程序定义中的类型扩展 From 8dcbcb4235ba73cd2618fe5407a1ea18f7784da1 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Mon, 5 Sep 2022 21:13:10 +0800 Subject: [PATCH 23/42] Complete Simplified Chinese document translation --- doc/EN/tools/pack.md | 2 +- doc/EN/tools/repl.md | 2 +- doc/zh_CN/faq_general.md | 48 ++++++------- doc/zh_CN/faq_technical.md | 42 ++++++------ doc/zh_CN/improved_points.md | 38 +++++----- doc/zh_CN/index.md | 14 ++-- doc/zh_CN/migration_from_py.md | 8 +-- doc/zh_CN/tips.md | 52 +++++++------- doc/zh_CN/tools/build.md | 20 +++--- doc/zh_CN/tools/env.md | 12 ++-- doc/zh_CN/tools/fmt.md | 6 +- doc/zh_CN/tools/install.md | 14 ++-- doc/zh_CN/tools/pack.md | 122 ++++++++++++++++----------------- doc/zh_CN/tools/repl.md | 8 +-- doc/zh_CN/tools/test.md | 24 +++---- 15 files changed, 206 insertions(+), 206 deletions(-) diff --git a/doc/EN/tools/pack.md b/doc/EN/tools/pack.md index d2e2f561..0e3b23b3 100644 --- a/doc/EN/tools/pack.md +++ b/doc/EN/tools/pack.md @@ -29,7 +29,7 @@ Also see [package_system.md](../syntax/33_package_system.md) for the Erg package /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`. diff --git a/doc/EN/tools/repl.md b/doc/EN/tools/repl.md index b22166c8..84e87e24 100644 --- a/doc/EN/tools/repl.md +++ b/doc/EN/tools/repl.md @@ -1,4 +1,4 @@ -#REPL +# REPL Running the `erg` command with no arguments invokes the REPL. It can also be invoked with the `repl` subcommand. Additionally, you can specify the following flags: diff --git a/doc/zh_CN/faq_general.md b/doc/zh_CN/faq_general.md index 331212e5..c5ab4ee3 100644 --- a/doc/zh_CN/faq_general.md +++ b/doc/zh_CN/faq_general.md @@ -1,37 +1,37 @@ -# Erg FAQ +# 尔格常见问题 -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 初学者。 +对于个别(常见)技术问题,请参阅 [此处](./faq_technical.md) 了解个别(常见)技术问题,以及 +[这里](./dev_guide/faq_syntax.md) 了解更多信息。 -## What does it mean that Erg is a Python compatible language? +## 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.~~ +~~A:Erg的可执行系统EVM(Erg VirtualMachine)执行Erg字节码,是Python字节码的扩展。它在 Python 字节码中引入了静态类型系统和其他特性(例如向不带参数的指令引入参数,以及在自由编号中实现唯一指令)。这让 Erg 可以无缝调用 Python 代码并快速执行。~~ -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). +A: Erg 代码被转译成 Python 字节码。也就是说,它运行在与 Python 相同的解释器上。最初,我们计划开发一个兼容 Cpython 的解释器,并将其与编译器结合起来形成“Erg”。但是,由于处理系统的发展远远落后于编译器,我们决定提前只发布编译器(但解释器仍在开发中)。 -## What languages have influenced Erg? +## 哪些语言影响了尔格? -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、Rust、Nim 和 Haskell 的影响最大。 +我们从 Python 继承了许多语义,从 Rust 继承了面向表达式和 trait,从 Nim 继承了过程,从 Haskell 继承了函数式编程相关的特性。 -## Languages that can call Python include Julia. Why did you create Erg? +## 可以调用 Python 的语言包括 Julia。你为什么创建 Erg? -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 设计的动机之一是拥有一种易于使用且具有强大类型系统的语言。即具有类型推断、种类、依赖类型等的语言。 +Julia 是可以有类型的,但它确实是一种动态类型语言,不具备静态类型语言的编译时错误检测优势。 -## 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."? +## Erg 支持多种编程风格,包括函数式和面向对象的编程。这不是与 Python 的“应该有一种——最好只有一种——明显的方法”相反吗? -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 中,该术语是在更狭窄的上下文中使用的。例如,Erg API 中一般没有别名;在这种情况下,尔格是“唯一一种方式”。 +在更大的上下文中,例如 FP 或 OOP,只有一种做事方式并不一定很方便。 +例如,JavaScript 有几个库可以帮助创建不可变的程序,而 C 有几个用于垃圾收集的库。 +然而,即使是这样的基本功能也有多个库不仅需要时间来选择,而且在集成使用不同库的代码时也会产生很大的困难。 +即使在纯函数式语言 Haskell 中,也有支持 OOP 的库。 +如果程序员没有一些东西,他们会自己创造它们。因此,我们认为将它们作为标准提供会更好。 +这也符合 Python 的“含电池”概念。 -## What is the origin of the name Erg? +## Erg 这个名字的由来是什么? -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. +它以cgs单位系统中的能量单位erg命名。它具有双重含义:一种为程序员提供能量的符合人体工程学的语言。 -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. +还有其他几个候选者,但之所以选择它是因为它最短(根据 Ruby 的开发者 Matz 的说法,语言名称越短越好)并且具有相当高的可搜索性。 \ No newline at end of file diff --git a/doc/zh_CN/faq_technical.md b/doc/zh_CN/faq_technical.md index 896b120a..5c73524e 100644 --- a/doc/zh_CN/faq_technical.md +++ b/doc/zh_CN/faq_technical.md @@ -1,34 +1,34 @@ -# Technical FAQ +# 技术常见问题 -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 语言的技术问题。换句话说,它包含以 What 或 Which 开头的问题,以及可以用 Yes/No 回答的问题。 -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). +有关如何确定语法的更多信息,请参阅 [此处](./dev_guide/faq_syntax.md) 了解基础语法决策,以及 [此处](./dev_guide/../faq_general.md)。 -## Is there an exception mechanism in Erg? +## Erg 中有异常机制吗? -A: No. Erg uses the `Result` type instead. See [here](./dev_guide/faq_syntax.md) for why Erg does not have an exception mechanism. +答:不会。Erg 使用 `Result` 类型代替。请参阅 [此处](./dev_guide/faq_syntax.md) 了解 Erg 没有异常机制的原因。 -## Does Erg have a type equivalent to TypeScript's `Any`? +## Erg 是否有与 TypeScript 的 `Any` 等价的类型? -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''. +答:不,没有。所有对象都至少属于 `Object` 类,但是这种类型只提供了一组最小的属性,所以你不能像使用 Any 那样对它做任何你想做的事情。 +`Object` 类通过`match` 等动态检查转换为所需的类型。它与Java 和其他语言中的`Object` 是同一种。 +在 Erg 世界中,没有像 TypeScript 那样的混乱和绝望,其中 API 定义是“Any”。 -## What is the difference between Never, {}, None, (), NotImplemented, and Ellipsis? +## Never、{}、None、()、NotImplemented 和 Ellipsis 有什么区别? -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:`Never` 是一种“不可能”的类型。产生运行时错误的子例程将“Never”(或“Never”的合并类型)作为其返回类型。该程序将在检测到这一点后立即停止。尽管 `Never` 类型在定义上也是所有类型的子类,但 `Never` 类型的对象永远不会出现在 Erg 代码中,也永远不会被创建。 `{}` 等价于 `Never`。 +`Ellipsis` 是一个表示省略号的对象,来自 Python。 +`NotImplemented` 也来自 Python。它被用作未实现的标记,但 Erg 更喜欢产生错误的 `todo` 函数。 +`None` 是 `NoneType` 的一个实例。它通常与 `Option` 类型一起使用。 +`()` 是一个单元类型和它自己的一个实例。当您想要返回“无意义的值”(例如过程的返回值)时使用它。 -## Why is `x = p!()` valid but `f() = p!()` causes an EffectError? +## 为什么 `x = p!()` 有效但 `f() = p!()` 会导致 EffectError? -`!` 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. +`!` 不是副作用产品的标记,而是可能导致副作用的对象。 +过程 `p!` 和可变类型 `T!` 会引起副作用,但如果 `p!()` 的返回值是 `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? +## 当我尝试使用 Python API 时,对于在 Python 中有效的代码,我在 Erg 中收到类型错误。这是什么意思? -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. +A:Erg API 的类型尽可能接近 Python API 规范,但有些情况无法完全表达。 +此外,根据规范有效但被认为不合需要的输入(例如,在应该输入 int 时输入浮点数)可能会被 Erg 开发团队酌情视为类型错误。 \ No newline at end of file diff --git a/doc/zh_CN/improved_points.md b/doc/zh_CN/improved_points.md index dc8f71e0..b137aad2 100644 --- a/doc/zh_CN/improved_points.md +++ b/doc/zh_CN/improved_points.md @@ -1,13 +1,13 @@ -# Improvements from Python +# 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. +静态类型检查的好处现在怎么强调都不为过,但是检查变量和属性的存在也是相当重要的一部分。 -## 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` 或 `if` 中定义的变量具有外部影响。 不能随便命名变量。 ```python for i in range(10): @@ -16,15 +16,15 @@ for i in range(10): print(x) # 1 ``` -In Erg, all blocks have scope and are completely isolated. +在 Erg 中,所有块都有范围并且是完全隔离的。 -## 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? +# 你能相信这段代码对过去的 Python 版本有效吗? i = 256 assert i is 256 i = 257 @@ -33,16 +33,16 @@ assert i is not 257 ## Traits -Just like Java's interface, you can do contract-based programming. +就像 Java 的接口一样,你可以进行基于契约的编程。 -Python also has ABC (Abstract Base Class), but this kind of structure works best with static typing. +Python 也有 ABC(抽象基类),但这种结构最适合静态类型。 -## 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 +## 内置包管理器 -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. +具有标准化目录结构和构建文件的可重现构建。 +当然提供了锁定文件生成和版本控制。 +无需为每个项目选择或混合anaconda、pyenv、诗歌等。 diff --git a/doc/zh_CN/index.md b/doc/zh_CN/index.md index 0dab9ad3..e35146b5 100644 --- a/doc/zh_CN/index.md +++ b/doc/zh_CN/index.md @@ -1,25 +1,25 @@ -# Index +# 索引 ## [API/](./API/index.md) - This section describes the specifications of subroutines, types, constants, etc. provided by Erg's built-in or standard libraries. + 本节介绍 Erg 的内置或标准库提供的子程序、类型、常量等的规范。 ## [compiler/](./compiler/index.md) - Describes the design of the Erg compiler (Centimetre). + 描述 Erg 编译器的设计(厘米) ## [dev_guide/](./dev_guide/index.md) - It explains the development policy of the project, how to make contributions, etc. + 它解释了项目的发展政策,如何做出贡献等。 ## [python/](./python/index.md) - The knowledge of Python required to develop Erg is explained. + 解释了开发 Erg 所需的 Python 知识。 ## [syntax/](./syntax/00_basic.md) - The syntax of Erg is explained. + Erg 的语法进行了解释。 ## [tools/](./tools/index.md) - Explains how to use Erg's peripheral tools and command options. + 解释如何使用 Erg 的外围工具和命令选项。 \ No newline at end of file diff --git a/doc/zh_CN/migration_from_py.md b/doc/zh_CN/migration_from_py.md index 5e8565e7..abb19725 100644 --- a/doc/zh_CN/migration_from_py.md +++ b/doc/zh_CN/migration_from_py.md @@ -1,8 +1,8 @@ -# Tips for migrating from Python to Erg +# 从 Python 迁移到 Erg 的提示 -## I want to convert a string to int etc. +## 我想将字符串转换为 int 等。 -Use the `parse` method of the `Str` class. It returns a `Result` type. +使用 `Str` 类的 `parse` 方法。 它返回一个 `Result` 类型。 ```python s: str @@ -16,7 +16,7 @@ i: Int = res.unwrap() f: Result(Float, FloatParseError) = s. parse Float ``` -You can also use the `try_from` method. +您还可以使用 `try_from` 方法。 ```python s: Str diff --git a/doc/zh_CN/tips.md b/doc/zh_CN/tips.md index 1baf322d..0646a08a 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 +## 想要更改显示错误的语言 -Please download Erg for your language. -However, external libraries may not support multiple languages. +请为您的语言下载 Erg。 +但是,外部库可能不支持多种语言。 -## Want to change only certain attributes of a record +## 只想更改记录的某些属性 ```python record: {.name = Str; .age = Nat; .height = CentiMeter} @@ -13,21 +13,21 @@ record: {.name = Str; .age = Nat; .height = CentiMeter} mut_record = {.height = !height; ...rest} ``` -## Want to shadow variables +## 想要隐藏变量 -Shadowing in the same scope is not possible with Erg. However, you can redefine them if the scope changes (This is a syntax called instance block). +使用 Erg 无法在相同范围内进行遮蔽。 但是,如果范围发生变化,您可以重新定义它们(这是一种称为实例块的语法)。 ````python -## Get a T!-type object and finally assign it to a variable as type T +## 获取一个 T!-type 对象,最后将它作为 T 类型赋值给一个变量 x: T = x: T! = foo() x.bar!() x.freeze() ```` -## Want to reuse a final class (non-inheritable class) somehow +## 想以某种方式重用最终类(不可继承的类) -You can create a wrapper class. This is a so-called composition pattern. +您可以创建一个包装类。 这就是所谓的构图模式。 ```python FinalWrapper = Class {inner = FinalClass} @@ -37,11 +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. +可以定义其他语言中常见的传统枚举类型(代数数据类型)如下 +如果您实现“单例”,则类和实例是相同的。 +此外,如果您使用 `Enum`,则选择的类型会自动定义为重定向属性。 ```python Ok = Class Impl := Singleton @@ -57,7 +57,7 @@ match! stat: ```python Status = Enum Ok, Err, ErrWithInfo -# is equivalent to +# 相当于 Status = Class Ok or Err or ErrWithInfo Status. Ok = Ok @@ -65,9 +65,9 @@ Status. ErrWithInfo = ErrWithInfo ``` -## I want to enumerate at the beginning of 1 +## 我想在1开头枚举 -method 1: +方法一: ```python arr = [...] @@ -83,10 +83,10 @@ for! arr.iter().zip(1...) , i => ... ``` -## Want to test a (white box) non-public API +## 想要测试一个(白盒)非公共 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. +`foo.er` 中的私有 API 可在 `foo.test.er` 模块中特别访问。 +`foo.test.er` 模块无法导入,因此它保持隐藏状态。 ```python # foo.er @@ -104,9 +104,9 @@ foo = import "foo" ... ``` -## Want to define a (variable) attribute that is read-only from the outside +## 想定义一个从外部只读的(变量)属性 -You can make the attribute private and define a getter. +您可以将属性设为私有并定义一个 getter。 ```python C = Class {v = Int!} @@ -118,9 +118,9 @@ C. ... ``` -## Want the argument names to be identified on the type system +## 希望在类型系统上识别参数名称 -You can receive arguments by record. +您可以按记录接收参数。 ```python Point = {x = Int; y = Int} @@ -130,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 +## 想要停止警告 -There is no option in Erg to stop warnings (this is by design). Please rewrite your code. +Erg 中没有停止警告的选项(这是设计使然)。 请重写你的代码。 diff --git a/doc/zh_CN/tools/build.md b/doc/zh_CN/tools/build.md index e8df33b7..7d28452e 100644 --- a/doc/zh_CN/tools/build.md +++ b/doc/zh_CN/tools/build.md @@ -1,14 +1,14 @@ -# build subcommand +# 构建子命令 -The build subcommand builds the package. -The steps performed in the default build are as follows: +build 子命令构建包。 +默认构建中执行的步骤如下: -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. +1. 检查注释/文档中的代码(doc 下的 md 文件) +2. 编译打包所需的代码。 +3. 对于应用程序包,生成批处理文件或相当于命令的shell脚本。 +4. 运行测试。 -The deliverables after the build is completed are output to the following directory. +构建完成后的交付物输出到以下目录。 -* During debug build: build/debug -* For release build: build/release \ No newline at end of file +* 在调试构建期间:build/debug +* 对于发布构建:build/release \ No newline at end of file diff --git a/doc/zh_CN/tools/env.md b/doc/zh_CN/tools/env.md index 19673686..03d2bd48 100644 --- a/doc/zh_CN/tools/env.md +++ b/doc/zh_CN/tools/env.md @@ -1,7 +1,7 @@ -# env subcommand +# 环境子命令 -The env subcommand specifies the erg execution environment. -Create a new execution environment with `erg env new [env name]`. An interactive tool opens, and when you specify an erg version, that version of erg will be installed (if it already exists, it will be used), and you will be able to use it as a new environment. -You can switch the environment with `erg env switch [env name]`. -The created environment can be edited with `erg env edit` to pre-install packages and specify dependencies for other languages. -The biggest feature of this command is that `erg env export` can output the information that reproduces the environment as `[env name].env.er` file. This allows you to immediately start developing in the same environment as others. Furthermore, `erg env publish` can publish the environment like a package. \ No newline at end of file +env 子命令指定 erg 执行环境。 +使用 `erg env new [env name]` 创建一个新的执行环境。 将打开一个交互式工具,当您指定 erg 版本时,将安装该版本的 erg(如果已存在,将使用它),您将能够将其用作新环境。 +您可以使用 `erg env switch [env name]` 切换环境。 +可以使用 `erg env edit` 编辑创建的环境以预安装软件包并指定其他语言的依赖项。 +该命令最大的特点是`erg env export`可以将重现环境的信息输出为`[env name].env.er`文件。 这使您可以立即开始在与其他人相同的环境中进行开发。 此外,`erg env publish` 可以像包一样发布环境。 \ No newline at end of file diff --git a/doc/zh_CN/tools/fmt.md b/doc/zh_CN/tools/fmt.md index 49f22b63..b24ecae8 100644 --- a/doc/zh_CN/tools/fmt.md +++ b/doc/zh_CN/tools/fmt.md @@ -1,6 +1,6 @@ # fmt -Code formatting can be done with the fmt subcommand. -Commonly used flags are: +可以使用 fmt 子命令来完成代码格式化。 +常用的标志有: -* explicit-type: Automatically completes where the type specification is omitted. \ No newline at end of file +* 显式类型:在省略类型说明的情况下自动完成。 \ No newline at end of file diff --git a/doc/zh_CN/tools/install.md b/doc/zh_CN/tools/install.md index 0343a0ca..fa0a8b5d 100644 --- a/doc/zh_CN/tools/install.md +++ b/doc/zh_CN/tools/install.md @@ -1,10 +1,10 @@ -# install subcommand +# 安装子命令 -You can install packages registered on the registry site with install. -The basic usage is the same as package managers such as cargo. +您可以使用 install 安装在注册表站点上注册的软件包。 +基本用法与cargo等包管理器相同。 -## Convenience functions +## 便利功能 -* If there is a package name with a similar name and the number of downloads is more than 10 times that of that one, a suggestion will appear that you may have entered it incorrectly. This prevents typo squatting. -* If the package size is large (more than 50MB), display the size and suggest if you really want to install it. -* Suggest an alternative package if the package is duplicated. \ No newline at end of file +* 如果有同名的包名,且下载次数超过该包名的10倍以上,会提示可能输入错误。 这可以防止拼写错误。 +* 如果包很大(超过 50MB),请显示大小并建议您是否真的要安装它。 +* 如果包装重复,建议使用替代包装。 \ No newline at end of file diff --git a/doc/zh_CN/tools/pack.md b/doc/zh_CN/tools/pack.md index d2e2f561..9679e502 100644 --- a/doc/zh_CN/tools/pack.md +++ b/doc/zh_CN/tools/pack.md @@ -1,21 +1,21 @@ -# package manager +# 包管理器 -Erg comes standard with a package manager, which you can invoke with the `pack` subcommand. -The following are typical options. +Erg 标配有一个包管理器,您可以使用 `pack` 子命令调用它。 +以下是典型的选项。 -* `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 pack init`:将当前目录初始化为一个包。会生成一个 `package.er` 文件和一个 `src` 目录。指定 `app` 将产生一个可执行包,`lib` 将产生一个库包,而 `hybrid` 将产生两个包。如果指定了 `--license`,将自动放置许可文件。 +* `erg pack build`:构建一个包。使用 `--release` 可以运行和优化测试。工件放置在 `build/debug` 或 `build/release` 中。 +* `erg pack install`:安装一个包。在库的情况下,`src` 被放置在 `.erg/lib` 中,而应用程序作为 shell 脚本被放置在 `.erg/app` 中。使用 `--release` 进行优化。 +* `erg pack run`:构建包并运行应用程序(仅限应用程序包)。 +* `erg pack clean`:删除构建目录的内容。 +* `erg pack test`:运行包测试。有关详细信息,请参阅 [test.md](./test.md)。 +* `erg pack publish`:发布/发布包。您将需要一个 GitHub 帐户和公钥。 -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. +本文档解释了如何管理您自己的包。 +如果要安装或搜索外部包,请参阅 [install.md](./install.md)。 +另请参阅 [package_system.md](../syntax/33_package_system.md) 了解 Erg 包系统。 -## Standard directory structure for the whole package (for application packages) +## 整个包的标准目录结构(对于应用程序包) ```console /package # package root directory @@ -29,72 +29,72 @@ Also see [package_system.md](../syntax/33_package_system.md) for the Erg package /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 pack init` 将生成如下所示的 `package.er` 文件。 `package.er` 描述了包的配置。 +下面是一个`package.er`的例子。 ```python -name = "example" # package name -author = "John Smith" # package author name +name = "example" # package 名称 +author = "John Smith" # package 作者名称 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 +categories = ["cli"] # package 类别 +type = "app" # "app" 或者 "lib" +license = "" # 例如"MIT", "APACHE-2.0", "MIT OR Apache-2.0" +pre_build = "" # 构建前要执行的脚本文件名 +post_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 + # 如果不指定版本,则选择最新的 + # 如果省略版本说明,包管理器会自动将上次成功构建的版本添加到注释中 + foo = pack("foo") # [INFO] 最后成功构建的版本:1.2.1 + # 包可以重命名 + bar1 = pack("bar", "1.*.*") # [INFO] 最后成功构建的版本:1.2.0 + bar2 = pack("bar", "2.*.*") # [INFO] 最后成功构建的版本:2.0.0 baz = pack("baz", "1.1.0") } deprecated=False -successors = [] # alternative packages (when a package is deprecated) +successors = [] # 替代包(当一个包被弃用时) ``` -## Semantic versioning +## 语义版本控制 -Erg packages are versioned based on [semantic versioning](https://semver.org/lang/en/). -Semantic versioning is roughly specified in the format `x.y.z` (x, y, z are integers greater than or equal to 0). -The meaning of each number is as follows. +Erg 包是基于 [语义版本控制](https://semver.org/lang/en/) 进行版本控制的。 +语义版本控制大致以“x.y.z”格式指定(x、y、z 是大于或等于 0 的整数)。 +每个数字的含义如下。 -* 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) +* x:主要版本(更新破坏兼容性时增加 1) +* y:次要版本(执行兼容更新时增加1(API添加,弃用等),错误修复等由补丁版本升级处理) +* z:补丁版本(当进行小的更改以修复错误或保持兼容性时增加1,破坏兼容性的严重修复由主要版本升级处理) -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`. +但是,默认情况下,版本 `0.*.*` 中的更改始终是不兼容的。如果要在保持兼容性的同时升级,请在其后指定 `-compatible`(Erg 自己的规则)。例如,如果要在保持与 0.2.1 兼容的同时添加功能,即要升级到 0.3.0,则指定 0.3.0-compatible。如果您已修复错误,还请指定“0.2.2-compatible”。 +该版本将被视为与以前的版本兼容。 +即使您想将 `0.*.*` 升级到 `1.0.0`,这仍然有效。也就是说,`1.0.0-compatible` 与之前的版本 `0.y.z` 兼容。 -Semantic versioning is very important when generating lockfiles. Lockfiles are files generated to keep dependencies compatible, so that newer releases of dependents depend on older packages unless explicitly updated. -Lockfiles are useful when multiple people are developing a package that has dependent packages. It also saves local storage by allowing packages that depend on them to reuse packages if they are compatible. +生成锁文件时,语义版本控制非常重要。锁定文件是为保持依赖项兼容而生成的文件,因此除非明确更新,否则较新版本的依赖项依赖于较旧的包。 +当多人开发具有依赖包的包时,锁定文件很有用。它还通过允许依赖于它们的包在兼容的情况下重用包来节省本地存储。 -Erg's package manager strictly enforces these rules and will reject package updates that violate them. -The Erg package manager works with version control systems (such as git) to detect code differences and verify the correctness of versioning when a package is published. -Specifically, the package manager looks at the types of the API. A change is considered compatible if the type is a subtype of an older version (note that this is not a full verification; type-compatible but semantically-incompatible significant changes are possible, it is the developer's job to determine this). +Erg 的包管理器严格执行这些规则,并将拒绝违反这些规则的包更新。 +Erg 包管理器与版本控制系统(例如 git)一起使用,以检测代码差异并在发布包时验证版本控制的正确性。 +具体来说,包管理器会查看 API 的类型。如果类型是旧版本的子类型,则认为更改是兼容的(请注意,这不是完整的验证;类型兼容但语义上不兼容的重大更改是可能的,这是开发人员的工作来确定这一点)。 -Furthermore, since the entire package repository is registered in the registry, even developers cannot update the package without going through the package manager. -Also, packages can be deprecated but not removed. +此外,由于整个包存储库都在注册表中注册,即使是开发人员也无法在不通过包管理器的情况下更新包。 +此外,包可以被弃用但不能被删除。 -### Appendix: Semantic Versioning Issues and Countermeasures +### 附录:语义版本控制问题和对策 -There are (at least) two known problems with semantic versioning. -First, semantic versioning can be too restrictive. -With semantic versioning, a single incompatible API change increments the major version of the entire package. -When this happens, things like "I wanted to try a new API, but I have to deal with another incompatible API change, so I won't upgrade". -Second, semantic versioning can promise too much. -As mentioned in the previous section, "compatible changes" to APIs are not theoretically provable. If you specify that you want a package with version `1.0.1`, you can instead use any package between `1.0.1` and `2.0.0` in terms of semantic versioning (`1.0.0` is It can't be used because a bug has been fixed), but there is a possibility that the build will not succeed due to unintended use of the API by the package developer. +语义版本控制存在(至少)两个已知问题。 +首先,语义版本控制可能过于严格。 +使用语义版本控制,单个不兼容的 API 更改会增加整个包的主要版本。 +发生这种情况时,诸如“我想尝试一个新的 API,但我必须处理另一个不兼容的 API 更改,所以我不会升级”之类的事情。 +其次,语义版本控制可以承诺太多。 +如上一节所述,对 API 的“兼容更改”在理论上是不可证明的。如果您指定要使用版本为 `1.0.1` 的包,则可以在语义版本控制方面使用 `1.0.1` 和 `2.0.0` 之间的任何包(`1.0.0` 不能被使用,因为错误已被修复),但由于包开发人员无意使用 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. +Erg 通过允许同时使用不同版本的包(通过重命名)解决了这个问题。这使得在部分引入 ver2 API 的同时继续使用 ver1 API 成为可能。 +此外,虽然这不是一个非常理想的状态,但如果只能使用 API 的某个次要版本而没有错误,则可以不理会它并继续前进到下一个版本。 -## publish +## 发布 -Packages can be published with the `publish` subcommand. Publishing requires a GitHub account. -Packages are registered with `(owner_name)/(package_name)` by default. If you meet certain conditions (number of downloads, frequency of maintenance, etc.), you can apply to register an alias that omits the owner name. -Note that package names are case-insensitive and delimiters such as `_` and `-` are not distinguished. \ No newline at end of file +可以使用 `publish` 子命令发布包。发布需要 GitHub 帐户。 +默认情况下,包使用 `(owner_name)/(package_name)` 注册。如果满足一定条件(下载次数、维护频率等),可以申请注册一个省略所有者名称的别名。 +请注意,包名称不区分大小写,并且不区分诸如 `_` 和 `-` 之类的分隔符。 \ No newline at end of file diff --git a/doc/zh_CN/tools/repl.md b/doc/zh_CN/tools/repl.md index b22166c8..94fab78f 100644 --- a/doc/zh_CN/tools/repl.md +++ b/doc/zh_CN/tools/repl.md @@ -1,9 +1,9 @@ -#REPL +# REPL -Running the `erg` command with no arguments invokes the REPL. It can also be invoked with the `repl` subcommand. -Additionally, you can specify the following flags: +运行不带参数的 `erg` 命令会调用 REPL。 它也可以用 `repl` 子命令调用。 +此外,您可以指定以下标志: -* typed: Show objects and their types. +* typed:显示对象及其类型。 ```console $ erg repl --typed diff --git a/doc/zh_CN/tools/test.md b/doc/zh_CN/tools/test.md index 5844047c..886473f5 100644 --- a/doc/zh_CN/tools/test.md +++ b/doc/zh_CN/tools/test.md @@ -1,11 +1,11 @@ -# test subcommand +# 测试子命令 -The erg command has a subcommand called test, which supports test implementation and execution. +erg 命令有一个名为 test 的子命令,它支持测试的实现和执行。 -## Test decorator (@Test) +## 测试装饰器 (@Test) -Erg tests the `@Test` subroutine in the `tests` directory in the package or in the `*.test.er` file with the `erg test` command. -`tests` subroutines are in charge of black-box testing (not testing private functions), and `*.test.er` subroutines are in charge of white-box testing (testing private functions as well). +Erg 使用 `erg test` 命令测试包中 `tests` 目录或 `*.test.er` 文件中的 `@Test` 子例程。 +`tests` 子例程负责黑盒测试(不测试私有函数),`*.test.er` 子例程负责白盒测试(也测试私有函数)。 ```python # tests/test1.er @@ -16,13 +16,13 @@ test_1_plus_n(n: Nat) = assert add(1, n) == n + 1 ``` -The execution result is displayed as a summary and can be output in various file formats (.md, .csv, etc.). +执行结果以摘要形式显示,可以以各种文件格式(.md、.csv 等)输出。 -## Doc Test +## 文档测试 -In Erg, `#` and `#[` are comment lines, but `##` and `#[[` are doc comments, and comments can be displayed as markdown from editors such as VSCode. -Furthermore, the source code in the doc comment is automatically tested with the erg test command if erg is specified. -Below is an example test. +在 Erg 中,`#` 和 `#[` 是注释行,但 `##` 和 `#[[` 是 doc 注释,并且注释可以从 VSCode 等编辑器显示为 markdown。 +此外,如果指定了 erg,则使用 erg test 命令自动测试文档注释中的源代码。 +下面是一个示例测试。 ```python VMs =... @@ -30,7 +30,7 @@ VMs =... #[[ execute commands. ```python - # VM in standard configuration + # 标准配置的虚拟机 {vm1; ...} = import "tests/mock" assert vm1.exec!("i = 0") == None @@ -42,4 +42,4 @@ VMs =... ... ``` -Mock objects (mock objects) used for testing are defined in the `tests/mock` module. \ No newline at end of file +用于测试的模拟对象(mock objects)在 `tests/mock` 模块中定义。 \ No newline at end of file From 244fe475962d5339d45d454a91dd8804ae92cf22 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Mon, 5 Sep 2022 21:14:09 +0800 Subject: [PATCH 24/42] Start Traditional Chinese Translation --- 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 | 72 ++ 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 | 42 + 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 | 438 +++++++++ doc/zh_TW/compiler/overview.md | 36 + doc/zh_TW/compiler/parsing.md | 33 + doc/zh_TW/compiler/refinement_subtyping.md | 147 +++ doc/zh_TW/compiler/trait_method_resolving.md | 95 ++ doc/zh_TW/compiler/transpile.md | 90 ++ doc/zh_TW/compiler/type_var_normalization.md | 39 + doc/zh_TW/dev_guide/branches.md | 35 + doc/zh_TW/dev_guide/build_features.md | 21 + 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 | 106 +++ 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 | 838 ++++++++++++++++++ doc/zh_TW/dev_guide/unify_terms.md | 56 ++ doc/zh_TW/faq_general.md | 37 + doc/zh_TW/faq_technical.md | 34 + doc/zh_TW/improved_points.md | 48 + doc/zh_TW/index.md | 25 + doc/zh_TW/migration_from_py.md | 25 + doc/zh_TW/python/bytecode_instructions.md | 116 +++ doc/zh_TW/python/bytecode_specification.md | 144 +++ doc/zh_TW/python/class_system.md | 94 ++ doc/zh_TW/python/index.md | 0 doc/zh_TW/syntax/00_basic.md | 148 ++++ doc/zh_TW/syntax/01_literal.md | 150 ++++ doc/zh_TW/syntax/02_name.md | 164 ++++ doc/zh_TW/syntax/03_declaration.md | 47 + doc/zh_TW/syntax/04_function.md | 290 ++++++ doc/zh_TW/syntax/05_builtin_funcs.md | 49 + doc/zh_TW/syntax/06_operator.md | 29 + doc/zh_TW/syntax/07_side_effect.md | 121 +++ doc/zh_TW/syntax/08_procedure.md | 12 + doc/zh_TW/syntax/09_builtin_procs.md | 14 + doc/zh_TW/syntax/10_array.md | 52 ++ doc/zh_TW/syntax/11_tuple.md | 116 +++ doc/zh_TW/syntax/12_dict.md | 67 ++ doc/zh_TW/syntax/13_record.md | 199 +++++ doc/zh_TW/syntax/14_set.md | 45 + doc/zh_TW/syntax/15_type.md | 7 + doc/zh_TW/syntax/16_iterator.md | 89 ++ doc/zh_TW/syntax/17_mutability.md | 103 +++ doc/zh_TW/syntax/18_ownership.md | 110 +++ doc/zh_TW/syntax/19_visibility.md | 191 ++++ doc/zh_TW/syntax/20_naming_rule.md | 50 ++ doc/zh_TW/syntax/21_lambda.md | 96 ++ doc/zh_TW/syntax/22_subroutine.md | 62 ++ doc/zh_TW/syntax/23_closure.md | 96 ++ doc/zh_TW/syntax/24_module.md | 42 + doc/zh_TW/syntax/25_object_system.md | 82 ++ doc/zh_TW/syntax/26_pattern_matching.md | 193 ++++ doc/zh_TW/syntax/27_comprehension.md | 65 ++ doc/zh_TW/syntax/28_spread_syntax.md | 42 + doc/zh_TW/syntax/29_decorator.md | 120 +++ doc/zh_TW/syntax/30_error_handling.md | 108 +++ doc/zh_TW/syntax/31_pipeline.md | 32 + .../syntax/32_integration_with_Python.md | 83 ++ doc/zh_TW/syntax/33_package_system.md | 83 ++ doc/zh_TW/syntax/34_generator.md | 35 + doc/zh_TW/syntax/SUMMARY.md | 69 ++ doc/zh_TW/syntax/container_ownership.md | 42 + doc/zh_TW/syntax/grammar.md | 90 ++ doc/zh_TW/syntax/indexes.md | 452 ++++++++++ doc/zh_TW/syntax/quick_tour.md | 267 ++++++ doc/zh_TW/syntax/type/01_type_system.md | 228 +++++ doc/zh_TW/syntax/type/02_basic.md | 161 ++++ doc/zh_TW/syntax/type/03_trait.md | 187 ++++ doc/zh_TW/syntax/type/04_class.md | 287 ++++++ doc/zh_TW/syntax/type/05_inheritance.md | 253 ++++++ doc/zh_TW/syntax/type/06_nst_vs_sst.md | 43 + doc/zh_TW/syntax/type/07_patch.md | 222 +++++ doc/zh_TW/syntax/type/08_value.md | 37 + doc/zh_TW/syntax/type/09_attributive.md | 9 + doc/zh_TW/syntax/type/10_interval.md | 36 + doc/zh_TW/syntax/type/11_enum.md | 85 ++ doc/zh_TW/syntax/type/12_refinement.md | 75 ++ doc/zh_TW/syntax/type/13_algebraic.md | 85 ++ doc/zh_TW/syntax/type/14_dependent.md | 74 ++ doc/zh_TW/syntax/type/15_quantified.md | 280 ++++++ doc/zh_TW/syntax/type/16_subtyping.md | 76 ++ doc/zh_TW/syntax/type/17_type_casting.md | 72 ++ doc/zh_TW/syntax/type/18_mut.md | 163 ++++ doc/zh_TW/syntax/type/19_bound.md | 18 + doc/zh_TW/syntax/type/advanced.md | 1 + doc/zh_TW/syntax/type/advanced/GADTs.md | 66 ++ doc/zh_TW/syntax/type/advanced/_rank2type.md | 142 +++ .../syntax/type/advanced/default_param.md | 28 + doc/zh_TW/syntax/type/advanced/erasure.md | 43 + doc/zh_TW/syntax/type/advanced/existential.md | 41 + .../syntax/type/advanced/keyword_param.md | 26 + doc/zh_TW/syntax/type/advanced/kind.md | 147 +++ .../syntax/type/advanced/marker_trait.md | 31 + 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 | 90 ++ doc/zh_TW/syntax/type/advanced/phantom.md | 56 ++ doc/zh_TW/syntax/type/advanced/projection.md | 24 + .../type/advanced/quantified_dependent.md | 27 + doc/zh_TW/syntax/type/advanced/shared.md | 72 ++ doc/zh_TW/syntax/type/advanced/special.md | 51 ++ doc/zh_TW/syntax/type/advanced/typeof.md | 65 ++ doc/zh_TW/syntax/type/advanced/variance.md | 142 +++ doc/zh_TW/syntax/type/advanced/widening.md | 92 ++ doc/zh_TW/tips.md | 135 +++ doc/zh_TW/tools/build.md | 14 + doc/zh_TW/tools/env.md | 7 + doc/zh_TW/tools/fmt.md | 6 + doc/zh_TW/tools/index.md | 0 doc/zh_TW/tools/install.md | 10 + doc/zh_TW/tools/pack.md | 100 +++ doc/zh_TW/tools/repl.md | 15 + doc/zh_TW/tools/test.md | 45 + 187 files changed, 12418 insertions(+) create mode 100644 doc/zh_TW/API/consts.md create mode 100644 doc/zh_TW/API/funcs.md create mode 100644 doc/zh_TW/API/index.md create mode 100644 doc/zh_TW/API/modules/external/alstruct.md create mode 100644 doc/zh_TW/API/modules/repl.md create mode 100644 doc/zh_TW/API/modules/status.md create mode 100644 doc/zh_TW/API/modules/unit.md create mode 100644 doc/zh_TW/API/modules/unsound.md create mode 100644 doc/zh_TW/API/operators.md create mode 100644 doc/zh_TW/API/procs.md create mode 100644 doc/zh_TW/API/special.md create mode 100644 doc/zh_TW/API/types.md create mode 100644 doc/zh_TW/API/types/classes/Array!(T).md create mode 100644 doc/zh_TW/API/types/classes/Array(T).md create mode 100644 doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md create mode 100644 doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md create mode 100644 doc/zh_TW/API/types/classes/Class.md create mode 100644 doc/zh_TW/API/types/classes/Complex.md create mode 100644 doc/zh_TW/API/types/classes/Dict!.md create mode 100644 doc/zh_TW/API/types/classes/Either.md create mode 100644 doc/zh_TW/API/types/classes/Float.md create mode 100644 doc/zh_TW/API/types/classes/Function(N).md create mode 100644 doc/zh_TW/API/types/classes/Inf.md create mode 100644 doc/zh_TW/API/types/classes/Int.md create mode 100644 doc/zh_TW/API/types/classes/IntRange.md create mode 100644 doc/zh_TW/API/types/classes/Interval.md create mode 100644 doc/zh_TW/API/types/classes/Iterator.md create mode 100644 doc/zh_TW/API/types/classes/Kind(N).md create mode 100644 doc/zh_TW/API/types/classes/Matrix.md create mode 100644 doc/zh_TW/API/types/classes/Module.md create mode 100644 doc/zh_TW/API/types/classes/Nat.md create mode 100644 doc/zh_TW/API/types/classes/Neg.md create mode 100644 doc/zh_TW/API/types/classes/Never.md create mode 100644 doc/zh_TW/API/types/classes/NonZero.md create mode 100644 doc/zh_TW/API/types/classes/Object.md create mode 100644 doc/zh_TW/API/types/classes/Operator.md create mode 100644 doc/zh_TW/API/types/classes/Option.md create mode 100644 doc/zh_TW/API/types/classes/Pos.md create mode 100644 doc/zh_TW/API/types/classes/Ratio.md create mode 100644 doc/zh_TW/API/types/classes/Record.md create mode 100644 doc/zh_TW/API/types/classes/Result.md create mode 100644 doc/zh_TW/API/types/classes/Str!.md create mode 100644 doc/zh_TW/API/types/classes/Str.md create mode 100644 doc/zh_TW/API/types/classes/StrWithLen.md create mode 100644 doc/zh_TW/API/types/classes/Subroutine.md create mode 100644 doc/zh_TW/API/types/classes/Tensor.md create mode 100644 doc/zh_TW/API/types/classes/TransCell(T).md create mode 100644 doc/zh_TW/API/types/classes/Tuple.md create mode 100644 doc/zh_TW/API/types/classes/Type.md create mode 100644 doc/zh_TW/API/types/classes/Vector.md create mode 100644 doc/zh_TW/API/types/patches/BinOp.md create mode 100644 doc/zh_TW/API/types/patches/UnaryOp.md create mode 100644 doc/zh_TW/API/types/traits/Add(R,O).md create mode 100644 doc/zh_TW/API/types/traits/Div(R,O).md create mode 100644 doc/zh_TW/API/types/traits/Eq.md create mode 100644 doc/zh_TW/API/types/traits/Into.md create mode 100644 doc/zh_TW/API/types/traits/Iterable.md create mode 100644 doc/zh_TW/API/types/traits/Num.md create mode 100644 doc/zh_TW/API/types/traits/Ord.md create mode 100644 doc/zh_TW/API/types/traits/SafeDiv(R,O).md create mode 100644 doc/zh_TW/API/types/traits/Sample.md create mode 100644 doc/zh_TW/API/types/traits/Seq.md create mode 100644 doc/zh_TW/API/types/traits/Show.md create mode 100644 doc/zh_TW/API/types/traits/Unpack.md create mode 100644 doc/zh_TW/compiler/TODO_hint.md create mode 100644 doc/zh_TW/compiler/TODO_recov_suggest.md create mode 100644 doc/zh_TW/compiler/TODO_warn.md create mode 100644 doc/zh_TW/compiler/abandoned.md create mode 100644 doc/zh_TW/compiler/architecture.md create mode 100644 doc/zh_TW/compiler/errors.md create mode 100644 doc/zh_TW/compiler/hir.md create mode 100644 doc/zh_TW/compiler/index.md create mode 100644 doc/zh_TW/compiler/inference.md create mode 100644 doc/zh_TW/compiler/overview.md create mode 100644 doc/zh_TW/compiler/parsing.md create mode 100644 doc/zh_TW/compiler/refinement_subtyping.md create mode 100644 doc/zh_TW/compiler/trait_method_resolving.md create mode 100644 doc/zh_TW/compiler/transpile.md create mode 100644 doc/zh_TW/compiler/type_var_normalization.md create mode 100644 doc/zh_TW/dev_guide/branches.md create mode 100644 doc/zh_TW/dev_guide/build_features.md create mode 100644 doc/zh_TW/dev_guide/directories.md create mode 100644 doc/zh_TW/dev_guide/doc_guideline.md create mode 100644 doc/zh_TW/dev_guide/env.md create mode 100644 doc/zh_TW/dev_guide/faq_syntax.md create mode 100644 doc/zh_TW/dev_guide/i18n_messages.md create mode 100644 doc/zh_TW/dev_guide/index.md create mode 100644 doc/zh_TW/dev_guide/rust_code_guideline.md create mode 100644 doc/zh_TW/dev_guide/terms.md create mode 100644 doc/zh_TW/dev_guide/unify_terms.md create mode 100644 doc/zh_TW/faq_general.md create mode 100644 doc/zh_TW/faq_technical.md create mode 100644 doc/zh_TW/improved_points.md create mode 100644 doc/zh_TW/index.md create mode 100644 doc/zh_TW/migration_from_py.md create mode 100644 doc/zh_TW/python/bytecode_instructions.md create mode 100644 doc/zh_TW/python/bytecode_specification.md create mode 100644 doc/zh_TW/python/class_system.md create mode 100644 doc/zh_TW/python/index.md create mode 100644 doc/zh_TW/syntax/00_basic.md create mode 100644 doc/zh_TW/syntax/01_literal.md create mode 100644 doc/zh_TW/syntax/02_name.md create mode 100644 doc/zh_TW/syntax/03_declaration.md create mode 100644 doc/zh_TW/syntax/04_function.md create mode 100644 doc/zh_TW/syntax/05_builtin_funcs.md create mode 100644 doc/zh_TW/syntax/06_operator.md create mode 100644 doc/zh_TW/syntax/07_side_effect.md create mode 100644 doc/zh_TW/syntax/08_procedure.md create mode 100644 doc/zh_TW/syntax/09_builtin_procs.md create mode 100644 doc/zh_TW/syntax/10_array.md create mode 100644 doc/zh_TW/syntax/11_tuple.md create mode 100644 doc/zh_TW/syntax/12_dict.md create mode 100644 doc/zh_TW/syntax/13_record.md create mode 100644 doc/zh_TW/syntax/14_set.md create mode 100644 doc/zh_TW/syntax/15_type.md create mode 100644 doc/zh_TW/syntax/16_iterator.md create mode 100644 doc/zh_TW/syntax/17_mutability.md create mode 100644 doc/zh_TW/syntax/18_ownership.md create mode 100644 doc/zh_TW/syntax/19_visibility.md create mode 100644 doc/zh_TW/syntax/20_naming_rule.md create mode 100644 doc/zh_TW/syntax/21_lambda.md create mode 100644 doc/zh_TW/syntax/22_subroutine.md create mode 100644 doc/zh_TW/syntax/23_closure.md create mode 100644 doc/zh_TW/syntax/24_module.md create mode 100644 doc/zh_TW/syntax/25_object_system.md create mode 100644 doc/zh_TW/syntax/26_pattern_matching.md create mode 100644 doc/zh_TW/syntax/27_comprehension.md create mode 100644 doc/zh_TW/syntax/28_spread_syntax.md create mode 100644 doc/zh_TW/syntax/29_decorator.md create mode 100644 doc/zh_TW/syntax/30_error_handling.md create mode 100644 doc/zh_TW/syntax/31_pipeline.md create mode 100644 doc/zh_TW/syntax/32_integration_with_Python.md create mode 100644 doc/zh_TW/syntax/33_package_system.md create mode 100644 doc/zh_TW/syntax/34_generator.md create mode 100644 doc/zh_TW/syntax/SUMMARY.md create mode 100644 doc/zh_TW/syntax/container_ownership.md create mode 100644 doc/zh_TW/syntax/grammar.md create mode 100644 doc/zh_TW/syntax/indexes.md create mode 100644 doc/zh_TW/syntax/quick_tour.md create mode 100644 doc/zh_TW/syntax/type/01_type_system.md create mode 100644 doc/zh_TW/syntax/type/02_basic.md create mode 100644 doc/zh_TW/syntax/type/03_trait.md create mode 100644 doc/zh_TW/syntax/type/04_class.md create mode 100644 doc/zh_TW/syntax/type/05_inheritance.md create mode 100644 doc/zh_TW/syntax/type/06_nst_vs_sst.md create mode 100644 doc/zh_TW/syntax/type/07_patch.md create mode 100644 doc/zh_TW/syntax/type/08_value.md create mode 100644 doc/zh_TW/syntax/type/09_attributive.md create mode 100644 doc/zh_TW/syntax/type/10_interval.md create mode 100644 doc/zh_TW/syntax/type/11_enum.md create mode 100644 doc/zh_TW/syntax/type/12_refinement.md create mode 100644 doc/zh_TW/syntax/type/13_algebraic.md create mode 100644 doc/zh_TW/syntax/type/14_dependent.md create mode 100644 doc/zh_TW/syntax/type/15_quantified.md create mode 100644 doc/zh_TW/syntax/type/16_subtyping.md create mode 100644 doc/zh_TW/syntax/type/17_type_casting.md create mode 100644 doc/zh_TW/syntax/type/18_mut.md create mode 100644 doc/zh_TW/syntax/type/19_bound.md create mode 100644 doc/zh_TW/syntax/type/advanced.md create mode 100644 doc/zh_TW/syntax/type/advanced/GADTs.md create mode 100644 doc/zh_TW/syntax/type/advanced/_rank2type.md create mode 100644 doc/zh_TW/syntax/type/advanced/default_param.md create mode 100644 doc/zh_TW/syntax/type/advanced/erasure.md create mode 100644 doc/zh_TW/syntax/type/advanced/existential.md create mode 100644 doc/zh_TW/syntax/type/advanced/keyword_param.md create mode 100644 doc/zh_TW/syntax/type/advanced/kind.md create mode 100644 doc/zh_TW/syntax/type/advanced/marker_trait.md create mode 100644 doc/zh_TW/syntax/type/advanced/mut_struct.md create mode 100644 doc/zh_TW/syntax/type/advanced/newtype.md create mode 100644 doc/zh_TW/syntax/type/advanced/overloading.md create mode 100644 doc/zh_TW/syntax/type/advanced/phantom.md create mode 100644 doc/zh_TW/syntax/type/advanced/projection.md create mode 100644 doc/zh_TW/syntax/type/advanced/quantified_dependent.md create mode 100644 doc/zh_TW/syntax/type/advanced/shared.md create mode 100644 doc/zh_TW/syntax/type/advanced/special.md create mode 100644 doc/zh_TW/syntax/type/advanced/typeof.md create mode 100644 doc/zh_TW/syntax/type/advanced/variance.md create mode 100644 doc/zh_TW/syntax/type/advanced/widening.md create mode 100644 doc/zh_TW/tips.md create mode 100644 doc/zh_TW/tools/build.md create mode 100644 doc/zh_TW/tools/env.md create mode 100644 doc/zh_TW/tools/fmt.md create mode 100644 doc/zh_TW/tools/index.md create mode 100644 doc/zh_TW/tools/install.md create mode 100644 doc/zh_TW/tools/pack.md create mode 100644 doc/zh_TW/tools/repl.md create mode 100644 doc/zh_TW/tools/test.md diff --git a/doc/zh_TW/API/consts.md b/doc/zh_TW/API/consts.md new file mode 100644 index 00000000..b42e2f5b --- /dev/null +++ b/doc/zh_TW/API/consts.md @@ -0,0 +1,13 @@ +# 内置常量 + +## True + +## False + +## None + +## Ellipsis + +## NotImplemented + +## Inf diff --git a/doc/zh_TW/API/funcs.md b/doc/zh_TW/API/funcs.md new file mode 100644 index 00000000..0a97634e --- /dev/null +++ b/doc/zh_TW/API/funcs.md @@ -0,0 +1,121 @@ +# 功能 + +## 基本功能 + +### if|T; U|(cond: Bool, then: T, else: U) -> T or U + +### map|T; U|(i: Iterable T, f: T -> U) -> Map U + +请注意,参数的顺序与 Python 相反 + +### log(x: Object, type: LogType = Info) -> None + +在调试显示中记录“x”。 执行完成后汇总并显示日志 +支持表情符号的终端根据“类型”添加前缀 + +* type == Info: 💬 +* type == Ok: ✅ +* type == Warn: ⚠️ +* type == Hint: 💡 + +### panic(msg: Str) -> Panic + +显示msg并停止。 +支持表情符号的终端有一个🚨前缀。 + +### discard|T|(x: ...T) -> NoneType + +扔掉`x`。不使用返回值时使用。与 `del` 不同,它不会使变量 `x` 不可访问 + +```python +p! x = + # q!应该返回一些不是None或()的值 + # 如果不需要,请使用`discard` + discard q!(x) + f x + +discard True +assert True # OK +``` + +### import(path: Path) -> Module or CompilerPanic + +导入一个模块。如果找不到模块,则引发编译错误 + +### eval(code: Str) -> Object + +将`code`作为代码进行评估并返回。 + +### classof(object: Object) -> Class + +返回`object`的类。 +但是,由于无法比较类,如果要判断实例,请使用`object in Class`而不是`classof(object) == Class` +编译时确定的结构类型是通过`Typeof`获得的 + +## Iterator, Array生成系统 + +### repeat|T|(x: T) -> RepeatIterator T + +```python +rep = repeat 1 # Repeater(1) +for! rep, i => + print! i +# 1 1 1 1 1 ... +``` + +### dup|T; N|(x: T, N: Nat) -> [T; N] + +```python +[a, b, c] = dup new(), 3 +print! a # +print! a == b # False +``` + +### cycle|T|(it: Iterable T) -> CycleIterator T + +```python +cycle([0, 1]).take 4 # [0, 1, 0, 1] +cycle("hello").take 3 # "hellohellohello" +``` + +## 定数式関数 + +### Class + +创建一个新类。 与`Inherit`不同,通过`Class`传递与基类型无关,并且方法会丢失 +您将无法进行比较,但您可以进行模式匹配等操作 + +```python +C = Class {i = Int} +NewInt = Class Int +Months = Class 1..12 +jan = Months.new(1) +jan + Months.new(2) # TypeError: `+` is not implemented for 'Months' +match jan: + 1 -> log "January" + _ -> log "Other" +``` + +第二个参数 Impl 是要实现的特征 + +### Inherit + +继承一个类。您可以按原样使用基类方法 + +### Trait + +创造一个新的特质。目前,只能指定记录类型 + +### Typeof + +返回参数类型。如果要获取运行时类,请使用`classof`。 +如果您将其用于类型规范,则会出现警告。 + +```python +x: Typeof i = ... +# TypeWarning: Typeof(i) == Int, please replace it +``` + +### Deprecated + +作为解码器使用。警告不推荐使用的类型或函数 \ No newline at end of file diff --git a/doc/zh_TW/API/index.md b/doc/zh_TW/API/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/modules/external/alstruct.md b/doc/zh_TW/API/modules/external/alstruct.md new file mode 100644 index 00000000..bfbf7a1b --- /dev/null +++ b/doc/zh_TW/API/modules/external/alstruct.md @@ -0,0 +1,57 @@ +# 结构 + +模块为它们提供代表代数结构和补丁的特征 + +* 成员 + +## 二进制运算 + +```python +BinOp Op: Kind 2 = Subsume Op(Self, Self.ReturnTypeOf Op), Additional: { + .ReturnTypeof = TraitType -> Type +} + +Nat <: BinOp Add +assert Nat. ReturnTypeof(Add) == Nat +assert Nat. ReturnTypeof(Sub) == Int +assert Nat. ReturnTypeof(Mul) == Nat +assert Nat.ReturnTypeof(Div) == Positive Ratio +``` + +## 半群(一个二元运算的代数系统) + +```python +SemiGroup Op: Kind 2 = Op(Self, Self) + +IntIsSemiGroupAdd = Patch Int, Impl=SemiGroupAdd + +Int <: SemiGroup Add +``` + +## 函子 + +```python +# * Identity law: x.map(id) == x +# * Composition law: x.map(f).map(g) == x.map(f.then g) +Functor = Trait { + .map|T, U: Type| = (Self(T), T -> U) -> Self U +} +``` + +## 应用 + +```python +# * Identity law: x.app(X.pure(id)) == x +Applicative = Subsume Functor, Additional: { + .pure|T: Type| = T -> Self T + .app|T, U: Type| = (Self(T), Self(T -> U)) -> Self U +} +``` + +## 单子(交互式命令行工具以及面向对象的脚本技术) + +```python +Monad = Subsume Applicative, Additional: { + .bind|T, U: Type| = (Self(T), T -> Self U) -> Self U +} +``` \ No newline at end of file diff --git a/doc/zh_TW/API/modules/repl.md b/doc/zh_TW/API/modules/repl.md new file mode 100644 index 00000000..0395afcb --- /dev/null +++ b/doc/zh_TW/API/modules/repl.md @@ -0,0 +1,24 @@ +# 模块`repl` + +提供REPL(Read-Eval-Print-Loop)相关的API。 + +## 功能 + +* `gui_help` + +在浏览器中查看有关对象的信息。 可以离线使用。 + +## 类型 + +### 猜测 = 对象 + +#### 方法 + +* `.guess` + +在给定参数和返回值的情况下推断函数。 + +```python +1.guess((1,), 2) # +[1, 2].guess((3, 4), [1, 2, 3, 4]) # +``` \ No newline at end of file diff --git a/doc/zh_TW/API/modules/status.md b/doc/zh_TW/API/modules/status.md new file mode 100644 index 00000000..1e65ebd8 --- /dev/null +++ b/doc/zh_TW/API/modules/status.md @@ -0,0 +1,6 @@ + # 模块`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 new file mode 100644 index 00000000..179b55f0 --- /dev/null +++ b/doc/zh_TW/API/modules/unit.md @@ -0,0 +1,72 @@ +# 模块`unit` + +`unit` 模块是将数值计算中经常使用的单位定义为类型的模块。 +Erg 数值类型包括 `Nat`、`Int`、`Ratio` 等。但是,这些类型没有关于“数字的含义”的信息,因此可以执行诸如添加米和码之类的无意义计算。 +通过使用 `unit` 模块,您可以避免错误,例如将不同单位的数字传递给函数。 +这样的错误确实会发生,并且会导致诸如[由于错误的单位系统导致火星探测器丢失](http://www.sydrose.com/case100/287/)之类的严重错误。 +如果您希望代码在进行数值计算时更加健壮,您应该使用此模块。 + +```python +{*} = import "unit" + +x = 6m # 相当于 `x = Meter.new(6)` +t = 3s # 相当于 `t = Sec.new(3)` +#m/s是速度单位对象,类型为velocity +print! x/t # 2m/s +print! x + 4m # 10m +print! x + 2s # 类型错误: `+`(Meter, Sec) 未实现 +``` +对象`m`、`s`和`m/s`被称为单元对象。它本身具有1m、1s、1m/s的含义。 `m/s`可以说是结合m和s创建的单位对象。 + +在单元中,以下单元被定义为类型。它被称为SI(国际单位制)。 + +* 长度:Meter(单位常数:m) +* 质量:KiloGram(单位常数:kg,g = 0.001kg) +* 时间:Sec(分、时、日、年等有分、时、日、年等常量由秒生成) +* 电流:Amper(单位常数:a) +* 温度:Kelvin(单位常数:k。华氏、摄氏度类型也可用,可相互转换) +* 物质量:Mol(单位常数:mol) +* 发光强度:Candela(单位常数:cd) + +此外,还定义了`Unit1`、`UnitMul`和`UnitDiv`类型,可以通过组合基本类型来创建新的单元。 +例如`UnitDiv(Unit1, Sec)`,因为频率单位赫兹(hertz)被定义为振动周期(秒)的倒数。 +如果要将此类型视为有意义的类型(例如添加专用方法),则应创建 [patch](./../../syntax/type/07_patch.md)。 + +```python +Hertz = Patch UnitDiv(Unit1, Sec) +SquareMeter = Patch UnitMul(Meter, Meter) +``` + +一些辅助单元也是预定义的: + +* 频率: Hertz(hz) +* 力: Newton(newton) +* 能量: Joule(j) +* 功率: Watt(w) +* 电压: Volt(v) +* 电阻: Ohm(ohm) +* 速度: Velocity(m/s) +* 面积: SquareMeter(m^2) +* 体积: CubicMeter(m^3) (liter = 10e-3 m^3) +* 角度: Degree(deg) (rad = 180/pi deg) +* 长度: Feet, Yard, Inch, Mile, Ly, Au, Angstrom +* 重量: Pound + +它还定义了一个前缀: + +* Femto = 1e-15 +* Pico = 1e-12 +* Nano = 1e-9 +* Micro = 1e-6 +* Milli = 1e-3 +* Centi = 1e-2 +* Deci = 1e-1 +* Hecto = 1e+2 +* Kilo = 1e+3 +* Mega = 1e+6 +* Giga = 1e+9 +* Tera = 1e+12 +* Peta = 1e+15 +* Exa = 1e+18 + +* 与名字的由来相反,Erg基本采用MKS单位制。如果需要 CGS 单位制的单位模块,请使用外部库[cgs](https://github.com/mtshiba/cgs)等)。 \ No newline at end of file diff --git a/doc/zh_TW/API/modules/unsound.md b/doc/zh_TW/API/modules/unsound.md new file mode 100644 index 00000000..adfe6ccf --- /dev/null +++ b/doc/zh_TW/API/modules/unsound.md @@ -0,0 +1,24 @@ +# 模块 `unsound` + +让 API 执行在 Erg 的类型系统中无法保证的不健全和不安全的操作。 + +## `unsafe!` + +执行“不安全”过程。 就像 Rust 一样,`Unsafe` API 不能直接调用,而是作为高阶函数传递给这个过程。 + +```python +unsound = import "unsound" + +i = unsound. unsafe! do!: + # 将 `Result Int` 转换为 `Int` + unsound.transmute input!().try_into(Int), Int +``` + +## transmit + +将第一个参数的对象转换为第二个参数的类型。没有进行类型检查。 +这个函数破坏了类型系统的类型安全。请在使用前进行验证。 + +## 隐式转换 + +与 `transmute` 不同,它会自动转换为预期的类型。与 Ocaml 的 `Obj.magic` 工作方式相同。 \ No newline at end of file diff --git a/doc/zh_TW/API/operators.md b/doc/zh_TW/API/operators.md new file mode 100644 index 00000000..82c43c93 --- /dev/null +++ b/doc/zh_TW/API/operators.md @@ -0,0 +1,64 @@ +# 操作员 + +## 中缀运算符 + +### `_+_`|R; O; A <: Add(R, O)|(x: A, y: R) -> O + +执行加法。 + +### `_-_`|R; O; S <: Sub(R, O)|(x: S, y: R) -> O + +执行减法。 + +### `*`|R; O; M <: Mul R, O|(x: M, y: R) -> O + +执行乘法。 + +### `/`|R; O; D <: Div(R, O)|(x: D, y: R) -> O + +进行除法。 + +## 中缀字母运算符 + +### `and`(x: Bool, y: Bool) -> Bool + +执行 and 操作。 + +### `or`(x: Bool, y: Bool) -> Bool + +执行 and 操作。 + +## 前缀运算符 + +### `+_`|T <: Num|(x: T) -> T + +默认与 id 相同。 + +### `-_`|T <: Num|(x: T) -> T.Neg + +例如 Nat.`-`: Nat -> Neg 和返回值不同。 + +### `!`|T <: Immut|(x: T) -> `T!` + +从不可变对象创建可变对象。 +该运算符本身不是程序性的,可以在函数内部使用。 + +### `..`|T <: Ord|(x: T) -> Range T + +在 x 的末尾创建一个没有下限的 Range 对象。 +x..x 仅返回 x 作为迭代器。 + +### `..<`|T <: Ord|(x: T) -> Range T + +x.. Range T + +创建一个从 x 开始没有上限的 Range 对象。 + +### |T <: Ord|(x: T)`<..` -> Range T \ No newline at end of file diff --git a/doc/zh_TW/API/procs.md b/doc/zh_TW/API/procs.md new file mode 100644 index 00000000..e527f5fb --- /dev/null +++ b/doc/zh_TW/API/procs.md @@ -0,0 +1,39 @@ +# 过程 + +## print! + +```python +打印!(x)->无类型 +``` + + 使用换行符返回 x。 + +## 调试&排除; + +```python +调试!(x,类型=信息)-> NoneType +``` + +用换行符调试 x(文件名、行号、变量名一起显示)。 在发布模式中删除。 +支持表情符号的终端根据类型加前缀。 + +* type == Info: 💬 +* type == Ok: ✅ +* type == Warn: ⚠️ +* type == Hint: 💡 + +## for!i: Iterable T, block: T => NoneType + +以块的动作遍历迭代器。 + +## while!cond: Bool!, block: () => NoneType + +当cond为True时的执行块。 + +## Lineno!() -> Nat + +## Filename!() -> Str + +## Namespace!() -> Str + +## Module!() -> Module \ No newline at end of file diff --git a/doc/zh_TW/API/special.md b/doc/zh_TW/API/special.md new file mode 100644 index 00000000..6de5fc48 --- /dev/null +++ b/doc/zh_TW/API/special.md @@ -0,0 +1,175 @@ +# 特殊形式 + +特殊形式是不能在 Erg 类型系统中表达的运算符、子程序(等等)。它被`包围,但实际上无法捕获。 +此外,为方便起见,还出现了“Pattern”、“Body”和“Conv”等类型,但不存在此类类型。它的含义也取决于上下文。 + +## `=`(pat: Pattern, body: Body) -> NoneType + +将 body 分配给 pat 作为变量。如果变量已存在于同一范围内或与 pat 不匹配,则引发错误。 +它还用于记录属性定义和默认参数。 + +```python +record = {i = 1; j = 2} +f(x: Int, y = 2) = ... +``` + +当主体是类型或函数时,`=` 具有特殊行为。 +左侧的变量名嵌入到右侧的对象中。 + +```python +print! Class() # > +print! x: Int -> x + 1 # > +C = Class() +print! c # +f = x: Int -> x + 1 +print! f # +g x: Int = x + 1 +print! g # +K X: Int = Class(...) +print! K # +L = X: Int -> Class(...) +print! L # +``` + +`=` 运算符的返回值为“未定义”。 +函数中的多个赋值和 `=` 会导致语法错误。 + +```python +i = j = 1 # SyntaxError: 不允许多次赋值 +print!(x=1) # SyntaxError: cannot use `=` in function arguments +# 提示:您的意思是关键字参数(`x: 1`)吗? +if True, do: + i = 0 # SyntaxError: 块不能被赋值表达式终止 +``` + +## `->`(pat: Pattern, body: Body) -> Func + +生成匿名函数,函数类型。 + +## `=>`(pat: Pattern, body: Body) -> Proc + +生成匿名过程,过程类型。 + +## `:`(subject, T) + +确定主题是否与 T 匹配。如果它们不匹配,则抛出编译错误。 + +```python +a: Int +f x: Int, y: Int = x / y +``` + +也用于 `:` 应用样式。 + +```python +f x: + y + z +``` + +像`:`和`=`一样,运算的结果是不确定的。 + +```python +_ = x: Int # 语法错误: +print!(x: Int) # 语法错误: +``` + +## `.`(obj, attr) + +读取obj的属性。 +`x.[y, z]` 将 x 的 y 和 z 属性作为数组返回。 + +## `|>`(obj, c: Callable) + +执行`c(obj)`。 `x + y |>.foo()` 与 `(x + y).foo()` 相同。 + +### (x: Option T)`?` -> T | T + +后缀运算符。如果出现错误,请立即调用 `x.unwrap()` 和 `return`。 + +## match(obj, ...lambdas: Lambda) + +对于 obj,执行与模式匹配的 lambda。 + +```python +match [1, 2, 3]: + (l: Int) -> log "this is type of Int" + [[a], b] -> log a, b + [...a] -> log a +# (1, 2, 3) +``` + +## del(x: ...T) -> NoneType | T + +删除变量“x”。但是,无法删除内置对象。 + +```python +a = 1 +del a # OK + +del True # SyntaxError: cannot delete a built-in object +``` + +## do(body: Body) -> Func + +生成一个不带参数的匿名函数。 `() ->` 的语法糖。 + +## do!(body: Body) -> Proc + +生成不带参数的匿名过程。 `() =>` 的语法糖。 + +## `else`(l, r) -> Choice + +创建一个由两对组成的类元组结构,称为 Choice 对象。 +`l, r` 被懒惰地评估。也就是说,只有在调用 .get_then 或 .get_else 时才会计算表达式。 + +```python +choice = 1 else 2 +assert choice.get_then() == 1 +assert choice.get_else() == 2 +assert True.then(choice) == 1 +``` + +## 集合运算符 + +### `[]`(...objs) + +从参数创建一个数组或从可选参数创建一个字典。 + +### `{}`(...objs) + +从参数创建一个集合。 + +### `{}`(...fields: ((Field, Value); N)) + +生成记录。 + +### `{}`(layout, ...names, ...preds) + +生成筛型,等级2型。 + +### `...` + +展开嵌套集合。它也可以用于模式匹配。 + +```python +[x, ...y] = [1, 2, 3] +assert x == 1 and y == [2, 3] +assert [x, ...y] == [1, 2, 3] +assert [...y, x] == [2, 3, 1] +{x; ...yz} = {x = 1; y = 2; z = 3} +assert x == 1 and yz == {y = 2; z = 3} +assert {x; ...yz} == {x = 1; y = 2; z = 3} +``` + +## 虚拟运算符 + +用户不能直接使用的运算符。 + +### ref(x: T) -> Ref T | T + +返回对对象的不可变引用。 + +### ref!(x: T!) -> Ref!T! | T! + +返回对可变对象的可变引用。 \ No newline at end of file diff --git a/doc/zh_TW/API/types.md b/doc/zh_TW/API/types.md new file mode 100644 index 00000000..68f525a0 --- /dev/null +++ b/doc/zh_TW/API/types.md @@ -0,0 +1,262 @@ +# 内置 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 等。 + +### 类型 + +* `__父类__`:超类型(`__mro__` 是一个数组,但这个是一个 Set) +* `__basicsize__`: +* `__dictoffset__`:Evm 不支持 +* `__flags__`: +* `__itemsize__`:实例的大小(如果不是类,则为 0) +* `__weakrefoffset__`:Evm 不支持 +* `__membercheck__`: 相当于`ismember(x, T)` +* `__subtypecheck__`:等价于`issubtype(U, T)`,别名`__subclasshook__`(兼容CPython) + +### 实例 + +* `__class__`:返回创建实例的类(自动附加到使用 `.new` 创建的对象) + +### Class + +* `__mro__`:用于方法解析的类型数组(包括自身,始终以 Object 结尾) +* `__base__`:基本类型(`__mro__[1]` 如果有多个) +* `__new__`: 实例化 +* `__init__`: 初始化实例 +* `__init_subclass__`: 初始化实例 +* `__intstancecheck__`:使用类似于 `MyClass.__instancecheck__(x)`,等价于 `isinstance(x, MyClass)` +* `__subclasscheck__`:等价于 `issubclass(C, MyClass)` + +## 运算符 + +此处指定以外的运算符没有特殊类型 + +### 方程 + +* `__eq__(self, rhs: Self) -> Bool`: 对象比较函数 (==) +* `__ne__`: 对象比较函数 (!=),默认实现 + +### 秩序 + +* `__lt__(self, rhs: Self) -> Bool`: 对象比较函数 (<) +* `__le__`:对象比较函数(<=),默认实现 +* `__gt__`:对象比较函数(>),默认实现 +* `__ge__`:对象比较函数(>=),默认实现 + +### BinAdd + +* 实现 `__add__(self, rhs: Self) -> Self`: `+` + +### 添加R + +* `__add__(self, rhs: R) -> Self.AddO` + +### Sub R + +* `__sub__(self, rhs: R) -> Self.SubO` + +### Mul R + +* `__mul__(self, rhs: R) -> Self.MulO` + +### BinMul <: Mul Self + +* `__pow__`:实现 `**`(默认实现) + +### Div R, O + +* 实现 `__div__(self, rhs: Self) -> Self`: `/`,可能会因为 0 而恐慌 + +### BinDiv <: Div Self + +* `__mod__`: 实现 `%` (默认实现) + +## 数值型 + +### Num (= Add and Sub and Mul and Eq) + +例如,除了Complex,Vector、Matrix和Tensor都是Num(Matrix和Tensor中的*分别与dot和product相同) + +### Complex (= Inherit(Object, Impl := Num)) + +* `imag: Ratio`:返回虚部 +* `real: Ratio`:返回实部 +* `conjugate self -> Complex`:返回复共轭 + +### Float (= Inherit(FloatComplex, Impl := Num)) + +### Ratio (= Inherit(Complex, Impl := Num)) + +* `numerator: Int`: 返回分子 +* `denominator: Int`: 返回分母 + +### Int (= Inherit Ratio) + +### Nat (= Inherit Int) + +* `times!`: 运行 proc self 时间 + +## 其他基本类型 + +### 布尔值 + +* `__and__`: +* `__or__`: +* `not`: + +## 字符串 (<: 序列) + +* `capitalize` +* `chomp`: 删除换行符 +* `isalnum`: +* `isascii`: +* `isalpha`: +* `isdecimal`: +* `isdight`: +* `isidentifier` +* `islower` +* `isnumeric` +* `isprintable` +* `isspace` +* `istitle` +* `isupper` +* `lower` +* `swapcase` +* `title` +* `upper` + +## 其他 + +### 位 + +* `from_bytes`:从字节转换 +* `to_bytes`:转换为字节(指定长度和字节序(字节序)) +* `bit_length`:返回位长度 + +### 可迭代 T + +请注意,它不是 `Iterator` 本身的类型。 `Nat` 是 `Iterable` 但你不能 `Nat.next()`,你需要 `Nat.iter().next()`。 + +* `iter`:创建一个迭代器。 + +### 迭代器 T + +Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter().fold (sum, n) -> sum + n*2`等是可能的。 +由于所有和任何在使用后都会被破坏,因此没有副作用。这些应该使用没有副作用的 `next` 来实现,但内部使用 `Iterator!.next!` 来提高执行效率。 + +* `next`:返回第一个元素和剩余的迭代器。 +* `all` +* `any` +* `filter` +* `filter_map` +* `find` +* `find_map` +* `flat_map` +* `flatten` +* `fold` +* `for_each` +* `map` +* `map_while` +* `nth` +* `pos` +* `take` +* `unzip` +* `zip` + +### Iterator!T = IteratorT 和 ... + +* `next!`:获取第一个元素。 + +## SizedIterator T = 迭代器 T 和 ... + +有限数量元素的迭代器。 + +* `len`: +* `chain`: +* `count`: +* `is_empty`: +* `rev`: +* `next_back`: +* `nth_back`: +* `rfind`: +* `rfold`: +* `sum`: +* `max`: +* `min`: + +## Seq T = SizedIterable T 和 ... + +* `concat`: 合并两个 Seq +* `__getitem__`:等同于使用 `[]` 访问(否则会出现恐慌) +* 与 `get`: __getitem__ 不同,它返回 Option +* `maketrans`:创建替换表(静态方法) +* `replace`: 替换 +* `translate`:根据替换表替换 +* `insert`: 添加到 idx +* `remove`: 删除 idx +* `prepend`: 前置 +* `dequeue`: 移除头部 +* `push`:添加到末尾 +* `pop`: 取尾巴 +* `dedup`:删除连续值 +* `uniq`:删除重复元素(通过 sort |> dedup 实现,因此顺序可能会改变) +* `swap`:交换元素 +* `reverse`:反转元素 +* `sort`: 排序元素 +* `first`: +* `last`: + +### Seq!T (= Seq T and ...) + +* `__setitem__!`: +* `__delitem__!`: +* `插入!`:添加到 idx +* `remove!`: 删除 idx +* `prepend!`:前置 +* `dequeue!`: 删除开头 +* `push!`:添加到末尾 +* `pop!`:拿尾巴 +* `dedup!`:删除连续值 +* `uniq!`: 删除重复元素(通过排序实现!|> dedup!,因此顺序可能会改变) +* `swap!`:交换元素 +* `reverse!`:反转元素 +* `set!` +* `sort!`: 排序元素 +* `translate!` \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Array!(T).md b/doc/zh_TW/API/types/classes/Array!(T).md new file mode 100644 index 00000000..1d020183 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Array!(T).md @@ -0,0 +1,3 @@ +# 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 new file mode 100644 index 00000000..c186d029 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Array(T).md @@ -0,0 +1,3 @@ +# 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 new file mode 100644 index 00000000..074bbe5d --- /dev/null +++ b/doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md @@ -0,0 +1,34 @@ +# ArrayWithLen T: Type, N: Nat + +`[T; N]`是语法糖。还有一个[`Array` 类型](./Array.md)省略了长度。 + +## 方法 + +* values_at(self, selectors: [Nat; N]) -> [T; N] + +```python +assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] +``` + +* all(self, pred: T -> Bool) -> Bool + 返回是否所有元素都满足 pred。 + 如果元素为 0,则无论 pred 为 `True`,但会发出警告。 + 该规范本身已被多种语言采用,是逻辑一致性所必需的。 + + ```python + assert [].all(_ -> False) + ``` + + ```python + assert all(False for _ in []) + ``` + +## ArrayWithLen T, N | T <: Eq 的方法 + +* freq self -> [{T: Nat}] + 返回对象出现的次数。 + +```python +assert ["a", "b", "c", "b", "c", "b"].freq() \ +== [{"a", 1}, {"b": 3}, {"c": 2}] +``` diff --git a/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md new file mode 100644 index 00000000..842084ca --- /dev/null +++ b/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md @@ -0,0 +1,26 @@ +# ArrayWithMutLength! T: Type, N: Nat! + +一个可变长度数组,其长度在编译时已知。还有语法糖`ArrayWithMutLength(T, !N) == [T; !N]` + +## 方法 + +* push! ref! self(N ~> N+1, ...), elem: T + +* pop! ref! (N ~> N-1, ...) -> T + +* sample!(ref! self) -> T +* sample! ref! self, M: Nat -> [T; M] + 随机选择里面的一个元素并返回一个副本 + +* shuffle!(ref! self) + 把里面的东西随机摆放 + +* assert_len ref! self(_ ~> N, ...), N: Nat -> () or Panic + 验证长度。 + `panic!` 如果长度无效。 + +## Impl + +* From Range Int +* From [T; N] +* Num diff --git a/doc/zh_TW/API/types/classes/Class.md b/doc/zh_TW/API/types/classes/Class.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/classes/Complex.md b/doc/zh_TW/API/types/classes/Complex.md new file mode 100644 index 00000000..e9e8b49a --- /dev/null +++ b/doc/zh_TW/API/types/classes/Complex.md @@ -0,0 +1,14 @@ +# Complex + +表示复数的类型。在 Erg 中表示数字的类型,例如 Float、Int和Nat,通常派生于Complex + +## 父类 + +Num 和 Norm + +## 方法 + +* abs +* conjugate +* imag +* real diff --git a/doc/zh_TW/API/types/classes/Dict!.md b/doc/zh_TW/API/types/classes/Dict!.md new file mode 100644 index 00000000..20e33c4c --- /dev/null +++ b/doc/zh_TW/API/types/classes/Dict!.md @@ -0,0 +1,7 @@ +# Dict! K, V + +表示字典(哈希Map)的类型。 有一个语法糖叫做`{K: V}` + +## 方法 + +* invert!(self) -> Self! V, K diff --git a/doc/zh_TW/API/types/classes/Either.md b/doc/zh_TW/API/types/classes/Either.md new file mode 100644 index 00000000..43a45deb --- /dev/null +++ b/doc/zh_TW/API/types/classes/Either.md @@ -0,0 +1,12 @@ +# Either L, R = L or R + +表示L或R的类型。 您可以将其视为Or类型的二元形式 + +## 方法 + +* orl +* orr +* andl +* andr +* mapl +* mapr diff --git a/doc/zh_TW/API/types/classes/Float.md b/doc/zh_TW/API/types/classes/Float.md new file mode 100644 index 00000000..06479f12 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Float.md @@ -0,0 +1,21 @@ +# 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 + +## 父类 + +Complex 和 Ord + +## 方法 + +* sgn(self) -> {-1, 0, 1} + 返回标志 + +* truncate(self) -> Int + 返回最接近自身的整数 + +* separate(self) -> [Str] +* separate(self, dight: Nat) -> [Str] + 按digit位数划分。没有自变量 diff --git a/doc/zh_TW/API/types/classes/Function(N).md b/doc/zh_TW/API/types/classes/Function(N).md new file mode 100644 index 00000000..4317a8ea --- /dev/null +++ b/doc/zh_TW/API/types/classes/Function(N).md @@ -0,0 +1,9 @@ +# Function N: Nat + +## Function 1 的方法 + +* then(self, g: Self) -> Self + +```python +assert f(g(x)) == f.then(g) x +``` diff --git a/doc/zh_TW/API/types/classes/Inf.md b/doc/zh_TW/API/types/classes/Inf.md new file mode 100644 index 00000000..0e7e02b9 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Inf.md @@ -0,0 +1,7 @@ +# Inf + +Inf是一个类,其唯一实例是inf。 +inf的主要用途是用于区间类型。 +例如,大于等于 2 的整数类型是 `2.. Self(L1+L2, R1+R2) + +正常加法。 `Int` 和 `Nat` 的添加在此定义为假装它在每个类中定义 + +```python +0..10 + 1..12 == 1..22 +Int + 0..10 == _..|Int|_ + 0..10 == _..|Int|_ == Int +Nat + Nat == 0.._ + 0.._ == 0.._ == Nat +``` diff --git a/doc/zh_TW/API/types/classes/Interval.md b/doc/zh_TW/API/types/classes/Interval.md new file mode 100644 index 00000000..68e69030 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Interval.md @@ -0,0 +1,18 @@ +# Interval begin, end := WellOrder + +表示有序集合类型 (WellOrder) 的子类型的类型。Interval 类型具有派生类型,例如 PreOpen(x<..y)。 + +```python +Months = 1..12 +Alphabet = "a".."z" +Weekdays = Monday..Friday +Winter = November..December or January..February +``` + +```python +0..1 # 整数范围 +0.0..1.0 # 真实(有理)范围 +# 或 0/1..1/1 相同 +``` + +计算机无法处理无限位数的数字,所以实数的范围实际上是有理数的范围。 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Iterator.md b/doc/zh_TW/API/types/classes/Iterator.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/classes/Kind(N).md b/doc/zh_TW/API/types/classes/Kind(N).md new file mode 100644 index 00000000..b3103d53 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Kind(N).md @@ -0,0 +1,5 @@ +# Kind N: Nat + +```python +Kind N: Nat = (Type; N) -> Type +``` diff --git a/doc/zh_TW/API/types/classes/Matrix.md b/doc/zh_TW/API/types/classes/Matrix.md new file mode 100644 index 00000000..bbb43b4f --- /dev/null +++ b/doc/zh_TW/API/types/classes/Matrix.md @@ -0,0 +1,7 @@ +# Matrix T: Num, Shape: [M, N] + +表示矩阵的类型。 它继承自 Tensor[M, N] + +## 定义 + +Inherit Tensor T, [M, N] diff --git a/doc/zh_TW/API/types/classes/Module.md b/doc/zh_TW/API/types/classes/Module.md new file mode 100644 index 00000000..547f7253 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Module.md @@ -0,0 +1,3 @@ +# Module + +## 方法 diff --git a/doc/zh_TW/API/types/classes/Nat.md b/doc/zh_TW/API/types/classes/Nat.md new file mode 100644 index 00000000..05911648 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Nat.md @@ -0,0 +1,18 @@ +# Nat + +表示自然数的类型。 用于数组索引和范围类型 + +## 定义 + +```python +Nat = 0.._ +``` + +## 方法 + +* times!(self, p: () => NoneType) -> NoneType + +```python +100.times! () => + print! "hello!" +``` diff --git a/doc/zh_TW/API/types/classes/Neg.md b/doc/zh_TW/API/types/classes/Neg.md new file mode 100644 index 00000000..7298453f --- /dev/null +++ b/doc/zh_TW/API/types/classes/Neg.md @@ -0,0 +1,8 @@ +# Neg + +表示负整数的类型。 Pos和Neg和{0} == Int +它还具有一些值得注意的属性,例如不被零除和 Neg * Neg == Pos + +## 定义 + +Inf<..-1 diff --git a/doc/zh_TW/API/types/classes/Never.md b/doc/zh_TW/API/types/classes/Never.md new file mode 100644 index 00000000..0336f19c --- /dev/null +++ b/doc/zh_TW/API/types/classes/Never.md @@ -0,0 +1,13 @@ +# Never + +它是所有类型的子类型。 它是一个`Class`,因为它拥有所有的方法,当然还有 `.new`。但是,它没有实例,并且Erg会在即将创建的那一刻停止。 +还有一种叫做`Panic`的类型没有实例,但是`Never`用于正常终止或故意无限循环,`Panic`用于异常终止。 + +```python +# Never <: Panic +f(): Panic = exit 0 # OK +g(): Never = panic() # TypeError +``` + +`Never`/`Panic`的 OR 类型,例如`T 或 Never`可以转换为`T`。 这是因为`Never`在语义上是一个从不出现的选项(如果出现了,程序会立即停止)。 +但是,在函数的返回值类型中使用时,`or Never`不能省略,因为它表示程序可能会终止。 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/NonZero.md b/doc/zh_TW/API/types/classes/NonZero.md new file mode 100644 index 00000000..b73422a0 --- /dev/null +++ b/doc/zh_TW/API/types/classes/NonZero.md @@ -0,0 +1,30 @@ +# 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 +``` + +## 方法 + +@Impl SafeDiv R, O +.`/`: Self.(R) -> O diff --git a/doc/zh_TW/API/types/classes/Object.md b/doc/zh_TW/API/types/classes/Object.md new file mode 100644 index 00000000..79a6e635 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Object.md @@ -0,0 +1,7 @@ +# Object + +它是所有类型的超类型 + +## 方法 + +* __sizeof__: Nat diff --git a/doc/zh_TW/API/types/classes/Operator.md b/doc/zh_TW/API/types/classes/Operator.md new file mode 100644 index 00000000..581e7ac5 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Operator.md @@ -0,0 +1,7 @@ +# Operator [...T], O + +是运算符的类型 + +## 定义 + +Inherit Func [...T], O diff --git a/doc/zh_TW/API/types/classes/Option.md b/doc/zh_TW/API/types/classes/Option.md new file mode 100644 index 00000000..bbcefdf9 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Option.md @@ -0,0 +1,21 @@ +# Option T = T or NoneType + +表示“可能失败”的类型。 + +## 方法 + +* unwrap(self, msg = "unwrapped a None value") -> T or Panic + +提取它,期望内容是 `T` 类型。 如果是 `None`,则输出 `msg` 并恐慌 + +```python +x = "...".parse(Int).into(Option Int) +x.unwrap() # UnwrappingError: unwrapped a None value +x.unwrap("failed to convert from string to number") # UnwrappingError: failed to convert from string to number +``` + +* unwrap_or(self, else: T) -> T + +* unwrap_or_exec(self, f: () -> T) -> T + +* unwrap_or_exec!(self, p!: () => T) -> T diff --git a/doc/zh_TW/API/types/classes/Pos.md b/doc/zh_TW/API/types/classes/Pos.md new file mode 100644 index 00000000..404b30ae --- /dev/null +++ b/doc/zh_TW/API/types/classes/Pos.md @@ -0,0 +1,8 @@ +# Pos + +Pos是一种表示正数(大于或等于1的整数)的类型。 +由于不包括0,因此具有消除被零除的可能性等优点。 + +## 定义 + +`Pos = 1.._` diff --git a/doc/zh_TW/API/types/classes/Ratio.md b/doc/zh_TW/API/types/classes/Ratio.md new file mode 100644 index 00000000..58b4211b --- /dev/null +++ b/doc/zh_TW/API/types/classes/Ratio.md @@ -0,0 +1,5 @@ +# 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类型之前,请进行真实的性能测试。 业余爱好者无条件偏爱较轻的模具。 diff --git a/doc/zh_TW/API/types/classes/Record.md b/doc/zh_TW/API/types/classes/Record.md new file mode 100644 index 00000000..7dc5f93f --- /dev/null +++ b/doc/zh_TW/API/types/classes/Record.md @@ -0,0 +1,14 @@ +# Record + +记录所属的类。例如,`{i = 1}` 是`Structural {i = Int}` 类型的元素,并且是`{i = Int}` 类的实例 +请注意,其他类的实例是记录类型的元素,而不是记录类的实例 + +```python +assert not Structural({i = Int}) in Class +assert {i = Int} in Class + +C = Class {i = Int} +c = C.new {i = 1} +assert c in Structural {i = Int} +assert not c in {i = Int} +``` diff --git a/doc/zh_TW/API/types/classes/Result.md b/doc/zh_TW/API/types/classes/Result.md new file mode 100644 index 00000000..67134e03 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Result.md @@ -0,0 +1,7 @@ +# Result T, E + +```python +Result T, E <: Error = Either T, E +``` + +和 `Option` 一样,它代表“一个可能失败的值”,但它可以有失败的上下文。 用法与`Either`几乎相同。 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Str!.md b/doc/zh_TW/API/types/classes/Str!.md new file mode 100644 index 00000000..af0f1ee7 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Str!.md @@ -0,0 +1,3 @@ +# StrWithLen! N: Nat! = Inherit StrWithLen N + +表示可变长度字符串的类型 diff --git a/doc/zh_TW/API/types/classes/Str.md b/doc/zh_TW/API/types/classes/Str.md new file mode 100644 index 00000000..269ea06a --- /dev/null +++ b/doc/zh_TW/API/types/classes/Str.md @@ -0,0 +1,9 @@ +# Str + +(不变长度)表示字符串的类型。 简单的 `Str` 类型是删除了字符数的 `StrWithLen N` 类型(`Str = StrWithLen _`) + +## 方法 + +* isnumeric + +返回字符串是否为阿拉伯数字。 使用 `isunicodenumeric` 判断汉字数字和其他表示数字的字符(注意此行为与 Python 不同)。 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/StrWithLen.md b/doc/zh_TW/API/types/classes/StrWithLen.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/classes/Subroutine.md b/doc/zh_TW/API/types/classes/Subroutine.md new file mode 100644 index 00000000..60bd76de --- /dev/null +++ b/doc/zh_TW/API/types/classes/Subroutine.md @@ -0,0 +1,19 @@ +# Subroutine + +Func和Proc的基本类型。 + +## 方法 + +* return + +中断子程序并返回指定的值。 用于快速逃离嵌套 + +```python +f x = + for 0..10, i -> + if i == 5: + do + f::return i + do + log i +``` diff --git a/doc/zh_TW/API/types/classes/Tensor.md b/doc/zh_TW/API/types/classes/Tensor.md new file mode 100644 index 00000000..2fa51a80 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Tensor.md @@ -0,0 +1,24 @@ +# Tensor Shape: [Nat; N] + + 用于有效操作多维数组的类。 它还定义了诸如多维数组上的乘法之类的操作 + Matrix、Vector 等都继承自该类型 + +```python +Tensor.arange(0..9) # Tensor [10] +``` + +* reshape(self, NewShape: [Nat; M]) -> Self NewShape + +```python +(1..9).into(Tensor).reshape [3, 3] +``` + +* identity i: Nat -> Self shape: [Nat; N] +* zeros(Shape: [Nat; N]) -> Self +* ones(Shape: [Nat; N]) -> Self + +* diag + +* linspace +* logspace +* geomspace diff --git a/doc/zh_TW/API/types/classes/TransCell(T).md b/doc/zh_TW/API/types/classes/TransCell(T).md new file mode 100644 index 00000000..afb24e2c --- /dev/null +++ b/doc/zh_TW/API/types/classes/TransCell(T).md @@ -0,0 +1,12 @@ +# TransCell! T: Type! + +它是一个单元格,其内容可以针对每个模具进行更改。 由于它是T类型的子类型,因此它也表现为T类型 +当它在初始化时输入T时很有用,并且在某个点之后总是输入U + +```python +a = TransCell!.new None +a: TransCell! !NoneType +a.set! 1 +a: TransCell! !Int +assert a + 1 == 2 +``` diff --git a/doc/zh_TW/API/types/classes/Tuple.md b/doc/zh_TW/API/types/classes/Tuple.md new file mode 100644 index 00000000..6ee22bb4 --- /dev/null +++ b/doc/zh_TW/API/types/classes/Tuple.md @@ -0,0 +1,27 @@ +# Tuple T: ...Type + +包含多种类型对象的集合 + +## 方法 + +* zip self, other + + 组合两个有序集合(数组或元组) + + ```python + assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4) + ``` + +* zip_by self, op, other + + 一种泛化 zip 的方法。 您可以指定一个二进制操作来组合 + `()`、`[]`、`{}`、`{:}` 也可以指定为运算符,分别生成元组、数组、集合和字典 + + ```python + assert ([1, 2, 3].zip([4, 5, 6]))[0] == (1, 4) + assert ([1, 2, 3].zip_by((), [4, 5, 6]))[0] == (1, 4) + assert ([1, 2, 3].zip_by([], [4, 5, 6]))[0] == [1, 4] + assert ([1, 2, 3].zip_by({}, [4, 5, 6]))[0] == {1, 4} + assert ([1, 2, 3].zip_by({:}, [4, 5, 6]))[0] == {1: 4} + assert ([1, 2, 3].zip_by(`_+_`, [4, 5, 6]))[0] == 5 + ``` diff --git a/doc/zh_TW/API/types/classes/Type.md b/doc/zh_TW/API/types/classes/Type.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/classes/Vector.md b/doc/zh_TW/API/types/classes/Vector.md new file mode 100644 index 00000000..f9a159ed --- /dev/null +++ b/doc/zh_TW/API/types/classes/Vector.md @@ -0,0 +1,3 @@ +# 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 new file mode 100644 index 00000000..8494aa4f --- /dev/null +++ b/doc/zh_TW/API/types/patches/BinOp.md @@ -0,0 +1,7 @@ +# BinOp L, R, O + +二元运算符的类型 + +## 修补程序 + +Operator [L, R], O diff --git a/doc/zh_TW/API/types/patches/UnaryOp.md b/doc/zh_TW/API/types/patches/UnaryOp.md new file mode 100644 index 00000000..6b56481a --- /dev/null +++ b/doc/zh_TW/API/types/patches/UnaryOp.md @@ -0,0 +1,7 @@ +# UnaryOp T, O + +一元运算符的类型 + +## 定义 + +Operator [T], O diff --git a/doc/zh_TW/API/types/traits/Add(R,O).md b/doc/zh_TW/API/types/traits/Add(R,O).md new file mode 100644 index 00000000..4d8b6220 --- /dev/null +++ b/doc/zh_TW/API/types/traits/Add(R,O).md @@ -0,0 +1,34 @@ +# Add R + +```python +Add R = Trait { + .AddO = Type + .`_+_` = (Self, R) -> Self.AddO +} +``` + +`Add`是一种定义加法的类型。加法有两种类型的`+`:方法和函数 +`+`作为二元函数,即`_+_`,定义如下: + +```python +`_+_`(l: Add(R, O), r: R): O = l.`_+_` r +``` + +这个定义的目的是让 `+` 可以被视为一个函数而不是一个方法 + +```python +assert [1, 2, 3].fold(0, `_+_`) == 6 + +call op, x, y = op(x, y) +assert call(`_+_`, 1, 2) == 3 +``` + +加法是这样输入的 + +```python +f: |O: Type; A <: Add(Int, O)| A -> O +f x = x + 1 + +g: |A, O: Type; Int <: Add(A, O)| A -> O +g x = 1 + x +``` diff --git a/doc/zh_TW/API/types/traits/Div(R,O).md b/doc/zh_TW/API/types/traits/Div(R,O).md new file mode 100644 index 00000000..020acba5 --- /dev/null +++ b/doc/zh_TW/API/types/traits/Div(R,O).md @@ -0,0 +1,9 @@ +# Div R, O + +如果除以零没有错误,请使用“SafeDiv” + +```python +Div R, O = Trait { + .`/` = Self.(R) -> O or Panic +} +``` diff --git a/doc/zh_TW/API/types/traits/Eq.md b/doc/zh_TW/API/types/traits/Eq.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/traits/Into.md b/doc/zh_TW/API/types/traits/Into.md new file mode 100644 index 00000000..de92a824 --- /dev/null +++ b/doc/zh_TW/API/types/traits/Into.md @@ -0,0 +1,11 @@ +# Into T + +一种类型,表明它可以被类型转换为类型T。 +即使Self和T之间没有继承关系,也是在关系可以相互转换的时候定义的。 +与继承不同,没有隐式转换。您必须始终调用 `.into` 方法。 + +## 方法 + +* into(self, T) -> T + + 変換を行います。 diff --git a/doc/zh_TW/API/types/traits/Iterable.md b/doc/zh_TW/API/types/traits/Iterable.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/traits/Num.md b/doc/zh_TW/API/types/traits/Num.md new file mode 100644 index 00000000..d5e3b2d8 --- /dev/null +++ b/doc/zh_TW/API/types/traits/Num.md @@ -0,0 +1,16 @@ +# Num + +## 定义初始化 + +```python +Num R = Add(R) and Sub(R) and Mul(R) and Eq +Num = Num Self +``` + +## 父类 + +Add and Sub and Mul and Eq + +## 方法 + +* `abs` diff --git a/doc/zh_TW/API/types/traits/Ord.md b/doc/zh_TW/API/types/traits/Ord.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/traits/SafeDiv(R,O).md b/doc/zh_TW/API/types/traits/SafeDiv(R,O).md new file mode 100644 index 00000000..998faf89 --- /dev/null +++ b/doc/zh_TW/API/types/traits/SafeDiv(R,O).md @@ -0,0 +1,8 @@ +# SafeDiv R, O + +```python +SafeDiv R, O = Subsume Div, { + @Override + .`/` = Self.(R) -> O +} +``` diff --git a/doc/zh_TW/API/types/traits/Sample.md b/doc/zh_TW/API/types/traits/Sample.md new file mode 100644 index 00000000..5d2a6cdb --- /dev/null +++ b/doc/zh_TW/API/types/traits/Sample.md @@ -0,0 +1,31 @@ +# Sample + +具有“随机”选择实例的`sample`和`sample!`方法的特征。`sample`方法总是返回相同的实例,而`sample!`方法返回一个随机实例,该实例随调用而变化 + +请注意,这是一个假设您想要一个适当的实例进行测试等的特征,并且它不一定是随机的。 如果您想要随机抽样,请使用“随机”模块。 + +所有主要的值类都实现了 `Sample`。它还在由“Sample”类组成的元组类型、记录类型、Or类型和筛选类型中实现 + +```python +assert Int.sample() == 42 +assert Str.sample() == "example" +# Int默认在64bit范围内采样 +print! Int.sample!() # 1313798 +print! {x = Int; y = Int}.sample!() # {x = -32432892, y = 78458576891} +``` + +下面是一个`Sample`的实现示例 + +```python +EmailAddress = Class {header = Str; domain = Str}, Impl=Sample and Show +@Impl Show +EmailAddress. + show self = "{self::header}@{self::domain}" +@Impl Sample +EmailAddress. + sample(): Self = Self.new "sample@gmail.com" + sample!(): Self = + domain = ["gmail.com", "icloud.com", "yahoo.com", "outlook.com", ...].sample!() + header = AsciiStr.sample!() + Self.new {header; domain} +``` diff --git a/doc/zh_TW/API/types/traits/Seq.md b/doc/zh_TW/API/types/traits/Seq.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/traits/Show.md b/doc/zh_TW/API/types/traits/Show.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/API/types/traits/Unpack.md b/doc/zh_TW/API/types/traits/Unpack.md new file mode 100644 index 00000000..7c721151 --- /dev/null +++ b/doc/zh_TW/API/types/traits/Unpack.md @@ -0,0 +1,13 @@ +# Unpack + +标记性状。实现时,元素可以像记录一样通过模式匹配来分解 + +```python +C = Class {i = Int}, Impl=Unpack +C.new i = Self::new {i;} +{i} = C.new(1) +D = Class C or Int +log match D.new(1): + (i: Int) -> i + ({i}: C) -> i +``` diff --git a/doc/zh_TW/compiler/TODO_hint.md b/doc/zh_TW/compiler/TODO_hint.md new file mode 100644 index 00000000..790ce1f7 --- /dev/null +++ b/doc/zh_TW/compiler/TODO_hint.md @@ -0,0 +1,4 @@ +# 提示(未实现) + +* `x 未定义`(x 已被`Del` 删除)=> `提示:在第 X 行删除` +*补丁方法重复:“提示:指定补丁(如`T.foo(1)`)或使用`Del`删除任何`.foo`” \ No newline at end of file diff --git a/doc/zh_TW/compiler/TODO_recov_suggest.md b/doc/zh_TW/compiler/TODO_recov_suggest.md new file mode 100644 index 00000000..93a193b1 --- /dev/null +++ b/doc/zh_TW/compiler/TODO_recov_suggest.md @@ -0,0 +1,11 @@ +# 错误恢复建议(尚未实现) + +* `1 or 2`, `1 and 2` => `{1, 2}`? +* `U = Inherit T` => 非类类型不能被继承,或者`U = Class T`? +* `Int and Str` => 不允许多重继承,或者`Int or Str`? +* `: [1, 2]` => `: {1, 2}`? +* `: [Int, 2]` => `: [Int; 2]`? +* `[Int; Str]` => `(Int, Str)`(Tuple) 还是 `[Int: Str]`(Dict)? +* `{x: Int}` => `{x = Int}`? +* `{x = Int}!` => `{x = Int!}`? +* `ref! immut_expr` => `ref! !immut_expr`? \ No newline at end of file diff --git a/doc/zh_TW/compiler/TODO_warn.md b/doc/zh_TW/compiler/TODO_warn.md new file mode 100644 index 00000000..9f1fcf23 --- /dev/null +++ b/doc/zh_TW/compiler/TODO_warn.md @@ -0,0 +1,5 @@ +# 警告(尚未实现) + +* `t = {(record type)}` => `T = {(record type)}`?(只有定义为常量的类型才能用于类型说明) +* `{I: Int | ...}!` => `{I: Int! | ...}` +* for/while 块中的`return x`(`x != ()`) => `f::return`(外部块)? \ No newline at end of file diff --git a/doc/zh_TW/compiler/abandoned.md b/doc/zh_TW/compiler/abandoned.md new file mode 100644 index 00000000..dc120306 --- /dev/null +++ b/doc/zh_TW/compiler/abandoned.md @@ -0,0 +1,10 @@ +# 废弃/拒绝的语言规范 + +## 重载(临时多态性) + +被放弃了,因为它可以用参数+子类型多态来代替,并且与Python的语义不兼容。 有关详细信息,请参阅 [overload](../syntax/type/overloading.md) 文章。 + +## 具有显式生命周期的所有权系统 + +原计划引入 Rust 之类的所有权系统,但由于与 Python 的语义不兼容以及需要引入生命周期注解等复杂规范而被放弃,并且所有不可变对象都是 RC。托管的可变对象现在只有一个所有权. +Dyne 没有 C# 和 Nim 那样的 GIL,策略是允许值对象和低级操作在安全范围内。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/architecture.md b/doc/zh_TW/compiler/architecture.md new file mode 100644 index 00000000..f33fdfaf --- /dev/null +++ b/doc/zh_TW/compiler/architecture.md @@ -0,0 +1,42 @@ +# `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` 和 `VirtualMachine` 实现。 + +## 2. 转换 `TokenStream` -> `AST` (parser/parse.rs) + +* `Parser` 和 `Lexer` 一样,有两个构造函数,`Parser::new` 和 `Parser::from_str`,而 `Parser::parse` 会给出 `AST`。 +* `AST` 是 `Vec` 的包装器类型。 + +### 2.5 脱糖 `AST` + +* 扩展嵌套变量 (`Desugarer::desugar_nest_vars_pattern`) +* desugar 多模式定义语法(`Desugarer::desugar_multiple_pattern_def`) + +## 3. 类型检查和推断,转换 `AST` -> `HIR` (compiler/lower.rs) + +* `HIR` 有每个变量的类型信息。它是用于“高级中间表示”的。 +* `HIR` 只保存变量的类型,但这已经足够了。在极端情况下,这是因为 Erg 只有转换(或运算符)应用程序的参数对象。 +* `ASTLower` 可以用与`Parser` 和`Lexer` 相同的方式构造。 +* 如果没有错误发生,`ASTLowerer::lower` 将输出 `HIR` 和 `CompileWarnings` 的元组。 +* `ASTLowerer`归`Compiler`所有。与传统结构不同,`ASTLowerer`处理代码上下文并且不是一次性的。 +* 如果类型推断的结果不完整(如果存在未知类型变量),名称解析时会出错。 + +## 4. 检查副作用(compiler/effectcheck.rs) + +## 4. 检查所有权(compiler/memcheck.rs) + +## 5. 从`HIR`(compiler/codegen.rs)生成字节码(`CodeObj`) + +* 根据表达式的类型信息,将执行量化子程序的名称解析。 + +##(6.(未来计划)转换字节码 -> LLVM IR) + +* 字节码是基于堆栈的,而 LLVM IR 是基于寄存器的。 + 这个转换过程会多出几层中间过程。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/errors.md b/doc/zh_TW/compiler/errors.md new file mode 100644 index 00000000..722d1339 --- /dev/null +++ b/doc/zh_TW/compiler/errors.md @@ -0,0 +1,131 @@ +# Erg Compiler Errors + +## AssignError + +尝试重写不可变变量时发生 + +## AttributeError + +尝试访问不存在的属性时发生 + +## PurityError + +当您在不允许副作用的范围内(函数、不可变类型等)编写导致副作用的代码时发生 + +## MoveError + +尝试访问已移动的变量时发生 + +## BorrowError + +在存在对对象的借用时尝试获取可变引用时发生 + +## CyclicError + +当你有一个明显不可阻挡的循环时发生 + +```python +i: Int = i + +f(): Int = g() +g() = f() + +h(): Int = module::h() + +T = U +U = T +``` + +## BytecodeError + +当加载的字节码损坏时发生 + +## CompileSystemError + +在编译器内部发生错误时发生 + +## EnvironmentError + +如果您在安装期间没有访问权限,则会发生这种情况 + +## FeatureError + +在检测到未正式提供的实验性功能时发生 + +## ImportError + +## IndentationError + +检测到不良缩进时发生 +派生自SyntaxError + +## NameError + +当您访问不存在的变量时发生 + +## NotImplementedError + +当您调用具有定义但没有实现的 API 时发生 +派生自 TypeError + +## PatternError + +当检测到非法模式时发生 +派生自SyntaxError + +## SyntaxError + +在检测到错误语法时发生 + +## TabError + +在使用制表符进行缩进/间距时发生 +派生自SyntaxError + +## TypeError + +当对象类型不匹配时发生 + +## UnboundLocalError + +在定义之前使用变量时发生 +更准确地说,它发生在以前使用过在范围内定义的变量时 + +```python +i = 0 +f x = + y = i + x + i = 1 + y + i +``` + +在这段代码中,`y = i + x` 中的 `i` 是一个未定义的变量 +但是,常量可以在定义之前在另一个函数中调用 + +```python +f() = g() +g() = f() +``` + +## Erg Compiler Warnings + +## SyntaxWarning + +它在语法上很好,但是当我们检测到冗余或不常见的代码(不必要的 `()` 等)时就会发生这种情况 + +```python +if (True): # SyntaxWarning: unnecessary parentheses + ... +``` + +## DeprecationWarning + +在不推荐使用引用的对象时发生 +(开发人员在生成此警告时应始终提供替代方法作为提示) + +## FutureWarning + +当您检测到将来可能导致问题的代码时发生 +此警告是由版本兼容性问题(包括库)以及语法和 API 的更改引起的 + +## ImportWarning diff --git a/doc/zh_TW/compiler/hir.md b/doc/zh_TW/compiler/hir.md new file mode 100644 index 00000000..748cc4d6 --- /dev/null +++ b/doc/zh_TW/compiler/hir.md @@ -0,0 +1,148 @@ +# 高级中间表示(HIR, High-level Intermediate Representation) + +HIR 是 Erg 编译器从 AST 生成的结构 +此结构包含源代码中每个表达式的完整类型信息,并且在语法上已脱糖 +AST与源代码一一对应(纯文本),但是HIR去掉了不必要的代码信息,添加了省略的类型信息,所以HIR可以转换为源代码很难恢复 +让我们在下面的代码中查看 HIR 的示例 + +```python +v = ![] +for! 0..10, i => + v.push! i +log v.sum() +``` + +从此代码生成的 AST 如下所示: + +```python +AST(Module[ + VarDef{ + sig: VarSignature{ + pat: VarPattern::Ident(None, VarName("v")), + spec_t: None, + }, + op: "=", + body: Block[ + UnaryOp{ + op: "!", + expr: Array([]), + }, + ], + }, + Call{ + obj: Accessor::Local("for!"), + args: [ + BinOp{ + op: "..", + lhs: Literal(0), + rhs: Literal(10), + }, + Lambda{ + sig: LambdaSignature{ + params: [ + ParamSignature{ + pat: ParamPattern::Name(VarName("i")), + }, + ], + spec_ret_t: None, + }, + body: Block[ + Call{ + obj: Accessor::Attr{"v", "push!"}, + args: [ + Accessor::Local("i"), + ], + }, + ], + }, + ], + }, + Call{ + obj: Accessor::Local("log"), + args: [ + Call{ + obj: Accessor::Attr("v", "sum"), + args: [], + } + ], + } +]) +``` + +从 AST 生成的 HIR 如下所示: + +```python +HIR(Module[ + VarDef{ + sig: VarSignature{ + pat: VarPattern::Ident(None, Name("v")), + t: [0..10, _]!, + }, + op: "=", + body: Block[ + expr: UnaryOp{ + op: "!", + expr: Array([]), + t: [0..10, 0]!, + }, + ], + }, + Call{ + obj: Accessor::Local{ + name: "for!", + t: (Range Nat, Nat => NoneType) => NoneType, + }, + args: [ + BinOp{ + op: "..", + lhs: Literal(0), + rhs: Literal(10), + t: 0..10, + }, + Lambda{ + sig: LambdaSignature{ + params: [ + ParamSignature{ + pat: ParamPattern::Name(Name("i")), + t: 0..10, + }, + ], + t: 0..10 => NoneType, + }, + body: Block[ + Call{ + obj: Accessor::Attr{ + obj: Accessor::Local("v"), + field: "push!", + t: Ref!(Self![T ~> T, N ~> N+1]).(Nat) => NoneType, + }, + args: [ + Accessor::Local("i"), + ], + }, + ], + }, + ], + }, + Call{ + obj: Accessor::Local{ + name: "log", + t: ...Object => NoneType, + }, + args: [ + Call{ + obj: Accessor::Attr{ + obj: Accessor::Local("v"), + field: "sum", + t: [0..10, !_] -> Nat + }, + args: [], + t: Nat + } + ], + } +]) +``` + +对象类型被推断为尽可能小。 另一方面,子例程推断实现存在的类型 +因此,实际参数的类型和形式参数的类型可能不匹配 \ No newline at end of file diff --git a/doc/zh_TW/compiler/index.md b/doc/zh_TW/compiler/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/compiler/inference.md b/doc/zh_TW/compiler/inference.md new file mode 100644 index 00000000..40aaf89b --- /dev/null +++ b/doc/zh_TW/compiler/inference.md @@ -0,0 +1,438 @@ +# 类型推断算法 + +> __Warning__:此部分正在编辑中,可能包含一些错误 + +显示了下面使用的符号 + +```python +Free type variables (type, unbound): ?T, ?U, ... +Free-type variables (values, unbound): ?a, ?b, ... +type environment (Γ): { x: T, ... } +Type assignment rule (S): { ?T --> T, ... } +Type argument evaluation environment (E): { e -> e', ... } +``` + +我们以下面的代码为例: + +```python +v = ![] +v.push! 1 +print! v +``` + +Erg 的类型推断主要使用 Hindley-Milner 类型推断算法(尽管已经进行了各种扩展)。具体而言,类型推断是通过以下过程执行的。术语将在后面解释。 + +1. 推断右值的类型(搜索) +2. 实例化结果类型 +3. 如果是调用,执行类型替换(substitute) +4. 解决已经单态化的特征 +5. 如果有类型变量值,求值/归约(eval) +6. 删除链接类型变量(deref) +7. 传播可变依赖方法的变化 +8. 如果有左值并且是Callable,则泛化参数类型(generalize) +9. 如果有左值,对(返回值)类型进行泛化(generalize) +10. 如果是赋值,则在符号表(`Context`)中注册类型信息(更新) + +具体操作如下。 + +第 1 行。 Def{sig: v, block: ![]} + 获取块类型: + 获取 UnaryOp 类型: + getArray 类型:`['T; 0]` + 实例化:`[?T; 0]` + (替代,评估被省略) + 更新:`Γ: {v: [?T; 0]!}` + 表达式 返回`NoneType`:OK + +第 2 行 CallMethod {obj: v, name: push!, args: [1]} + 获取 obj 类型:`Array!(?T, 0)` + 搜索:`Γ Array!(?T, 0).push!({1})` + 得到:`= Array!('T ~> 'T, 'N ~> 'N+1).push!('T) => NoneType` + 实例化:`Array!(?T, ?N).push!(?T) => NoneType` + 替代(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!(Nat) => NoneType` + 评估: `Array!(Nat, 0 ~> 1).push!({1}) => NoneType` + 更新:`Γ:{v:[Nat; 1]!}` + 表达式 返回`NoneType`:OK + +第 3 行。调用 {obj: print!, args: [v]} + 获取参数类型:`[[Nat; 1]!]` + 获取 obj 类型: + 搜索:`Γ print!([Nat; 1]!)` + 得到:`= print!(...Object) => NoneType` + 表达式 返回`NoneType`:OK + +## 类型变量的实现 + +类型变量最初在 [ty.rs](../../src/common/ty.rs) 的 `Type` 中表示如下。它现在以不同的方式实现,但本质上是相同的想法,所以我将以更天真的方式考虑这种实现。 +`RcCell` 是 `Rc>` 的包装类型。 + +```rust +pub enum Type { + ... + Var(RcCell>), // a reference to the type of other expression, see docs/compiler/inference.md + ... +} +``` + +类型变量可以通过将实体类型保存在外部字典中来实现,并且类型变量本身只有它的键。但是,据说使用 `RcCell` 的实现通常更有效(需要验证,[来源](https://mobile.twitter.com/bd_gfngfn/status/1296719625086877696?s=21))。 + +类型变量首先被初始化为 `Type::Var(RcCell::new(None))`。 +当分析代码并确定类型时,会重写此类型变量。 +如果内容直到最后都保持为 None ,它将是一个无法确定为具体类型的类型变量(当场)。例如,具有 `id x = x` 的 `x` 类型。 +我将这种状态下的类型变量称为 __Unbound 类型变量__(我不知道确切的术语)。另一方面,我们将分配了某种具体类型的变量称为 __Linked 类型变量__。 + +两者都是自由类型变量(该术语显然以“自由变量”命名)。这些是编译器用于推理的类型变量。它之所以有这样一个特殊的名字,是因为它不同于程序员指定类型的类型变量,例如 `id: 'T -> 'T` 中的 `'T`。 + +未绑定类型变量表示为`?T`、`?U`。在类型论的上下文中,经常使用 α 和 β,但这一种是用来简化输入的。 +请注意,这是出于一般讨论目的而采用的表示法,实际上并未使用字符串标识符实现。 + +进入类型环境时,未绑定的类型变量 `Type::Var` 被替换为 `Type::MonoQuantVar`。这称为 __quantified 类型变量__。这类似于程序员指定的类型变量,例如“T”。内容只是一个字符串,并没有像自由类型变量那样链接到具体类型的工具。 + +用量化类型变量替换未绑定类型变量的操作称为__generalization__(或泛化)。如果将其保留为未绑定类型变量,则类型将通过一次调用固定(例如,调用 `id True` 后,`id 1` 的返回类型将是 `Bool`),所以它必须是概括的。 +以这种方式,在类型环境中注册了包含量化类型变量的通用定义。 + +## 概括、类型方案、具体化 + +让我们将未绑定类型变量 `?T` 泛化为 `gen` 的操作表示。令生成的广义类型变量为 `|T: Type| T`。 +在类型论中,量化类型,例如多相关类型 `α->α`,通过在它们前面加上 `∀α.` 来区分(像 ∀ 这样的符号称为(通用)量词。)。 +这样的表示(例如`∀α.α->α`)称为类型方案。 Erg 中的类型方案表示为 `|T: Type| T -> T`。 +类型方案通常不被认为是一流的类型。以这种方式配置类型系统可以防止类型推断起作用。但是,在尔格中,在一定条件下可以算是一流的类型。有关详细信息,请参阅 [rank2 类型](../syntax/type/advanced/rank2type.md)。 + +现在,当在使用它的类型推断(例如,`id 1`,`id True`)中使用获得的类型方案(例如`'T -> 'T(id's type scheme)`)时,必须释放generalize。这种逆变换称为 __instantiation__。我们将调用操作`inst`。 + +```python +gen ?T = 'T +inst 'T = ?T (?T ∉ Γ) +``` + +重要的是,这两个操作都替换了所有出现的类型变量。 例如,如果你实例化 `'T -> 'T`,你会得到 `?T -> ?T`。 +实例化需要替换 dict,但为了泛化,只需将 `?T` 与 `'T` 链接以替换它。 + +之后,给出参数的类型以获取目标类型。 此操作称为类型替换,将用 `subst` 表示。 +此外,如果表达式是调用,则获取返回类型的操作表示为 `subst_call_ret`。 第一个参数是参数类型列表,第二个参数是要分配的类型。 + +类型替换规则 `{?T --> X}` 意味着将 `?T` 和 `X` 重写为相同类型。 此操作称为 __Unification__。 `X` 也可以是类型变量。 +[单独部分](./unification.md) 中描述了详细的统一算法。 我们将统一操作表示为“统一”。 + +```python +unify(?T, Int) == Ok(()) # ?T == (Int) + +# S为类型分配规则,T为适用类型 +subst(S: {?T --> X}, T: ?T -> ?T) == X -> X +# Type assignment rules are {?T --> X, ?U --> T} +subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y +``` + +## 半统一(semi-unification) + +统一的一种变体称为半统一(__Semi-unification__)。 这是更新类型变量约束以满足子类型关系的操作。 +在某些情况下,类型变量可能是统一的,也可能不是统一的,因此称为“半”统一。 + +例如,在参数分配期间会发生半统一。 +因为实际参数的类型必须是形式参数类型的子类型。 +如果参数类型是类型变量,我们需要更新子类型关系以满足它。 + +```python +# 如果形参类型是T +f(x: T): T = ... + +a: U +# 必须为 U <: T,否则类型错误 +f(a) +``` + +## 泛化 + +泛化不是一项简单的任务。 当涉及多个作用域时,类型变量的“级别管理”就变得很有必要了。 +为了看到层级管理的必要性,我们首先确认没有层级管理的类型推断会导致问题。 +推断以下匿名函数的类型。 + +```python +x -> + y = x + y +``` + +首先,Erg 分配类型变量如下: +y 的类型也是未知的,但暂时未分配。 + +```python +x(: ?T) -> + y = x + y +``` + +首先要确定的是右值 x 的类型。 右值是一种“用途”,因此我们将其具体化。 +但是 x 的类型 `?T` 已经被实例化了,因为它是一个自由变量。 Yo`?T` 成为右值的类型。 + +```python +x(: ?T) -> + y = x (: inst ?T) + y +``` + +注册为左值 y 的类型时进行泛化。 然而,正如我们稍后将看到的,这种概括是不完善的,并且会产生错误的结果。 + +```python +x(: ?T) -> + y(:gen?T) = x(:?T) + y +``` + +```python +x(: ?T) -> + y(: 'T) = x + y +``` + +y 的类型现在是一个量化类型变量“T”。 在下一行中,立即使用 `y`。 具体的。 + +```python +x: ?T -> + y(: 'T) = x + y(: inst 'T) +``` + +请注意,实例化必须创建一个与任何已经存在的(自由)类型变量不同的(自由)类型变量(概括类似)。 这样的类型变量称为新类型变量。 + +```python +x: ?T -> + y = x + y(: ?U) +``` + +并查看生成的整个表达式的类型。 `?T -> ?U`。 +但显然这个表达式应该是`?T -> ?T`,所以我们知道推理有问题。 +发生这种情况是因为我们没有“级别管理”类型变量。 + +所以我们用下面的符号来介绍类型变量的层次。 级别表示为自然数。 + +```python +# 普通类型变量 +?T<1>, ?T<2>, ... +# 具有子类型约束的类型变量 +?T<1>(<:U) or ?T(<:U)<1>, ... +``` + +让我们再尝试一次: + +```python +x -> + y = x + y +``` + +首先,按如下方式分配一个 leveled 类型变量: toplevel 级别为 1。随着范围的加深,级别增加。 +函数参数属于内部范围,因此它们比函数本身高一级。 + +```python +# level 1 +x (: ?T<2>) -> + # level 2 + y = x + y +``` + +首先,实例化右值`x`。和以前一样,没有任何改变。 + +```python +x (: ?T<2>) -> + y = x (: inst ?T<2>) + y +``` + +这是关键。 这是分配给左值`y`的类型时的概括。 +早些时候,这里的结果很奇怪,所以我们将改变泛化算法。 +如果类型变量的级别小于或等于当前范围的级别,则泛化使其保持不变。 + +```python +gen ?T = if n <= current_level, then= ?T, else= 'T +``` + +```python +x (: ?T<2>) -> + # current_level = 2 + y(: gen ?T<2>) = x(: ?T<2>) + y +``` + +That is, the lvalue `y` has type `?T<2>`. + +```python +x (: ?T<2>) -> + # ↓ 不包括 + y(: ?T<2>) = x + y +``` + +y 的类型现在是一个未绑定的类型变量 `?T<2>`。 具体如下几行:但是 `y` 的类型没有被概括,所以什么也没有发生 + +```python +x (: ?T<2>) -> + y(: ?T<2>) = x + y (: inst ?T<2>) +``` + +```python +x (: ?T<2>) -> + y = x + y (: ?T<2>) +``` + +我们成功获得了正确的类型`?T<2> -> ?T<2>`。 + +让我们看另一个例子。 这是更一般的情况,具有函数/运算符应用程序和前向引用。 + +```python +fx, y = id(x) + y +id x = x + +f10,1 +``` + +让我们逐行浏览它。 + +在 `f` 的推断过程中,会引用后面定义的函数常量 `id`。 +在这种情况下,在 `f` 之前插入一个假设的 `id` 声明,并为其分配一个自由类型变量。 +注意此时类型变量的级别是`current_level`。 这是为了避免在其他函数中泛化。 + +```python +id: ?T<1> -> ?U<1> +f x (: ?V<2>), y (: ?W<2>) = + id(x) (: subst_call_ret([inst ?V<2>], inst ?T<1> -> ?U<1>)) + y +``` + +类型变量之间的统一将高级类型变量替换为低级类型变量。 +如果级别相同,则无所谓。 + +类型变量之间的半统一有点不同。 +不同级别的类型变量不得相互施加类型约束。 + +```python +# BAD +f x (: ?V<2>), y (: ?W<2>) = + # ?V<2>(<: ?T<1>) + # ?T<1>(:> ?V<2>) + id(x) (: ?U<1>) + y (: ?W<2>) +``` + +这使得无法确定在何处实例化类型变量。 +对于 Type 类型变量,执行正常统一而不是半统一。 +也就是说,统一到下层。 + +```python +# OK +f x (: ?V<2>), y (: ?W<2>) = + # ?V<2> --> ?T<1> + id(x) (: ?U<1>) + y (: ?W<2>) +``` + +```python +f x (: ?T<1>), y (: ?W<2>) = + (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], inst |'L <: Add('R)| ('L, 'R) -> 'L .AddO) +``` + +```python +f x (: ?T<1>), y (: ?W<2>) = + (id(x) + x): subst_call_ret([inst ?U<1>, inst ?W<2>], (?L(<: Add(?R<2>))<2>, ?R<2 >) -> ?L<2>.AddO) +``` + +```python +id: ?T<1> -> ?U<1> +f x (: ?T<1>), y (: ?W<2>) = + # ?U<1>(<: Add(?W<2>)) # Inherit the constraints of ?L + # ?L<2> --> ?U<1> + # ?R<2> --> ?W<2> (not ?R(:> ?W), ?W(<: ?R)) + (id(x) + x) (: ?U<1>.AddO) +``` + +```python +# current_level = 1 +f(x, y) (: gen ?T<1>, gen ?W<2> -> gen ?U<1>.AddO) = + id(x) + x +``` + +```python +id: ?T<1> -> ?U<1> +f(x, y) (: |'W: Type| (?T<1>, 'W) -> gen ?U<1>(<: Add(?W<2>)).AddO) = + id(x) + x +``` + +```python +f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) = + id(x) + x +``` + +定义时,提高层次,使其可以泛化。 + +```python +# ?T<1 -> 2> +# ?U<1 -> 2> +id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>) +``` + +如果已经分配了返回类型,则与结果类型统一(`?U<2> --> ?T<2>`)。 + +```python +# ?U<2> --> ?T<2> +f(x, y) (: |'W: Type| (?T<2>, 'W) -> ?T<2>(<: Add(?W<2>)).AddO) = + id(x) + x +# current_level = 1 +id(x) (: gen ?T<2> -> gen ?T<2>) = x (: ?T<2>) +``` + +如果类型变量已经被实例化为一个简单的类型变量, +依赖于它的类型变量也将是一个 Type 类型变量。 +广义类型变量对于每个函数都是独立的。 + +```python +f(x, y) (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = + id(x) + x +id(x) (: |'T: Type| 'T -> gen 'T) = x +``` + +```python +f x, y (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = + id(x) + y +id(x) (: 'T -> 'T) = x + +f(10, 1) (: subst_call_ret([inst {10}, inst {1}], inst |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T .AddO) +``` + +```python +f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<1>) -> ? T<1>.AddO)) +``` + +类型变量绑定到具有实现的最小类型 + +```python +# ?T(:> {10} <: Add(?W<1>))<1> +# ?W(:> {1})<1> +# ?W(:> {1})<1> <: ?T<1> (:> {10}, <: Add(?W(:> {1})<1>)) +# serialize +# {1} <: ?W<1> or {10} <: ?T<1> <: Add({1}) <: Add(?W<1>) +# Add(?W)(:> ?V) 的最小实现特征是 Add(Nat) == Nat,因为 Add 相对于第一个参数是协变的 +# {10} <: ?W<1> or {1} <: ?T<1> <: Add(?W<1>) <: Add(Nat) == Nat +# ?T(:> ?W(:> {10}) or {1}, <: Nat).AddO == Nat # 如果只有一个候选人,完成评估 +f(10, 1) (: (?W(:> {10}, <: Nat), ?W(:> {1})) -> Nat) +# 程序到此结束,所以去掉类型变量 +f(10, 1) (: ({10}, {1}) -> Nat) +``` + +整个程序的结果类型是: + +```python +f|W: Type, T <: Add(W)|(x: T, y: W): T.AddO = id(x) + y +id|T: Type|(x: T): T = x + +f(10, 1): Nat +``` + +我还重印了原始的、未明确键入的程序。 + +```python +fx, y = id(x) + y +id x = x + +f(10, 1) +``` \ No newline at end of file diff --git a/doc/zh_TW/compiler/overview.md b/doc/zh_TW/compiler/overview.md new file mode 100644 index 00000000..e5e5c7f8 --- /dev/null +++ b/doc/zh_TW/compiler/overview.md @@ -0,0 +1,36 @@ +# `erg` 概览 + +我们将介绍每一层的功能以及特别重要的功能和方法。 + +## 1. 词法分析 + +* `Lexer` 进行词法分析。 `Lexer::next`(`Lexer`被实现为一个迭代器)负责词法分析的主要逻辑。 `Token` 作为解析的结果输出。 + +## 2. 解析 + +* `Parser` 进行解析。特别重要的是`Parser::parse_expr`。作为解析的结果,输出作为`ast::Expr`的集合的`AST`。 + +## 3. 脱糖 + +* 脱糖由 `Desugarer` 完成。 `AST` 将被输出。 + +## 4. 类型检查/类型推断 + +* `ASTLowerer` 进行打字。类型检查主要由 `Context` 完成。尤其重要的是 `Context::supertype_of`(确定子类型关系)、`Context::unify/sub_unify`(统一/半统一类型变量)、`Context::init_builtin_*`(定义内置 API)。 `HIR` 作为分析结果输出。 + +## 5. 副作用检查 + +* `SideEffectChecker` 可以。 + +## 6. 所有权检查 + +* `OwnershipChecker` 可以。 + +## 7. 字节码生成 + +* `CodeGenerator` 将 `HIR` 转换为 `CodeObj`。 `CodeObj` 保存字节码和执行配置。特别重要的是`CodeGenerator::compile_expr`。 + +--- + +* 以上所有的处理都是由`Compiler`作为一个门面组合起来的。 +* 当然 Python 会执行生成的字节码,称为 `DummyVM`。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/parsing.md b/doc/zh_TW/compiler/parsing.md new file mode 100644 index 00000000..c790e086 --- /dev/null +++ b/doc/zh_TW/compiler/parsing.md @@ -0,0 +1,33 @@ +# 解析 Erg 语言 + +## 空格的处理 + +尔格语法的一个特点是它对空间敏感。 +这是为了弥补因省略`()`而造成的表达力损失。在 Nim 中可以找到类似的语法,它也允许省略 `()`。 + +```python +f +1 == f(+1) +f + 1 == `+`(f, 1) +f (1,) == f((1,)) +f(1,) == f(1) +(f () -> ...) == f(() -> ...) +(f() -> ...) == (f() -> ...) +``` + +## 左值,右值 + +在 Erg 中,左侧的值并不像 `=` 的左侧那么简单。 +事实上,`=` 左侧有一个右值(非常令人困惑),而 `=` 右侧有一个左值。 +右值中甚至可以有左值。 + +```python +# i 是左边的值,Array(Int) 和 [1, 2, 3] 是右边的值 +i: Array(Int) = [1, 2, 3] +# `[1, 2, 3].iter().map i -> i + 1`是右边的值,但是->左边的i是左边的值 +a = [1, 2, 3].iter().map i -> i + 1 +# {x = 1; y = 2} 是右侧值,但 x, y 是左侧值 +r = {x = 1; y = 2} +``` + +左侧和右侧值的精确定义是“如果它是可评估的,则为右侧值,否则为左侧值”。 +例如,考虑代码 ``i = 1; i``,其中第二个 `i` 是右侧值,因为它是可评估的,但第一个 `i` 是左侧值。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/refinement_subtyping.md b/doc/zh_TW/compiler/refinement_subtyping.md new file mode 100644 index 00000000..631a9da8 --- /dev/null +++ b/doc/zh_TW/compiler/refinement_subtyping.md @@ -0,0 +1,147 @@ +# 筛子类型 + +```python +{I: Int | I >= 0} +{S: StrWithLen N | N >= 1} +{T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0} +``` + +Erg 通过将 Enum 和 Interval 类型转换为筛选类型来实现类型确定。 + +## 转换为筛型 + +在 [Sieve types] 一节中,我们说过区间类型和枚举类型是 sieve 类型的语法糖。每个转换如下。 + +* {0} -> {I: Int | I == 0} +* {0, 1} -> {I: Int | I == 0 or I == 1} +* 1.._ -> {I: Int | I >= 1} +* 1<.._ -> {I: Int | I > 1} -> {I: Int | I >= 2} +* {0} or 1.._ -> {I: Int | I == 0 or I >= 1} +* {0} or {-3, -2} or 1.._ -> {I: Int | I == 0 or (I == -2 or I == -3) or I >= 1} +* {0} and {-3, 0} -> {I: Int | I == 0 and (I == -3 or I == 0)} +* {0} not {-3, 0} or 1.._ -> {I: Int | I == 0 and not (I == -3 or I == 0) or I >= 1} + +## 筛型检测 + +描述了一种用于确定筛类型 A 是否是另一筛类型 B 的子类型的算法。正式地,(所有)子类型定义如下: + +```console +A <: B <=> ∀a∈A; a∈B +``` + +具体而言,应用以下推理规则。假定布尔表达式是简化的。 + +* 间隔规则(从类型定义自动完成) + * `Nat` => `{I: Int | I >= 0}` +* 围捕规则 + * `{I: Int | I < n}` => `{I: Int | I <= n-1}` + * `{I: Int | I > n}` => `{I: Int | I >= n+1}` + * `{R: Ratio | R < n}` => `{R: Ratio | R <= n-ε}` + * `{R: Ratio | R > n}` => `{R: Ratio | R >= n+ε}` +* 反转规则 + * `{A not B}` => `{A and (not B)}` +* 德摩根规则 + * `{not (A or B)}` => `{not A and not B}` + * `{not (A and B)}` => `{not A or not B}` +* 分配规则 + * `{A and (B or C)} <: D` => `{(A and B) or (A and C)} <: D` => `({A and B} <: D) and ( {A and C} <: D)` + * `{(A or B) and C} <: D` => `{(C and A) or (C and B)} <: D` => `({C and A} <: D) and ( {C and B} <: D)` + * `D <: {A or (B and C)}` => `D <: {(A or B) and (A or C)}` => `(D <: {A or B}) and ( D <: {A or C})` + * `D <: {(A and B) or C}` => `D <: {(C or A) and (C or B)}` => `(D <: {C or A}) and ( D <: {C or B})` + * `{A or B} <: C` => `({A} <: C) and ({B} <: C)` + * `A <: {B and C}` => `(A <: {B}) and (A <: {C})` +* 终止规则 + * {I: T | ...} <: T = True + * {} <: _ = True + * _ <: {...} = True + * {...} <: _ = False + * _ <: {} == False + * {I >= a and I <= b} (a < b) <: {I >= c} = (a >= c) + * {I >= a and I <= b} (a < b) <: {I <= d} = (b <= d) + * {I >= a} <: {I >= c or I <= d} (c >= d) = (a >= c) + * {I <= b} <: {I >= c or I <= d} (c >= d) = (b <= d) + * {I >= a and I <= b} (a <= b) <: {I >= c or I <= d} (c > d) = ((a >= c) or (b <= d )) + * 基本公式 + * {I >= l} <: {I >= r} = (l >= r) + * {I <= l} <: {I <= r} = (l <= r) + * {I >= l} <: {I <= r} = False + * {I <= l} <: {I >= r} = False + +布尔表达式的简化规则如下。 min, max 不能被删除。此外,多个 or, and 被转换为嵌套的 min, max。 + +* 组合规则 + * `I == a` => `I >= a 和 I <= a` + * `i != a` => `I >= a+1 或 I <= a-1` +* 一致性规则 + * `I >= a 或 I <= b (a < b)` == `{...}` +* 恒常规则 + * `I >= a 和 I <= b (a > b)` == `{}` +* 替换规则 + * 以 `I >= n` 和 `I <= n` 的顺序替换顺序表达式。 +* 扩展规则 + * `I == n 或 I >= n+1` => `I >= n` + * `I == n 或 I <= n-1` => `I <= n` +* 最大规则 + * `I <= m 或 I <= n` => `I <= max(m, n)` + * `I >= m 和 I >= n` => `I >= max(m, n)` +* 最低规则 + * `I >= m 或 I >= n` => `I >= min(m, n)` + * `I <= m 和 I <= n` => `I <= min(m, n)` +* 淘汰规则 + * 当 `I >= a (n >= a)` 或 `I <= b (n <= b)` 或 `I == n` 在右侧时,左侧的 `I == n` 被删除能够。 + * 如果无法消除所有左手方程,则为 False + +例如 + +```python +1.._<: Nat +=> {I: Int | I >= 1} <: {I: Int | I >= 0} +=> {I >= 1} <: {I >= 0} +=> (I >= 0 => I >= 1) +=> 1 >= 0 +=> True +# {I >= l} <: {I >= r} == (l >= r) +# {I <= l} <: {I <= r} == (l <= r) +``` + +```python +{I: Int | I >= 0} <: {I: Int | I >= 1 or I <= -3} +=> {I >= 0} <: {I >= 1 or I <= -3} +=> {I >= 0} <: {I >= 1} or {I >= 0} <: {I <= -3} +=> False or False +=> False +``` + +```python +{I: Int | I >= 0} <: {I: Int | I >= -3 and I <= 1} +=> {I >= 0} <: {I >= -3 and I <= 1} +=> {I >= 0} <: {I >= -3} and {I >= 0} <: {I <= 1} +=> True and False +=> False +``` + +```python +{I: Int | I >= 2 or I == -2 or I <= -4} <: {I: Int | I >= 1 or I <= -1} +=> {I >= 2 or I <= -4 or I == -2} <: {I >= 1 or I <= -1} +=> {I >= 2 or I <= -4} <: {I >= 1 or I <= -1} + and {I == -2} <: {I >= 1 or I <= -1} +=> {I >= 2} <: {I >= 1 or I <= -1} + and {I <= -4} <: {I >= 1 or I <= -1} + and + {I == -2} <: {I >= 1} + or {I == -2} <: {I <= -1} +=> {I >= 2} <: {I >= 1} + or {I >= 2} <: {I <= -1} + and + {I <= -4} <: {I >= 1} + or {I <= -4} <: {I <= -1} + and + False or True +=> True or False + and + False or True + and + True +=> True and True +=> True +``` \ No newline at end of file diff --git a/doc/zh_TW/compiler/trait_method_resolving.md b/doc/zh_TW/compiler/trait_method_resolving.md new file mode 100644 index 00000000..66574713 --- /dev/null +++ b/doc/zh_TW/compiler/trait_method_resolving.md @@ -0,0 +1,95 @@ +# 解决补丁方法 + +`Nat` 是零个或多个`Int`,`Int` 的子类型。 +`Nat` 在 Python 类层次结构中不存在。 我想知道 Erg 是如何解决这个补丁方法的? + +```python +1.times do: + log "hello world" +``` + +`.times` 是一种 `NatImpl` 补丁方法。 +由于`1`是`Int`的一个实例,首先通过跟踪`Int`的MRO(方法解析顺序)来搜索它。 +Erg 在 `Int` 的 MRO 中有 `Int`、`Object`。它来自 Python(Python 中的`int.__mro__ == [int, object]`)。 +`.times` 方法在它们中都不存在。现在让我们探索那个子类型。 + +~ + +整数显然应该在其超类型中包含实数、复数甚至整数,但这一事实并没有出现在 Python 兼容层中。 +然而,`1 in Complex` 和 `1 in Num` 在 Erg 中实际上是 `True`。 +至于`Complex`,即使是与`Int`没有继承关系的类,也被判断为类型兼容。这到底是怎么回事? + +~ + +一个对象有无数种它所属的类型。 +但是我们真的只需要考虑带有方法的类型,即带有名称的类型。 + +Erg 编译器有一个补丁类型的哈希图,其中包含所有提供的方法及其实现。 +每次定义新类型时都会更新此表。 + +```python +provided_method_table = { + ... + "foo": [Foo], + ... + ".times": [Nat, Foo], + ... +} +``` + +具有 `.times` 方法的类型是 `Nat`、`Foo`。从这些中,找到与“{1}”类型匹配的一个。 +有两种类型的符合性确定。它们是筛式判断和记录式判断。这是通过筛子类型确定来完成的。 + +##筛型确定 + +检查候选类型是否与 `1` 的类型 `{1}` 兼容。与“{1}”兼容的筛子类型有“{0, 1}”、“0..9”等。 +有限元代数类型,例如 `0..1 或 3..4`、`-1..2 和 0..3`,在声明为基本类型(即 {0, 1, 3, 4}`,`{0, 1, 2}`)。 +在这种情况下,`Nat` 是 `0.._ == {I: Int | I >= 0}`,所以 `{1}` 与 `Nat` 兼容。 + +## 确定记录类型 + +检查候选类型是否与 `Int` 兼容,1 类。 +其他是`Int`的修复程序并且`Int`具有所有必需属性的也是兼容的。 + +~ + +所以`Nat`适合。但是,如果 `Foo` 也匹配,则由 `Nat` 和 `Foo` 之间的包含关系决定。 +即,选择子类型方法。 +如果两者之间没有包含关系,则会发生编译错误(这是一种安全措施,防止违背程序员的意图执行方法)。 +要消除错误,您需要明确指定补丁。 + +```python +o.method(x) -> P.method(o, x) +``` + +## 通用方法解析修补程序 + +像这样定义一个补丁: + +```python +FnType T: Type = Patch T -> T +FnType.type = T +``` + +在 `FnType` 补丁下可以使用如下代码。 我想知道这将如何解决。 + +```python +assert (Int -> Int).type == Int +``` + +首先,`FnType(T)` 以下列格式注册到`provided_method_table` 中。 + +```python +provided_method_table = { + ... + "type": [FnType(T)], + ... +} +``` + +`FnType(T)` 检查匹配类型。 在这种情况下,`FnType(T)` 补丁类型是 `Type -> Type`。 +这匹配 `Int -> Int`。 如果合适,进行单态化和替换(取 `T -> T` 和 `Int -> Int`、`{T => Int}` 的差异)。 + +```python +assert FnType(Int).type == Int +``` \ No newline at end of file diff --git a/doc/zh_TW/compiler/transpile.md b/doc/zh_TW/compiler/transpile.md new file mode 100644 index 00000000..396c72d7 --- /dev/null +++ b/doc/zh_TW/compiler/transpile.md @@ -0,0 +1,90 @@ +# Erg 代码如何转译成 Python 代码? + +准确地说,Erg 代码被转译为 Python 字节码。 +但是,由于 Python 字节码几乎可以重构为 Python 代码,因此这里以等效的 Python 代码为例。 +顺便说一句,这里展示的示例是低优化级别。 +更高级的优化消除了不需要实例化的东西。 + +## 记录,记录类型 + +它将被转译为一个命名元组。 +对于 namedtuple,请参阅 [此处](https://docs.python.jp/3/library/collections.html#collections.namedtuple)。 +有一个类似的函数,dataclass,但是由于 `__eq__` 和 `__hash__` 的自动实现,dataclass 的性能略有下降。 + +```python +Employee = Class {.name = Str; .id = Int} + +employee = Employee.new({.name = "John Smith"; .id = 100}) + +assert employee.name == "John Smith" +``` + +```python +from typing import NamedTuple + +class Employee(NamedTuple): + __records__ = ['name', 'id'] + name: str + id: int + +employee = Employee('John Smith', 100) + +assert employee.name == 'John Smith' +``` + +如果可以进一步优化,它也将转换为简单的元组。 + +## 多态类型 + +> 在制品 + +## 即时范围 + +如果没有发生命名空间冲突,它只会被破坏和扩展。 +`x::y` 等名称在字节码中使用,不能与 Python 代码关联,但如果强制表示,则会如下所示。 + +```python +x = + y = 1 + y+1 +``` + +```python +x::y = 1 +x = x::y + 1 +``` + +万一发生冲突,定义和使用只能在内部引用的函数。 + +```python +x = + y = 1 + y+1 +``` + +```python +def _(): + x=1 + y = x + return y + 1 +x = _() +``` + +## 可见性 + +它对公共变量没有任何作用,因为它是 Python 的默认值。 +私有变量由 mangling 处理。 + +```python +x=1 +y = + x = 2 + assert module::x == 2 +``` + +```python +module::x = 1 +y::x = 2 +assert module::x == 2 +y = None +``` \ No newline at end of file diff --git a/doc/zh_TW/compiler/type_var_normalization.md b/doc/zh_TW/compiler/type_var_normalization.md new file mode 100644 index 00000000..fded3f21 --- /dev/null +++ b/doc/zh_TW/compiler/type_var_normalization.md @@ -0,0 +1,39 @@ +# 归一化 + +* Erg 的类型参数规范化基于 SymPy 的简化函数。 + +例如,当您定义 `concat: |T, M, N|([T; M], [T; N] -> [T; M+N])` 时,您可以匹配类型变量和参数而无需实例化它们.必须作出判断。 +平等判断自然有其局限性,但目前可能的判断及其方法如下。 + +* 加法/乘法对称性: + + `n+m == m+n` + + 类型变量被排序和规范化为字符串。 + +* 加法、乘法、减法和除法等价: + + `n+n == 2*n` + + 归一化为 Σ[c] x == c*x,其中 c 是一个常数。 + 常量通过将它们放在二进制操作的左侧进行标准化。 + +* 双重表达式的相等性: + + `n+m+l == m+n+l == l+m+n == ...` + `n+m*l == m*l+n` + + 通过排序归一化确定。 + 乘法和除法块放置在加法和减法的左侧。通过比较最左侧的类型变量对块进行排序。 + +* 基本不等式: + + `n > m -> m + 1 > n` + +* 平等: + + `n >= m 和 m >= n -> m == n` + +* 不等式的传递性: + + `n > 0 -> n > -1` \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/branches.md b/doc/zh_TW/dev_guide/branches.md new file mode 100644 index 00000000..c4380f04 --- /dev/null +++ b/doc/zh_TW/dev_guide/branches.md @@ -0,0 +1,35 @@ +# 分支机构命名和运营策略 + +## main + +* 主要开发分支 +* 必须满足以下条件 + +* 编译成功 + +## beta(目前不创建) + +* 最新的 Beta 版本 +* 必须满足以下条件 + +* 编译成功 +* 所有测试都会成功 + +## feature-* + +* 开发特定功能的分支 +* 切开 main + +* 没有条件 + +## issue-* + +* 解决特定 issue 的分支 + +* 没有条件 + +## fix-* + +* 修复特定错误的分支(如果该问题是一个错误,则代替`issue-*`创建)。 + +* 没有条件。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/build_features.md b/doc/zh_TW/dev_guide/build_features.md new file mode 100644 index 00000000..0de6c136 --- /dev/null +++ b/doc/zh_TW/dev_guide/build_features.md @@ -0,0 +1,21 @@ +# `erg` 构建功能 + +## 调试 + +进入调试模式。结果,Erg 内部的行为顺序显示在日志中。 +独立于 Rust 的 `debug_assertions` 标志。 + +## japanese + +将系统语言设置为日语。 +Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为日语。 + +## simplified_chinese + +将系统语言设置为简体中文。 +Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为简体中文。 + +## traditional_chinese + +将系统语言设置为繁体中文。 +Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为繁体中文。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/directories.md b/doc/zh_TW/dev_guide/directories.md new file mode 100644 index 00000000..a44615e3 --- /dev/null +++ b/doc/zh_TW/dev_guide/directories.md @@ -0,0 +1,24 @@ +# 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:测试代码 +``` \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/doc_guideline.md b/doc/zh_TW/dev_guide/doc_guideline.md new file mode 100644 index 00000000..56899909 --- /dev/null +++ b/doc/zh_TW/dev_guide/doc_guideline.md @@ -0,0 +1,13 @@ +# 格式 + +任何不符合以下规则的文件都将得到更正。 + +* 以某种语气写代码注释或内部文档。 +* 向外部(普通用户)展示的文档应该越来越多地编写。 +* 始终包含定义、含义或文档中首次出现的术语的链接。 +* 仅对理解正文所必需的补充句子使用括号作为附加条件,对于理解正文不是必需的句子使用脚注[1]( #1)。 +* 如果文档内容过时,按照【此方法】更新(https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)。 + +--- + +1 参见这里了解如何编写脚注。[↩](#f1) \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/env.md b/doc/zh_TW/dev_guide/env.md new file mode 100644 index 00000000..3c98f96d --- /dev/null +++ b/doc/zh_TW/dev_guide/env.md @@ -0,0 +1,19 @@ +# 开发环境 + +## 你需要安装什么 + +* Rust(与 rustup 一起安装) + + * 版本 >= 1.63.0 + * 2021年版 + +* [预提交](https://pre-commit.com/) + +* Python3 解释器 + +## 推荐 + +* 编辑器:Visual Studio Code +* VSCode 扩展:Rust-analyzer、GitLens、Git Graph、GitHub Pull Requests and Issues、Markdown All in One、markdownlint +* 操作系统:Windows 10/11 | Ubuntu 20.04/22.04 | Mac OS Monterey +* 其他:pyenv、模具 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/faq_syntax.md b/doc/zh_TW/dev_guide/faq_syntax.md new file mode 100644 index 00000000..9ff0b713 --- /dev/null +++ b/doc/zh_TW/dev_guide/faq_syntax.md @@ -0,0 +1,106 @@ +# Erg design's "Why" and Answers + +## 当我们有所有权系统时,为什么要与 GC 共存? + +因为 Erg 推出所有权系统的动机并不是为了 Rust 那样的“不依赖 GC 的内存管理”。最初,由于 Erg 是一种语言,目前使用 Python VM,因此最终仍使用 GC。Erg 引入产权系统的目标是“可变状态的局部化”。在 Erg 中,可变对象具有所有权概念。这是根据共享可变状态容易成为 bug 的温床,甚至是类型安全性的侵犯(详见)来判断的。 + +## 为什么类型参数周围的括号不是 <> 或 []? + +因为在和中会发生语法冲突。 + +```python +# []版 +id[T: Type] [t]: [T] = t +y = id[Int] # 这是一个功能吗? +# <>版 +id {t: T} = t +y = (id 1) # 这是一个元组吗? +# {}版 +id{T: Type} {t: T} = t +y = id{Int} # 这是一个功能吗? +# ||版 +id|T: Type| t: T = t +y = id|Int| # OK +``` + +## {i=1} 的类型为 {i=Int},但在 OCaml 等环境中为 {i:Int}。为什么 Erg 采用前者的语法? + +Erg 设计为将类型本身也视为值。 + +```python +A = [Int; 3] +assert A[2] == Int +T = (Int, Str) +assert T.1 == Str +D = {Int: Str} +assert D[Int] == Str +S = {.i = Int} +assert S.i == Int +``` + +## 你打算在 Erg 中实现宏吗? + +目前没有。宏观大致分为四个目的。第一个是编译时计算。这在 Erg 中由编译时函数负责。第二,代码执行的延迟。这可以用 do 块来代替。第三个是处理通用化,对此多相关数和全称类型是比宏观更好的解决方案。第四个是自动生成代码,但这会造成可读性的下降,所以我们不敢在 Erg 中实现。因此,宏的大部分功能都由 Erg 型系统承担,因此没有动力进行部署。 + +## 为什么 Erg 没有例外机制? + +在许多情况下,错误处理类型是更好的解决方案。类型是一种错误处理方法,通常在较新的编程语言中使用。 + +在 Erg 中,运算符使你可以在不太注意错误的情况下编写。 + + +```python +read_file!() = + f = open!("foo.txt")? # 如果失败则立即返回错误,所以 f 是文件类型 + f.read_all!() + +# 也可以使用 try 过程捕获类似的异常 +try!: + do! + s = read_file!()? + print! s + e => + # 发生错误时执行的块 + print! e + exit 1 +``` + +在引入 Python 函数时,缺省情况下,所有函数都被视为包含异常,返回类型为。如果你知道不调度异常,请在中指明。 + +此外,Erg 没有引入异常机制的另一个原因是它计划引入并行编程的功能。这是因为异常机制与并行执行不兼容(例如,如果并行执行导致多个异常,则很难处理)。 + +## Erg 似乎消除了 Python 被认为是坏做法的功能,但为什么没有取消继承? + +Python 的库中有一些类设计为继承,如果完全取消继承,这些操作就会出现问题。然而,由于 Erg 的类默认为 final,并且原则上禁止多重和多层继承,因此继承的使用相对安全。 + +## 为什么多相关数的子类型推理默认指向记名trait? + +默认情况下,指向结构托盘会使类型指定变得复杂,并且可能会混合程序员的非预期行为。 + + +```python +# 如果 T 是结构特征的子类型... +# f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T +f|T| x, y: T = x + y - x +# T 是名义特征的子类型 +# g: |T <: Add() and Sub()| (T, T) -> T +g|T| x, y: T = x + y - x +``` + +## Erg 是否实现了定义自己的运算符的功能? + +A:没有那个计划。最重要的原因是,如果允许定义自己的运算符,就会出现如何处理组合顺序的问题。可以定义自己的运算符的 Scala 和 Haskell 等都有不同的对应,但这可以看作是可能产生解释差异的语法的证据。此外,独立运算符还有一个缺点,那就是可能产生可读性较低的代码。 + +## 为什么 Erg 取消了 += 这样的扩展赋值运算符? + +首先,Erg 中没有变量的可变性。也就是不能重新赋值。一旦对象与一个变量关联,它将一直绑定到该变量,直到它脱离作用域并被释放。在 Erg 中,可变性是指对象的可变性。明白了这个,故事就简单了。例如,表示,但由于变量是不可重新赋值的,因此这种语法是非法的。还有一个 Erg 的设计原则是运算符没有副作用。Python 通常也是如此,但对于某些对象(如 Dict),扩展赋值运算符会更改对象的内部状态。这算不上是一个很漂亮的设计。因此,扩展赋值运算符被完全废弃。 + +## 为什么 Erg 在语法上特别对待有副作用的过程? + +副作用的局部化是代码维护的一个关键因素。 + +但是,确实也不是没有方法可以不在语言上特殊对待副作用。例如,可以用代数效果(类型系统上的功能)替代过程。但这样的合一并不总是正确的。例如,Haskell 没有对字符串进行特殊处理,只是一个字符数组,但这种抽象是错误的。 + +什么情况下,可以说合一化是错的?一个指标是“是否会因其合一而难以看到错误信息”。Erg 设计师发现,将副作用特殊处理会使错误消息更容易阅读。 + +Erg 有一个强大的类型系统,但并不是所有的类型都决定了它。如果这样做了,你的下场就跟 Java 试图用类来控制一切一样。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/i18n_messages.md b/doc/zh_TW/dev_guide/i18n_messages.md new file mode 100644 index 00000000..7a2fdbb5 --- /dev/null +++ b/doc/zh_TW/dev_guide/i18n_messages.md @@ -0,0 +1,55 @@ +# 多语言错误信息 + +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`)嵌入到字符串中。 + +## 构建 + +现在,我们使用选项构建它。 + +screenshot_i18n_messages + +你做到了! + +## FAQ + +Q:像这样的指定是什么意思?A:{RED} 及更高版本将显示为红色。重新启动交互渲染。 + +Q:如果想添加自己的语言,该如何替换部分?答:目前支持以下语言。 + +* "english"(默认设置) +* "japanese" (日语) +* "simplified_chinese" (简体中文) +* "traditional_chinese" (繁体中文) + +如果你想添加其他语言,请提出请求。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/index.md b/doc/zh_TW/dev_guide/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/dev_guide/rust_code_guideline.md b/doc/zh_TW/dev_guide/rust_code_guideline.md new file mode 100644 index 00000000..0c15a9f7 --- /dev/null +++ b/doc/zh_TW/dev_guide/rust_code_guideline.md @@ -0,0 +1,23 @@ +# Rust 代码指南 + +## 本地规则 + +* 使用 `log!` 进行调试输出(使用 `println!` 等进行输出处理,这也是发布所必需的)。 +* 未使用或内部变量/方法(私有且仅用于特定功能)必须以 `_` 为前缀。如果要避免与保留字冲突,请在末尾添加一个`_`。 + +## 推荐代码 + +* 定义和使用特定领域的枚举而不是数字枚举或布尔值。 +* 将访问修饰符保持在最低限度。即使在发布时也要优先使用 `pub(mod)` 或 `pub(crate)`。 +* 将 for 表达式中的可迭代对象显式转换为迭代器(`for i in x.iter()` 而不是 `for i in x`)。 +* 懒惰的评价。例如,如果 `default` 不是文字,请使用 `unwrap_or_else` 而不是 `unwrap_or`。 + +## 不鼓励使用代码 + +* 大量使用返回类型重载。特别是使用大量非显而易见的 `.into` 的代码。这是因为类型推断结果可能违反直觉。在这种情况下,建议使用 `from` 代替。 +* 大量使用 `Deref`。这有效地提出了与继承相同的问题。 + +## 根据上下文做出决策的代码 + +* 定义未使用的辅助方法。 +* 大量使用 `unwrap` 和 `clone`。在某些情况下,没有什么比这样做更好的了。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/terms.md b/doc/zh_TW/dev_guide/terms.md new file mode 100644 index 00000000..8dc55e6e --- /dev/null +++ b/doc/zh_TW/dev_guide/terms.md @@ -0,0 +1,838 @@ +# 词汇表 + +## 象征 + +### ! + +添加到标识符末尾的标记以指示它是过程,变量类型或变异运算符。 + +### [#](../syntax/00_basic.md/# comment) + +### $ + +### % + +### & + +### ′ (single quote) + +### () + +### * + +### + + +### , + +### − + +### -> + +### . + +### / + +### : + +### :: + +### ; + +### < + +### <: + +### << + +### <= + +### = + +### == + +### => + +### > + +### >> + +### >= + +### ? + +### @ + +### [] + +### \ + +### ^ + +### ^^ + +### _ + +### `` + +### {} + +### {:} + +### {=} + +### | + +### || + +### ~ + +## A + +### [algebraic type] + +### [And] + +### [and] + +### [assert] + +### [attribute] + +## B + +### [Base] + +### [Bool] + +## C + +### [Class] + +## D + +### Deprecated + +### [distinct] + +## E + +### [enum type] + +### [Eq] + +### [Erg] + +## F + +### [for] + +## G + +## H + +## I + +### [if] + +### [import] + +### [in] + +### [Int] + +## J + +## K + +## L + +### let-polymorphism -> [rank 1 polymorphism] + +### [log] + +## M + +### [match] + +## N + +### [Nat] + +### Never + +### None + +### [Not] + +### [not] + +## O + +### [Option] + +### [Or] + +### [or] + +### [Ord] + +## P + +### panic + +### [print!](../syntax/../API/procs.md#print) + +### [Python] + +## Q + +## R + +### ref + +### ref! + +### [Result] + +### [rootobj] + +## S + +### self + +### [Self](../syntax/type/special.md) + +### [side-effect](../syntax/07_side_effect.md) + +### [Str] + +## T + +### Traits + +### [True] + +### [Type] + +### [type] + +## U + +## V + +## W + +### [while!] + +## X + +## Y + +## Z + +## A line + +### [Assertion] + +检查(通常在运行时)代码中的条件是否为真。 这是使用 `assert` 函数等来完成的。 + +```python +sum = !0 +for! 0..10, i => + sum.add!i + +assert sum == 55 +``` + +### 值对象 + +在 Erg 中,相当于基础对象。 它可以在编译时进行评估,并且具有简单的比较方法。 + +### [附件补丁](../syntax/29_decorator.md#attach) + +为特征提供标准实现的补丁。 + +### Ad hoc 多态性 -> [无重载](../syntax/type/overloading.md) + +具有所谓重载的多态性。 + +### 属性-> [属性] + +`x.y` 标识符中的 `y` 部分。 + +### Arity + +运算符需要多少个操作数。 + +### [依赖类型](../syntax/type/dependent_type.md) + +参数是值的类型(习惯上说,不是类型)。 + +### 不可变 -> [不可变] + +表示目标不会改变。 +其他语言中的变量也是不可变/可变的,但是在 Erg 中所有的变量都是不可变的。 + +### 参数 -> [参数] + +### 实例 + +由类创建的对象。 类类型的元素。 + +### [即时封锁](../syntax/00_basic.md#expression separator) + +```python +x = + y = f(a) + z = g(b,c) + y+z +``` + +### 指数 + +形式为“x[i]”,或其“i”部分。我们称 `x` 为 Indexable 对象。 + +### [缩进](../syntax/00_basic.md#indent) + +通过向空格移动将文本向右对齐。缩进。 +Ergs 通过缩进表示块。这称为越位规则。 + +### 别名 + +别名。 + +### 错误 + +规范中定义的异常情况。 + +* [错误处理] + +### [运算符](../syntax/06_operator.md) + +将操作应用于其操作数的对象。或表示该对象的符号。 + +* [运算符绑定强度] + +### 覆盖 + +在子类中覆盖超类方法。 +在 Erg 中,您必须在覆盖时添加 `Override` 装饰器。 + +### [不重载](../syntax/type/overloading.md) + +### 越位规则-> [缩进](../syntax/00_basic.md#indent) + +### [目的] + +* 面向对象 + +### 操作数 -> [操作数](../syntax/06_operator.md) + +### 运算符 -> [运算符](../syntax/06_operator.md) + +##嘉线 + +### [种类](../syntax/type/advanced/kind.md) + +所谓类型的类型。 + +### [可见性] + +标识符是否可以被外部引用(超出范围,或在另一个模块或包中)的属性。 + +### [类型] + +对术语进行分组的对象。 + +* [类型规格] +* [类型擦除](../syntax/type/advanced/erasure.md) +* [类型推断] +* [类型注释](../syntax/type/conv_type.md) +* [类型参数] +* [类型添加](../syntax/type/advanced/erasure.md) +* [类型变量](../syntax/type/type_variable.md) +* [类型约束] + +### 监视 + +### 封装 + +隐藏实现细节。 + +### [多变的] + +不能是一成不变的。 + +* [可变对象] +* [多变的] +* [变量参考] +* [变量数组] +* [可变参数] + +### [函数](../syntax/04_function.md) + +没有副作用的子程序。 + +* [函数式编程](../syntax/23_scope.md#避免可变状态函数式编程) + +### 基本类型 + +###主格 + +通过名称而不是对称结构来区分。 + +* [命名类型] -> [类](../syntax/type/04_class.md) +* [报喜] +* [名义子类型](../syntax/type/05_nst_vs_sst.md) + +### 捕获-> [关闭] + +### [协变] + +在 Erg 中,如果 `T <: U` 则 `K(T) <: K(U)` 则称 `K` 是协变的。 + +### [关键字参数] + +`k` 以函数调用 `f(k: v)` 的形式出现。您可以通过形式参数名称而不是按顺序指定实际参数。 + +### 空集 -> [{}] + +### 部分 + +* [区间类型](../syntax/type/11_interval.md) +* 区间运算符 + +### 嵌入式 + +Erg 标准 API 未在 .er 文件中实现。 + +### [类](../syntax/type/04_class.md) + +具有继承功能的结构/抽象数据类型。在 Erg 中,它是一种实现命名子类型化和覆盖的类型。 +在 Erg 中,模块是模块对象负责,类型是类型对象,而其他语言可能负责模块和类型。 + +### [关闭] + +### [全局变量] + +### [克隆] + +### [继承](../syntax/type/07_inheritance.md) + +定义一个类是另一个类的父类集。 +继承的类称为超类,继承的类称为子类。 +子类具有其超类的所有功能。 + +### 高楼层 + +* [高阶种类](../syntax/type/advanced/kind.md) +* 高阶类型 +* 高阶函数 + +### [公共变量] + +### [结构子类型] + +### ~~后向引用~~ -> [后向引用] + +### [复制] + +### 评论 + +### [集合](../syntax/10_array.md) + +### 冒号 -> [:] + +### [构造函数](../syntax/type/04_class.md) + +### 容器 + +### 编译器 + +### [编译时计算](../syntax/04_function.md#compile-time function) + +### 逗号 -> [,] + +## sa线 + +### 递归 + +参考自己。 + +* 递归 +* [递归函数](../syntax/04_function.md#递归函数) + +### 下标 -> [索引] + +### [子类型多态性](../syntax/type/overloading.md) + +具有子类型的多态性。子类型对应于类型中的集合包含。 + +### 子程序 + +模块化处理的对象。 Erg 中函数、过程和方法的通用术语。 + +### [参考](../syntax/18_memory_management.md#borrowed) + +* 参考对象 +* [引用计数 (RC)](../syntax/18_memory_management.md#memory management) +* 引用相等 -> [副作用](../syntax/07_side_effect.md) + +### [标识符](../syntax/02_variable.md/# 赋值) + +### 签名 + +* 类型签名 + +### [dict](../syntax/11_dict.md) + +### 自然数 -> Nat + +### 泛型 -> 泛型 + +### 发电机 + +### 投影类型 + +### 借用-> [参考](../syntax/18_memory_management.md#borrowed) + +### [阴影](../syntax/02_name.md# variables) + +通过在内部范围内定义具有相同名称的变量来覆盖对变量的引用。 + +### kind -> [kind](../syntax/type/advanced/kind.md) + +大致类型的类型。 + +### set -> set + +在 Erg 中,它表示一个 Set 对象。 + +### 谓词 + +* 谓词函数 + +返回布尔类型的函数。 + +### 条件分支 + +### 所有权 + +对象唯一性的概念。 +如果您拥有对象的所有权,则可以使用 mutable 参考它。 + +### Boolean -> Bool + +### 单例 + +从只能创建一个实例的类创建的实例。一种设计模式,可确保只创建一个类的一个实例。 + +### [Symbol] -> [Identifier](../syntax/02_name.md) + +* 符号化 + +### [脚本](../syntax/00_basic.md# 脚本) + +包含 Erg 程序的文件。 + +### 范围 + +变量管理单元。外部作用域不能引用内部作用域中存在的变量。 +当范围退出时,引用计数为 0 的对象将被释放。 + +### 扩展运算符 -> expansion assignment + +### [切片](../syntax/10_array.md#slice) + +表示数组子序列的对象,以 `x[a..b]` 的形式生成。 + +### 控制字符 + +### 整数 -> Int + +一组自然数加上负数。 + +### [设置](../syntax/12_set.md) + +### 分号 -> ; + +### [声明](../syntax/03_declaration.md) + +显式类型变量。 + +### 全名 + +* 通用类型 -> [多态类型](../syntax/type/quantified.md) + * 封闭式通用 + * 打开通用 +* 通用函数 -> 多相关函数 +* 通用量化 + +### 前缀运算符 + +运算符 `∘` 以 `∘x` 的形式应用。 + +### 相互递归 + +### 下标 -> index + +### 属性 + +* 属性子类型 + +## 塔线 + +### [代数](../syntax/02_name.md) + +* [代数类型](../syntax/type/13_algebraic.md) +* 代数数据类型 + +### [赋值](../syntax/02_variable.md/#assignment) + +### 多 + +* [多重继承](../syntax/type/07_inheritance.md/#禁止多重继承) +* 多重赋值 +* 重载 -> [不重载] + +### 多态性 + +* [多态类型](../syntax/type/quantified.md) +* 多相关系数 + +### 多态性 -> [多态性] + +### 鸭子类型 + +### [元组](../syntax/11_tuple.md) + +### 单相 + +* 单相 +* 单相型 +* 单相关系数 + +### [延迟初始化] + +### 提取分配 + +### 抽象语法树 -> [AST] + +### 中缀运算符 + +运算符 `∘` 以 `x∘y` 的形式应用。 + +### [常数](../syntax/02_name.md/#constant) + +不可变的,编译时可评估的代数。 + +* [常量类型](../syntax/type/advanced/const.md) +* [常量表达式](../syntax/type/advanced/const.md) + +### 定义 + +分配与变量对应的对象。 + +### 提供的属性 + +可作为 API 使用的属性。特别是由特征自动实现的属性。 + +### 申请 + +将参数传递给函数对象并获取评估结果。 + +### [装饰器](../syntax/29_decorator.md) + +``` python +@deco +f x = ... +``` + +语法糖,或“装饰”。大致等于`_f x = ...; f = 装饰 _f`。 `deco` 本身只是一个高阶子程序。 + +### 析构函数 + +对象被销毁时调用的方法。 + +### 程序 -> [procedure](../syntax/08_procedure.md) + +读取和写入可变状态的子程序。 +有时会说程序的执行结果可以根据调用过程的顺序而改变,但如果我们谈论交换性,这是不正确的。 +例如,作为函数子类型的运算符通常不可交换。 + +### [默认参数](../syntax/04_function.md/#default arguments default-parameters) + +通过指定形式参数的默认值,可以在调用时省略实际参数的指定的函数。 + +### 扩张 + +* 扩展运算符 +* 扩展分配 + +### [特殊格式](../syntax/../API/special.md) + +不能作为实际参数传递的对象。 + +### 匿名函数 -> [anonymous function](../syntax/20_lambda.md) + +由匿名函数运算符`->`创建的函数对象。可以在不定义名称的情况下使用。 + +### 点运算符 (`.`) -> attribute reference + +### 顶部 + +* 顶部类型 -> [结构对象] +* 顶级 -> [对象] + +### [特征](../syntax/type/03_trait.md) + +## na line + +### [理解](../syntax/27_comprehension.md) + +### ~~中缀运算符~~ -> 中缀运算符 + +### 命名空间 + +## 是一行 + +### [数组](../syntax/10_array.md) + +### [派生类型](../syntax/type/variances.md/# 用户定义的类型变体) + +### [模式(匹配)](../syntax/26_pattern_matching.md) + +### [包](../syntax/33_package_system.md) + +### hashmap -> [dict](../syntax/11_dict.md) + +### [补丁](../syntax/type/07_patch.md) + +### 公共变量-> [public variables](../syntax/19_visibility.md) + +### 参数 -> [argument](../syntax/04_function.md) + +### [参数多态](../syntax/type/overloading.md) + +### [逆变](../syntax/type/advanced/variance.md) + +### 相比 + +* 比较运算符 +* 可比类型 + +### [私有变量](../syntax/19_visibility.md) + +### 标准 + +* 标准输出 +* 标准输入 +* 标准库 + +### [副作用](../syntax/07_side_effect.md) + +代码应该/不应该读/写外部可变状态。 + +### 复数 -> 复数 + +### 浮动 -> 浮动 + +### 私有变量 -> 私有变量 + +### 布尔代数-> Bool + +### [程序](../syntax/08_procedure.md) + +### [参数](../syntax/04_function.md) + +### 部分类型 -> Subtyping + +### [不可变] + +在 Erg 中,一个对象永远不应该改变它的内容。 + +* [不可变对象] +* [不可变类型] +* [不可变引用] + +### [筛子类型](../syntax/type/12_refinement.md) + +### [堵塞] + +### 解构赋值 + +### [变量](../syntax/02_variable.md) + +### 底部 + +* 底部类型 -> [{}] +* 底层 -> [从不] + +### [多态性] + +## ma line + +### ~~ 前缀运算符 ~~ -> 前缀运算符 + +### [标记类型](../syntax/type/advanced/marker_trait.md) + +### [匿名函数](../syntax/21_lambda.md) + +### 可变 -> [可变] + +### [移动] + +### 方法 + +### 元字符 + +### [模块](../syntax/24_module.md) + +### [字符串] -> [字符串] + +* [字符串插值](../syntax/01_literal.md/#Str 字面量) + +### 返回值 + +## 或行 + +### [幻像类型](../syntax/type/advanced/phantom.md) + +### 请求属性 + +### [元素] + +### [称呼] + +## 拉线 + +### [图书馆] + +### lambda 表达式 -> [匿名函数](../syntax/20_lambda.md) + +### 排名 + +* [rank2 多态性](../syntax/type/advanced/rank2type.md) + +### [文字](../syntax/01_literal.md) + +* [文字标识符](../syntax/18_naming_rule.md/#literal identifier) + +### [量化](../syntax/type/quantified.md) + +### [布局](../syntax/type/mut.md) + +### [枚举](../syntax/type/10_enum.md) + +### [记录](../syntax/12_record.md) + +* [记录类型] +* 记录多态 -> Column Polymorphism + +### 列多态 + +### [局部变量](../syntax/19_visibility.md) + +## 线 + +### 通配符 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/unify_terms.md b/doc/zh_TW/dev_guide/unify_terms.md new file mode 100644 index 00000000..2c8e49f5 --- /dev/null +++ b/doc/zh_TW/dev_guide/unify_terms.md @@ -0,0 +1,56 @@ +# 术语统一 + +## 可访问性,可见性 + +使用可见性。 + +## 类型绑定,类型约束 + +给定量化和细化类型的谓词表达式列表。使用类型边界。 + +## 子程序、例程、子程序 + +使用子程序。 + +## 引用透明/不透明,有/没有副作用 + +使用有/无副作用。 + +## 标识符、代数、变量、名称、符号 + +就其本义而言, + +* 符号:在源代码中实心编写的字符(符号、控制字符等除外),不是字符串对象(未包含在“”中)。符号在 Ruby、Lisp 等中作为原始类型存在,但在 Erg 中它们不被视为对象。 +* 标识符:(并且可以)引用某个对象的符号,而不是保留字。例如,在 Python 中 class 和 def 不能用作标识符。由于 Erg 没有保留字,所以除了某些符号外,所有符号都可以用作标识符。 +* 名称:与标识符的含义几乎相同。它有时与 Erg 中的代数同义使用。 +* 代数名称:相当于尔格中的标识符。在 C 中,函数名称是标识符,而不是代数名称。 “代数”指的是语言特性本身,它允许您使用 `=`(变量赋值运算符)或 `=`(常量赋值运算符)来分配对象。 + +```python +代数名称<:(名称==标识符)​​<:符号 +变量 + 常数 == 代数 +``` + +然而,应该称为“代数”的东西,往往被称为“变量”。这就是数学术语的效果。 +值内容可以改变的变量是可变变量,值内容不改变的变量是不可变变量。 +请注意,常量始终是不可变的。 + +Erg 中不使用代数名称和名称,使用统一标识符。 +但是,一般来说,具有 `v = 1` 的 `v` 称为“变量 v”,而具有 `C = 1` 的 `C` 称为“常量 C”。 . + +## 属性、字段、属性 + +使用属性。顺便说一句,记录是一个函数,它可以定义一个没有类的具有元素属性的对象。 + +## 应用程序,调用 + +为子例程对象提供参数并获得结果。 +使用呼叫。这是因为Application有“应用软件”的用法。 + +## 数组列表 + +使用数组。 Erg 数组(通常)在内存中是连续的。 +List 是指所谓的链表,或者说列表作为 Python 数据类型。 + +## lambda 函数、lambda 表达式、匿名函数 + +与匿名函数统一。在英文中,可以使用 Lambda 来缩短字符数,但正式名称是 Anonymous function。 \ No newline at end of file diff --git a/doc/zh_TW/faq_general.md b/doc/zh_TW/faq_general.md new file mode 100644 index 00000000..c5ab4ee3 --- /dev/null +++ b/doc/zh_TW/faq_general.md @@ -0,0 +1,37 @@ +# 尔格常见问题 + +此常见问题解答适用于一般 Erg 初学者。 +对于个别(常见)技术问题,请参阅 [此处](./faq_technical.md) 了解个别(常见)技术问题,以及 +[这里](./dev_guide/faq_syntax.md) 了解更多信息。 + +## Erg 是 Python 兼容语言是什么意思? + +~~A:Erg的可执行系统EVM(Erg VirtualMachine)执行Erg字节码,是Python字节码的扩展。它在 Python 字节码中引入了静态类型系统和其他特性(例如向不带参数的指令引入参数,以及在自由编号中实现唯一指令)。这让 Erg 可以无缝调用 Python 代码并快速执行。~~ + +A: Erg 代码被转译成 Python 字节码。也就是说,它运行在与 Python 相同的解释器上。最初,我们计划开发一个兼容 Cpython 的解释器,并将其与编译器结合起来形成“Erg”。但是,由于处理系统的发展远远落后于编译器,我们决定提前只发布编译器(但解释器仍在开发中)。 + +## 哪些语言影响了尔格? + +我们受到的语言多于我们双手所能指望的数量,但 Python、Rust、Nim 和 Haskell 的影响最大。 +我们从 Python 继承了许多语义,从 Rust 继承了面向表达式和 trait,从 Nim 继承了过程,从 Haskell 继承了函数式编程相关的特性。 + +## 可以调用 Python 的语言包括 Julia。你为什么创建 Erg? + +答:Erg 设计的动机之一是拥有一种易于使用且具有强大类型系统的语言。即具有类型推断、种类、依赖类型等的语言。 +Julia 是可以有类型的,但它确实是一种动态类型语言,不具备静态类型语言的编译时错误检测优势。 + +## Erg 支持多种编程风格,包括函数式和面向对象的编程。这不是与 Python 的“应该有一种——最好只有一种——明显的方法”相反吗? + +答:在 Erg 中,该术语是在更狭窄的上下文中使用的。例如,Erg API 中一般没有别名;在这种情况下,尔格是“唯一一种方式”。 +在更大的上下文中,例如 FP 或 OOP,只有一种做事方式并不一定很方便。 +例如,JavaScript 有几个库可以帮助创建不可变的程序,而 C 有几个用于垃圾收集的库。 +然而,即使是这样的基本功能也有多个库不仅需要时间来选择,而且在集成使用不同库的代码时也会产生很大的困难。 +即使在纯函数式语言 Haskell 中,也有支持 OOP 的库。 +如果程序员没有一些东西,他们会自己创造它们。因此,我们认为将它们作为标准提供会更好。 +这也符合 Python 的“含电池”概念。 + +## Erg 这个名字的由来是什么? + +它以cgs单位系统中的能量单位erg命名。它具有双重含义:一种为程序员提供能量的符合人体工程学的语言。 + +还有其他几个候选者,但之所以选择它是因为它最短(根据 Ruby 的开发者 Matz 的说法,语言名称越短越好)并且具有相当高的可搜索性。 \ No newline at end of file diff --git a/doc/zh_TW/faq_technical.md b/doc/zh_TW/faq_technical.md new file mode 100644 index 00000000..5c73524e --- /dev/null +++ b/doc/zh_TW/faq_technical.md @@ -0,0 +1,34 @@ +# 技术常见问题 + + +本节回答有关使用 Erg 语言的技术问题。换句话说,它包含以 What 或 Which 开头的问题,以及可以用 Yes/No 回答的问题。 + +有关如何确定语法的更多信息,请参阅 [此处](./dev_guide/faq_syntax.md) 了解基础语法决策,以及 [此处](./dev_guide/../faq_general.md)。 + +## Erg 中有异常机制吗? + +答:不会。Erg 使用 `Result` 类型代替。请参阅 [此处](./dev_guide/faq_syntax.md) 了解 Erg 没有异常机制的原因。 + +## Erg 是否有与 TypeScript 的 `Any` 等价的类型? + +答:不,没有。所有对象都至少属于 `Object` 类,但是这种类型只提供了一组最小的属性,所以你不能像使用 Any 那样对它做任何你想做的事情。 +`Object` 类通过`match` 等动态检查转换为所需的类型。它与Java 和其他语言中的`Object` 是同一种。 +在 Erg 世界中,没有像 TypeScript 那样的混乱和绝望,其中 API 定义是“Any”。 + +## Never、{}、None、()、NotImplemented 和 Ellipsis 有什么区别? + +A:`Never` 是一种“不可能”的类型。产生运行时错误的子例程将“Never”(或“Never”的合并类型)作为其返回类型。该程序将在检测到这一点后立即停止。尽管 `Never` 类型在定义上也是所有类型的子类,但 `Never` 类型的对象永远不会出现在 Erg 代码中,也永远不会被创建。 `{}` 等价于 `Never`。 +`Ellipsis` 是一个表示省略号的对象,来自 Python。 +`NotImplemented` 也来自 Python。它被用作未实现的标记,但 Erg 更喜欢产生错误的 `todo` 函数。 +`None` 是 `NoneType` 的一个实例。它通常与 `Option` 类型一起使用。 +`()` 是一个单元类型和它自己的一个实例。当您想要返回“无意义的值”(例如过程的返回值)时使用它。 + +## 为什么 `x = p!()` 有效但 `f() = p!()` 会导致 EffectError? + +`!` 不是副作用产品的标记,而是可能导致副作用的对象。 +过程 `p!` 和可变类型 `T!` 会引起副作用,但如果 `p!()` 的返回值是 `Int` 类型,它本身就不再引起副作用。 + +## 当我尝试使用 Python API 时,对于在 Python 中有效的代码,我在 Erg 中收到类型错误。这是什么意思? + +A:Erg API 的类型尽可能接近 Python API 规范,但有些情况无法完全表达。 +此外,根据规范有效但被认为不合需要的输入(例如,在应该输入 int 时输入浮点数)可能会被 Erg 开发团队酌情视为类型错误。 \ No newline at end of file diff --git a/doc/zh_TW/improved_points.md b/doc/zh_TW/improved_points.md new file mode 100644 index 00000000..b137aad2 --- /dev/null +++ b/doc/zh_TW/improved_points.md @@ -0,0 +1,48 @@ +# Python 的改进 + +## 执行静态分析(静态类型检查、变量和属性检查) + +静态类型检查的好处现在怎么强调都不为过,但是检查变量和属性的存在也是相当重要的一部分。 + +## 严格范围处理 + +在 Python 中,语句没有范围。 +因此,在 `for` 或 `if` 中定义的变量具有外部影响。 不能随便命名变量。 + +```python +for i in range(10): + x = 1 + print(i + x) +print(x) # 1 +``` + +在 Erg 中,所有块都有范围并且是完全隔离的。 + +## 明确区分可变对象和不可变对象 + +Python并不清楚可变和不可变/堆和值对象之间的区别,因此您必须记住元组是不可变的但列表是可变的......您需要记住元组是不可变的,但列表是可变的 ... 等等。 +另外,如果你想让你自己的类不可变,你必须经历一个乏味的过程。 + +```python +# 你能相信这段代码对过去的 Python 版本有效吗? +i = 256 +assert i is 256 +i = 257 +assert i is not 257 +``` + +## Traits + +就像 Java 的接口一样,你可以进行基于契约的编程。 + +Python 也有 ABC(抽象基类),但这种结构最适合静态类型。 + +## 静态解决依赖关系 + +这可以防止长时间运行程序然后由于缺少模块而出现错误的烦人体验。 + +## 内置包管理器 + +具有标准化目录结构和构建文件的可重现构建。 +当然提供了锁定文件生成和版本控制。 +无需为每个项目选择或混合anaconda、pyenv、诗歌等。 diff --git a/doc/zh_TW/index.md b/doc/zh_TW/index.md new file mode 100644 index 00000000..e35146b5 --- /dev/null +++ b/doc/zh_TW/index.md @@ -0,0 +1,25 @@ +# 索引 + +## [API/](./API/index.md) + + 本节介绍 Erg 的内置或标准库提供的子程序、类型、常量等的规范。 + +## [compiler/](./compiler/index.md) + + 描述 Erg 编译器的设计(厘米) + +## [dev_guide/](./dev_guide/index.md) + + 它解释了项目的发展政策,如何做出贡献等。 + +## [python/](./python/index.md) + + 解释了开发 Erg 所需的 Python 知识。 + +## [syntax/](./syntax/00_basic.md) + + Erg 的语法进行了解释。 + +## [tools/](./tools/index.md) + + 解释如何使用 Erg 的外围工具和命令选项。 \ No newline at end of file diff --git a/doc/zh_TW/migration_from_py.md b/doc/zh_TW/migration_from_py.md new file mode 100644 index 00000000..abb19725 --- /dev/null +++ b/doc/zh_TW/migration_from_py.md @@ -0,0 +1,25 @@ +# 从 Python 迁移到 Erg 的提示 + +## 我想将字符串转换为 int 等。 + +使用 `Str` 类的 `parse` 方法。 它返回一个 `Result` 类型。 + +```python +s: str +i: int = int(s) +``` + +```python +s: Str +res: Result(Int, IntParseError) = s. parse Int +i: Int = res.unwrap() +f: Result(Float, FloatParseError) = s. parse Float +``` + +您还可以使用 `try_from` 方法。 + +```python +s: Str +i: Int = Int.try_from(s).unwrap() +f: Float = Float.try_from(s).unwrap() +``` \ No newline at end of file diff --git a/doc/zh_TW/python/bytecode_instructions.md b/doc/zh_TW/python/bytecode_instructions.md new file mode 100644 index 00000000..c93ec1eb --- /dev/null +++ b/doc/zh_TW/python/bytecode_instructions.md @@ -0,0 +1,116 @@ +# Python 字节码指令 + +Python 字节码变量操作命令通过 名称索引(名称索引)访问。 这是为了在 Python 中实现动态变量访问(可以使用 eval 等作为字符串访问)。 +一条指令为 2 个字节,指令和参数以 little endian 形式存储。 +不带参数的指令也使用 2 个字节(参数部分为 0)。 + +## STORE_NAME(名称索引) + +```python +globals[namei] = stack.pop() +``` + +## LOAD_NAME(名称索引) + +```python +stack.push(globals[namei]) +``` + +Only called at top level. + +## LOAD_GLOBAL(名称索引) + +```python +stack.push(globals[namei]) +``` + +用于加载内部作用域顶层的STORE_NAME,但顶层的`名称索引`不一定与某个作用域的代码对象中的名称索引相同(名称相同,名称索引不一定) + +## LOAD_CONST(名称索引) + +```python +stack.push(consts[namei]) +``` + +在常量表中加载常量。 +目前(Python 3.9),在 CPython 中,每个 lambda 函数都是 MAKE_FUNCTION,名称为“\” + +```console +>>> dis.dis("[1,2,3].map(lambda x: x+1)") +1 0 LOAD_CONST 0 (1) + 2 LOAD_CONST 1 (2) + 4 LOAD_CONST 2 (3) + 6 BUILD_LIST 3 + 8 LOAD_ATTR 0 (map) + 10 LOAD_CONST 3 ( at 0x7f272897fc90, file "", line 1>) + 12 LOAD_CONST 4 ('') + 14 MAKE_FUNCTION 0 + 16 CALL_FUNCTION 1 + 18 RETURN_VALUE +``` + +## STORE_FAST(名称索引) + +fastlocals[namei] = stack.pop() +可能对应于顶层的 STORE_NAME +假定未引用(或单个)变量由此存储 +全局空间有自己的指令是为了优化吗? + +## LOAD_FAST(名称索引) + +```python +stack.push(fastlocals[namei]) +``` +fastlocals 是变量名吗? + +## LOAD_CLOSURE(名称索引) + +```python +cell = freevars[namei] +stack. push(cell) +``` + +然后调用 BUILD_TUPLE +它只在闭包内被调用,并且 cellvars 应该在闭包内存储引用。 +与 LOAD_DEREF 不同,每个单元格(填充有引用的容器)都被推入堆栈 + +## STORE_DEREF(名称索引) + +```python +cell = freevars[namei] +cell.set(stack.pop()) +``` + +在内部范围内没有引用的变量是 STORE_FAST,但引用的变量是 STORE_DEREF +在 Python 中,引用计数在该指令内递增和递减 + +## LOAD_DEREF(名称索引) + +```python +cell = freevars[namei] +stack.push(cell.get()) +``` + +## 名称列表 + +### 变量名 + +fast_locals 对应的函数内部变量名称列表 +即使名称中有同名的变量,它们也基本不一样(新创建的和外部变量不能从那个范围访问) +即没有在范围内定义的外部引用的变量进入 varnames + +### 名字 + +与全局兼容 +范围内使用的外部常量(仅引用)的名称列表(在顶层,即使是普通变量也包含在名称中) +即在范围之外定义的常量进入名称 + +## 自由变量 + +与免费变量兼容 +闭包捕获的变量。它在同一个函数实例中静态地运行。 + +## 单元格变量 + +对应于 cellvars +在函数内捕获到内部闭包函数的变量。 由于制作了副本,因此原始变量保持原样。 \ No newline at end of file diff --git a/doc/zh_TW/python/bytecode_specification.md b/doc/zh_TW/python/bytecode_specification.md new file mode 100644 index 00000000..86fd9c27 --- /dev/null +++ b/doc/zh_TW/python/bytecode_specification.md @@ -0,0 +1,144 @@ +# 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 + +* If I use a character other than ascii, does it become PyUnicode? +* "あ", "𠮷", and "α" are PyUnicode (no longer used?) + +* 0 byte: 0x73 (means 's') +* 1~4 byte: length of string +* 5~ byte: payload + +## PyUnicodeObject + +* 0 byte: 0x75 (means 'u') +* 1~4 byte: length of string +* 5~ byte: payload + +## PyShortAsciiObject + +* This is called short, but even if there are more than 100 characters, this will still short +* or rather, there is no ascii that is not short (is short a data type?) + +* 0 byte: 0xFA (means 'z') +* 1~4 byte: length of string +* 5~ byte: payload + +## PyInternedObject + +* interned objects are registered in a dedicated map and can be compared with is +* String, for example, can be compared in constant time regardless of its length + +* 0 byte: 0x74 (means 't') + +## PyShortAsciiInternedObject + +* 0 byte: 0xDA (means 'Z') +* 1~4 byte: length of string +* 5~ byte: payload + + +# Python 字节码规范 + +## 格式 + +* 0~3 byte(u32):幻数(详见common/bytecode.rs) +* 4~7 byte(u32): 0 padding +* 8~12 byte(u32): 时间戳 +* 13~ byte(PyCodeObject): 代码对象 + +## PyCode 对象 + +* 0 byte(u8): '0xe3' (前缀,这意味着代码的'c') +* 01~04 byte(u32): args个数(co_argcount) +* 05~08 byte(u32): position-only args 的数量 (co_posonlyargcount) +* 09~12 byte(u32):仅关键字参数的数量(co_kwonlyargcount) +* 13~16 byte(u32): 本地数 (co_nlocals) +* 17~20 byte(u32): 栈大小(co_stacksize) +* 21~24 byte(u32):标志(co_flags)() +* ? byte:字节码指令,以'0x53'、'0x0'结尾(83, 0):RETURN_VALUE(co_code) +* ? byte(PyTuple):代码中使用的常量(co_consts) +* ? byte(PyTuple):代码中使用的名称(co_names) +* ? byte(PyTuple):代码中定义的变量名,包括params (PyTuple) (co_varnames) +* ? byte(PyTuple):从外部范围捕获的变量(co_freevars) +* ? byte(PyTuple):内部闭包中使用的变量(co_cellvars) +* ? byte(PyUnicode 或 PyShortAscii):文件名,它是从哪里加载的(co_filename) +* ? byte(PyUnicode or PyShortAscii): 代码本身的名字,默认是\ (co_name) +* ?~?+3 byte(u32): 第一行数 (co_firstlineno) +* ? byte(bytes):行表,用 PyStringObject? (co_lnotab) + +## PyTupleObject + +* 0 byte: 0x29 (意思是:')') +* 01~04 byte(u32): 元组项数 +* ? byte(PyObject):项目 + +## PyString 对象 + +* 如果我使用 ascii 以外的字符,它会变成 PyUnicode 吗? +* “あ”、“𠮷”和“α”是 PyUnicode(不再使用?) + +* 0 byte:0x73(表示's') +* 1~4 byte:字符串长度 +* 5~ byte:有效载荷 + +## PyUnicode 对象 + +* 0 byte:0x75(表示“u”) +* 1~4 byte:字符串长度 +* 5~ byte:有效载荷 + +## PyShortAsciiObject + +* 这叫短,但是即使超过100个字符,仍然会保持在短的状态 +* 或者更确切地说,没有不短的 ascii(短数据类型吗?) + +* 0 byte:0xFA(表示“z”) +* 1~4 byte:字符串长度 +* 5~ byte:有效载荷 + +## PyInternedObject + +* 实习对象注册在专用地图中,可以与is进行比较 +* 例如字符串,无论其长度如何,都可以在恒定时间内进行比较 + +* 0 byte:0x74(表示't') + +## PyShortAsciiInternedObject + +* 0 byte:0xDA(表示“Z”) +* 1~4 byte:字符串长度 +* 5~ byte:有效载荷 \ No newline at end of file diff --git a/doc/zh_TW/python/class_system.md b/doc/zh_TW/python/class_system.md new file mode 100644 index 00000000..6623395d --- /dev/null +++ b/doc/zh_TW/python/class_system.md @@ -0,0 +1,94 @@ +# 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 ", line 3, in g +类型错误:只能将str(不是“int”)连接到str +``` + +Erg 静态检查与父类的一致性。 +重写时必须给出“Override”装饰器,并且重写函数的类型必须是被重写函数类型的子类型。 + +```python +>>> C = Class() +... .f self = 1 +... .g self = self.f() + 1 +... +>>> D = Inherit C +... .f self = "a" +... +错误[#XX]:文件“”,第 5 行,在 D 中 +要覆盖 f,必须添加 `Override` 装饰器,其类型必须是 `Self.() -> Nat` 或其子类型 +f(self) 已在 C 中定义。要覆盖 f,必须添加 `Override` 装饰器,其类型必须为 `Self. 要覆盖,必须给它一个 `Override` 装饰器,并且它的类型必须是 `Self.() -> Nat` 或 that.f(self) 的子类型。 +``` + +## 类型检查 + +类型检查通常都是关于检查函数参数的类型。 +在 Python 中,大多数操作都是方法调用。 如果对象所属的类在调用时没有附加方法,就是这样。 + +```python +def f(x): + return x.m() + +class C: + def m(self): return None + +c = C() +f(c) +f(1) # 类型错误 +``` + +```python +# f: |T, X <: {.m = Self.() -> T}| X -> T +f(x) = x.m() + +C = Class() +C.m(self) = None + +c = C.new() +f(c) +f(1) # 类型错误:f 将具有方法 `.m` 的类型作为参数,但传递了 Nat +``` diff --git a/doc/zh_TW/python/index.md b/doc/zh_TW/python/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/syntax/00_basic.md b/doc/zh_TW/syntax/00_basic.md new file mode 100644 index 00000000..b640f7fc --- /dev/null +++ b/doc/zh_TW/syntax/00_basic.md @@ -0,0 +1,148 @@ +# 基本 + +> __Warning__:本文档不完整。 它未经校对(样式、正确链接、误译等)。 此外,Erg 的语法可能在版本 0.* 期间发生破坏性更改,并且文档可能没有相应更新。 请事先了解这一点。 +> 如果您在本文档中发现任何错误,请报告至 [此处的表单](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我们将不胜感激您的建议。 +> +> [Erg原版(日文)](http://mtshiba.me/TheErgBook/) + +本文档描述 Erg 的基本语法。 [标准 API](./API/index.md) 和 [Erg 贡献者的内部文档](./dev_guide/index.md) 位于另一个目录中。 + +## 你好,世界! + +首先,让我们做“Hello World”。 + +```python +print!("Hello, World!") +``` + +这与 Python 和同一家族中的其他语言几乎相同。 最显着的特征是`!`,后面会解释它的含义。 +在 Erg 中,括号 `()` 可以省略,除非在解释上有一些混淆。 +括号的省略与 Ruby 类似,但不能省略可以以多种方式解释的括号。 + +```python +print! "Hello, World!" # OK +print! "Hello,", "World!" # OK +print!() # OK +print! # OK, 但这并不意味着调用,只是将 `print!` 作为可调用对象 + +print! f x # OK, 解释为 `print!(f(x))` +print!(f(x, y)) # OK +print! f(x, y) # OK +print! f(x, g y) # OK +print! f x, y # NG, 可以理解为 `print!(f(x), y)` 或 `print!(f(x, y))` print! +print!(f x, y) # NG, 可以表示“print!(f(x),y)”或“print!(f(x,y))” +print! f(x, g y, z) # NG, 可以表示“print!(x,g(y),z)”或“print!(x,g(y,z))” +``` + +## 脚本 + +Erg 代码称为脚本。 脚本可以以文件格式 (.er) 保存和执行。 + +## REPL/文件执行 + +要启动 REPL,只需键入: + +```sh +> erg +``` + +`>` mark is a prompt, just type `erg`. +Then the REPL should start. + +```sh +> erg +Starting the REPL server... +Connecting to the REPL server... +Erg interpreter 0.2.4 (tags/?:, 2022/08/17 0:55:12.95) on x86_64/windows +>>> +``` + +Or you can compile from a file. + +```sh +> 'print! "hello, world!"' >> hello.er + +> erg hello.er +hello, world! +``` + +## 注释 + +`#` 之后的代码作为注释被忽略。 使用它来解释代码的意图或暂时禁用代码。 + +```python +# Comment +# `#` and after are ignored until a new line is inserted +#[ +Multi-line comment +Treated as a comment all the way up to the corresponding `]#` +]# +``` + +## 表达式,分隔符 + +脚本是一系列表达式。 表达式是可以计算或评估的东西,在 Erg 中几乎所有东西都是表达式。 +每个表达式由分隔符分隔 - 新行或分号 `;`-。 +Erg 脚本基本上是从左到右、从上到下进行评估的。 + +```python +n = 1 # 赋值表达式 +f(1, 2) # 函数调用表达式 +1 + 1 # 运算符调用表达式 +f(1, 2); 1 + 1 +``` + +如下所示,有一种称为 Instant block 的语法,它将块中评估的最后一个表达式作为变量的值。 +这与没有参数的函数不同,它不添加 `()`。 请注意,即时块仅在运行中评估一次 + +```python +i = + x = 1 + x + 1 +assert i == 2 +``` + +这不能用分号 (`;`) 完成。 + +```python +i = (x = 1; x + 1) # 语法错误:不能在括号中使用 `;` +``` + +## 缩进 + +Erg 和 Python 一样,使用缩进来表示块。 有五个运算符(特殊形式)触发块的开始:`=`、`->`、`=>`、`do` 和 `do!`(此外,`:` 和 `|` ,虽然不是运算符,但也会产生缩进)。 每个的含义将在后面描述。 + +```python +f x, y = + x + y + +for! 0..9, i => + print! + +for! 0..9, i => + print! i; print! i + +ans = match x: + 0 -> "zero" + _: 0..9 -> "1 dight" + _: 10..99 -> "2 dights" + _ -> "unknown" +``` + +如果一行太长,可以使用 `\` 将其断开 + +```python +# 这不是表示 `x + y + z` 而是表示 `x; +y; +z` +X ++ y ++ z + +# 这意味着`x + y + z` +x \ ++ y \ ++ z +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/01_literal.md b/doc/zh_TW/syntax/01_literal.md new file mode 100644 index 00000000..a285d8d3 --- /dev/null +++ b/doc/zh_TW/syntax/01_literal.md @@ -0,0 +1,150 @@ +# 字面量 + +## 基本字面量 + +### 整数字面量 + +```python +0, -0, 1, -1, 2, -2, 3, -3, ... +``` + +### 比率文字 + +```python +0.00, -0.0, 0.1, 400.104, ... +``` + +如果“比率”文字的整数或小数部分为`0`,则可以省略`0` + +```python +assert 1.0 == 1. +assert 0.5 == .5 +``` + +> __注意__:这个函数 `assert` 用于表明 `1.0` 和 `1.` 相等。 +后续文档可能会使用 `assert` 来表示结果是相等的。 + +### 字符串字面量 + +可以使用任何 Unicode 可表示的字符串。 +与 Python 不同,引号不能包含在 `'` 中。 如果要在字符串中使用 `"`,请使用 `\"`。 + +```python +"", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "السَّلَامُ عَلَيْكُمْ", ... +``` + +`{}` 允许您在字符串中嵌入表达式。 这称为字符串插值。 +如果要输出 `{`、`}` 本身,请使用 `\{`、`\}`。 + +```python +assert "1 + 1 is 2" == "{1} + {1} is {1+1}" +s = "1+1" +assert "\{1+1}\" == "\{{s}\}" +``` + +### 指数字面量 + +这是学术计算中常用的表示指数符号的文字。 它是“比率”类型的一个实例。 +该符号与 Python 中的符号相同。 + +```python +1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ... +``` + +```python +assert 1e-10 == 0.0000000001 +``` + +## 复合字面量 + +这些文字中的每一个都有自己的文档分别描述它们,因此请参阅该文档以获取详细信息。 + +### [数组字面量](./10_array.md) + +```python +[], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ... +``` + +### [字典字面量](./11_dict.md) + +```python +{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ... +``` + +### [元组字面量](./12_tuple.md) + +```python +(), (1, 2, 3), (1, "hello", True), ... +``` + +### [Record 字面量](./13_record.md) + +```python +{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ... +``` + +### [Set 字面量](./14_set.md) + +```python +{}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ... +``` + +与 `Array` 字面量不同的是,`Set` 中删除了重复元素 + +```python +assert {1, 2, 1} == {1, 2} +``` + +### 看起来像文字但不是 + +## 布尔对象 + +```python +True, False +``` + +### None 对象 + +```python +None +``` + +## Range 对象 + +```python +assert 0..5 == {1, 2, 3, 4, 5} +assert 0..10 in 5 +assert 0..<10 notin 10 +assert 0..9 == 0..<10 +``` + +## Float 对象 + +```python +assert 0.0f64 == 0 +assert 0.0f32 == 0.0f64 +``` + +浮点对象是通过将 `Ratio` 对象乘以 `f64` 构造的,后者是 `Float 64` 单位对象 + +## Complex 对象 + +```python +1+2im, 0.4-1.2im, 0im, im +``` + +一个“复杂”对象只是一个虚数单位对象`im`的算术组合 + + +## *-less 乘法 + +在 Erg 中,您可以省略 `*` 来表示乘法,只要解释上没有混淆即可。 但是,运算符的组合强度设置为强于 `*`。 + +```python +# same as `assert (1*m) / (1*s) == 1*(m/s)` +assert 1m / 1s == 1 (m/s) +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/02_name.md b/doc/zh_TW/syntax/02_name.md new file mode 100644 index 00000000..cbb0ef36 --- /dev/null +++ b/doc/zh_TW/syntax/02_name.md @@ -0,0 +1,164 @@ +# 多变的 + +变量是一种代数; Erg 中的代数 - 如果没有混淆,有时简称为变量 - 指的是命名对象并使它们可从代码的其他地方引用的功能。 + +变量定义如下。 +`n` 部分称为变量名(或标识符),`=` 是赋值运算符,`1` 部分是赋值。 + +```python +n = 1 +``` + +以这种方式定义的“n”此后可以用作表示整数对象“1”的变量。 该系统称为分配(或绑定)。 +我们刚刚说过`1`是一个对象。 稍后我们将讨论对象是什么,但现在我们假设它是可以赋值的,即在赋值运算符的右侧(`=` 等)。 + +如果要指定变量的“类型”,请执行以下操作。 类型大致是一个对象所属的集合,后面会解释。 +这里我们指定`n`是自然数(`Nat`)类型。 + +```python +n: Nat = 1 +``` + +请注意,与其他语言不同,不允许多次分配 + +```python +# NG +l1 = l2 = [1, 2, 3] # 语法错误:不允许多重赋值 +# OK +l1 = [1, 2, 3] +l2 = l1.clone() +``` + +也不能重新分配给变量。 稍后将描述可用于保存可变状态的语法 + +```python +i = 1 +i = i + 1 # 分配错误:不能分配两次 +``` + +您可以在内部范围内定义具有相同名称的变量,但您只是覆盖它,而不是破坏性地重写它的值。 如果您返回外部范围,该值也会返回。 +请注意,这是与 Python “语句”范围不同的行为。 +这种功能通常称为阴影。 但是,与其他语言中的阴影不同,您不能在同一范围内进行阴影。 + +```python +x = 0 +# x = 1 # 赋值错误:不能赋值两次 +if x.is_zero(), do: + x = 1 # 与同名的外部 x 不同 + assert x == 1 +assert x == 0 +``` + +乍一看,以下内容似乎可行,但仍然不可能。 这是一个设计决定,而不是技术限制。 + +```python +x = 0 +if x.is_zero(), do: + x = x + 1 # 名称错误:无法定义变量引用同名变量 + assert x == 1 +assert x == 0 +``` + +## 常量 + +常数也是一种代数。 如果标识符以大写字母开头,则将其视为常量。 它们被称为常量,因为一旦定义,它们就不会改变。 +`N` 部分称为常量名(或标识符)。 否则,它与变量相同。 + +```python +N = 0 +if True, do: + N = 1 # 赋值错误:常量不能被遮蔽 + pass() +``` + +常量在定义的范围之外是不可变的。 他们不能被遮蔽。 由于这个属性,常量可以用于模式匹配。 模式匹配在后面解释。 + +例如,常量用于数学常量、有关外部资源的信息和其他不可变值。 + +除了 [types](./type/01_type_system.md) 之外的对象标识符使用全大写(所有字母大写的样式)是常见的做法。 + +```python +PI = 3.141592653589793 +URL = "https://example.com" +CHOICES = ["a", "b", "c"] +``` + +```python +PI = 3.141592653589793 +match! x: + PI => print! "π" + other => print! "other" +``` + +当 `x` 为 `3.141592653589793` 时,上面的代码会打印 `π`。 如果 `x` 更改为任何其他数字,它会打印 `other`。 + +有些对象不能绑定为常量。 例如,可变对象。 可变对象是其状态可以改变的对象,后面会详细介绍。 +这是因为只有常量表达式才能分配给常量的规则。 常量表达式也将在后面讨论。 + +```python +X = 1 # OK +X = !1 # 类型错误:无法定义 Int! 对象作为常量 +``` + +## 删除变量 + +您可以使用 `Del` 函数删除变量。 依赖于变量的所有其他变量(即直接引用变量值的变量)也将被删除。 + +```python +x = 1 +y = 2 +Z = 3 +f a = x + a + +assert f(2) == 3 +Del x +Del y, Z + +f(2) # 名称错误:f 未定义(在第 6 行中删除) +``` + +注意 `Del` 只能删除用户自定义模块中定义的变量。 无法删除诸如“True”之类的内置常量。 + +```python +Del True # 类型错误:无法删除内置常量 +Del print! # TypeError: 无法删除内置变量 +``` + +## 附录:赋值和等价 + +请注意,当 `x = a` 时,`x == a` 不一定为真。 一个例子是`Float.NaN`。 这是 IEEE 754 定义的浮点数的正式规范。 + +```python +x = Float.NaN +assert x ! = NaN +assert x ! = x +``` + +还有其他对象首先没有定义等价关系。 + +```python +f = x -> x**2 + 2x + 1 +g = x -> (x + 1)**2 +f == g # 类型错误:无法比较函数对象 + +C = Class {i: Int} +D = Class {i: Int} +C == D # 类型错误:无法比较类对象 +``` + +严格来说,`=` 不会将右侧的值直接分配给左侧的标识符。 +在函数和类对象的情况下,执行“修改”,例如将变量名称信息赋予对象。 但是,结构类型并非如此。 + +```python +f x = x +print! f # <函数 f> +g x = x + 1 +print! g # <函数 g> + +C = Class {i: Int} +print! C # <类 C> +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/03_declaration.md b/doc/zh_TW/syntax/03_declaration.md new file mode 100644 index 00000000..458c4097 --- /dev/null +++ b/doc/zh_TW/syntax/03_declaration.md @@ -0,0 +1,47 @@ +# 宣言(Declaration) + +声明是用于指定要使用的变量类型的语法。 +可以在代码中的任何地方进行声明,但单独的声明并不引用变量。 它们必须被初始化。 +分配后,可以检查声明以确保类型与分配它的对象兼容。 + +```python +i: Int +# 可以与赋值同时声明,如 i: Int = 2 +i = 2 +i: Num +i: Nat +i: -2..2 +i: {2} +``` + +赋值后的声明类似于`assert`的类型检查,但具有在编译时检查的特点。 +在运行时通过`assert`进行类型检查可以检查“可能是Foo类型”,但是在编译时通过`:`进行类型检查是严格的:如果类型未确定为“类型Foo”,则不会通过 检查会出现错误。 + +```python +i = (-1..10).sample! +assert i in Nat # 这可能会通过 +i: Int # 这会通过 +i: Nat # 这不会通过(-1 不是 Nat 的元素) +``` + +函数可以用两种不同的方式声明。 + +```python +f: (x: Int, y: Int) -> Int +f: (Int, Int) -> Int +``` + +如果显式声明参数名称,如果在定义时名称不同,则会导致类型错误。 如果你想给参数名称任意命名,你可以用第二种方式声明它们。 在这种情况下,类型检查只会看到方法名称及其类型。 + +```python +T = Trait { + .f = (x: Int, y: Int): Int +} + +C = Class(U, Impl := T) +C.f(a: Int, b: Int): Int = ... # 类型错误:`.f` 必须是 `(x: Int, y: Int) -> Int` 的类型,而不是 `(a: Int, b: Int) -> Int` +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/04_function.md b/doc/zh_TW/syntax/04_function.md new file mode 100644 index 00000000..3dd6143c --- /dev/null +++ b/doc/zh_TW/syntax/04_function.md @@ -0,0 +1,290 @@ +# 功能 + +函数是一个块,它接受一个“参数”,对其进行处理,并将其作为“返回值”返回。 定义如下。 + +```python +add x, y = x + y +# 或者 +add(x, y) = x + y +``` + +在函数名之后指定的名称称为参数。 +相反,传递给函数的对象称为参数。 +函数 `add` 是一个以 `x` 和 `y` 作为参数并返回它们之和的函数,`x + y`。 +可以按如下方式调用(应用/调用)定义的函数。 + +```python +add 1, 2 +# or +add(1, 2) +``` + +## 冒号应用风格 + +函数像`f x, y, ...`一样被调用,但是如果单行参数太多,可以使用`:`(冒号)来应用它们。 + +```python +f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4 +``` + +```python +f some_long_name_variable_1 + some_long_name_variable_2: + some_long_name_variable_3 * some_long_name_variable_4 +``` + +```python +f: + some_long_name_variable_1 + some_long_name_variable_2 + some_long_name_variable_3 * some_long_name_variable_4 +``` + +以上三个代码的含义相同。 例如,这种风格在使用 `if` 函数时也很有用 + +```python +result = if Bool.sample!(): + do: + log "True was chosen" + 1 + do: + log "False was chosen" + 0 +``` + +在 `:` 之后,除了注释之外,不得编写任何代码,并且必须始终在新行上 + +## 关键字参数 + +如果使用大量参数定义函数,则存在以错误顺序传递参数的危险。 +在这种情况下,使用关键字参数调用函数是安全的。 + +```python +f x, y, z, w, v, u: Int = ... +``` + +上面定义的函数有很多参数,并且排列顺序混乱。 您不应该创建这样的函数,但是在使用别人编写的代码时可能会遇到这样的代码。 因此,我们使用关键字参数。 如果使用关键字参数,则值会从名称传递到正确的参数,即使它们的顺序错误。 + +```python +f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3 +``` + +请注意,紧跟在 `:` 之后的关键字参数和新行被视为冒号调用样式 + +```python +# 意思是 `f(x: y)` +f x: y + +# 意思是 `f(x, y)` +f x: + y +``` + +## 定义错误参数 + +当某些参数大部分是固定的并且您希望能够省略它们时,使用默认参数。 + +默认参数由`:=`(walrus运算符)指定。 如果未指定 `base`,则将 `math.E` 分配给 `base`。 + +```python +math_log x: Ratio, base := math.E = ... + +assert math_log(100, 10) == 2 +assert math_log(100) == math_log(100, math.E) +``` + +请注意,不指定参数和指定`None`是有区别的 + +```python +p! x := 0 = print! +p!(2) # 2 +p!() # 0 +p!(None) # None +``` + +也可以与类型规范和模式一起使用 + +```python +math_log x, base: Ratio := math.E = ... +f [x, y] := [1, 2] = ... +``` + +但是,在默认参数中,不能调用过程(稍后描述)或分配可变对象 + +```python +f x := p! 1 = ... # NG +``` + +此外,刚刚定义的参数不能用作传递给默认参数的值 + +```python +f x := 1, y := x = ... # NG +``` + +## 可变长度参数 + +输出其参数的日志(记录)的 `log` 函数可以采用任意数量的参数。 + +```蟒蛇 +记录“你好”、“世界”、“!” # 你好世界 ! +``` + +要定义这样的函数,请将 `...` 添加到参数中。 这样,函数将参数作为可变长度数组接收 + +```python +f ...x = + for x, i -> + log i + +# x == [1, 2, 3, 4, 5] +f 1, 2, 3, 4, 5 +``` + +## 具有多种模式的函数定义 + +```python +fib n: Nat = + match n: + 0 -> 0 + 1 -> 1 + n -> fib(n - 1) + fib(n - 2) +``` + +像上面这样的函数,其中 `match` 直接出现在定义下,可以重写如下 + +```python +fib 0 = 0 +fib 1 = 1 +fib(n: Nat): Nat = fib(n - 1) + fib(n - 2) +``` + +注意一个函数定义有多个模式不是所谓的重载(multiple definition); 一个函数只有一个定义。 在上面的示例中,“n”必须与“0”或“1”属于同一类型。 此外,与 `match` 一样,模式匹配是从上到下完成的。 + +如果不同类的实例混合在一起,最后一个定义必须指定函数参数的类型为`Or` + +```python +f "aa" = ... +f 1 = ... +# `f x = ... ` 无效 +f x: Int or Str = ... +``` + +此外,像 `match` 一样,它也必须是详尽的。 + +```python +fib 0 = 0 +fib 1 = 1 +# 模式错误:fib 参数的模式并不详尽 +``` + +但是,可以通过使用稍后描述的 [refinement type](./type/12_refinement.md) 显式指定类型来使其详尽无遗。 + +```python +fib: 0..1 -> 0..1 +fib 0 = 0 +fib 1 = 1 +# OK +``` + +## 递归函数 + +递归函数是在其定义中包含自身的函数。 + +作为一个简单的例子,让我们定义一个执行阶乘计算的函数`factorial`。 阶乘是“将所有小于或等于的正数相乘”的计算。 +5 的阶乘是 `5*4*3*2*1 == 120`。 + +```python +factorial 0 = 1 +factorial 1 = 1 +factorial(n: Nat): Nat = n * factorial(n - 1) +``` + +首先,从阶乘的定义来看,0和1的阶乘都是1。 +反过来,2的阶乘是`2*1 == 2`,3的阶乘是`3*2*1 == 6`,4的阶乘是`4*3*2*1 == 24 `。 +如果我们仔细观察,我们可以看到一个数 n 的阶乘是前一个数 n-1 乘以 n 的阶乘。 +将其放入代码中,我们得到 `n * factorial(n - 1)`。 +由于 `factorial` 的定义包含自身,`factorial` 是一个递归函数。 + +提醒一下,如果您不添加类型规范,则会这样推断。 + +```python +factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int +factorial 0 = 1 +factorial 1 = 1 +factorial n = n * factorial(n - 1) +``` + +但是,即使您可以推理,您也应该明确指定递归函数的类型。 在上面的例子中,像“factorial(-1)”这样的代码可以工作,但是 + +```python +factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ... +``` + +并且这种计算不会停止。 递归函数必须仔细定义值的范围,否则您可能会陷入无限循环。 +所以类型规范也有助于避免接受意外的值。 + +## 编译时函数 + +函数名以大写字母开头,表示编译时函数。 用户定义的编译时函数必须将所有参数作为常量,并且必须指定它们的类型。 +编译时函数的功能有限。 在编译时函数中只能使用常量表达式,即只有一些运算符(例如求积、比较和类型构造操作)和编译时函数。 要传递的参数也必须是常量表达式。 +作为回报,优点是计算可以在编译时完成。 + +```python +Add(X, Y: Nat): Nat = X + Y +assert Add(1, 2) == 3 + +Factorial 0 = 1 +Factorial(X: Nat): Nat = X * Factorial(X - 1) +assert Factorial(10) == 3628800 + +math = import "math" +Sin X = math.sin X # 常量错误:此函数在编译时不可计算 +``` + +编译时函数也用于多态类型定义。 + +```python +Option T: Type = T or NoneType +Option: Type -> Type +``` + +## 附录:功能对比 + +Erg 没有为函数定义 `==`。 这是因为通常没有函数的结构等价算法。 + +```python +f = x: Int -> (x + 1)**2 +g = x: Int -> x**2 + 2x + 1 + +assert f == g # 类型错误:无法比较函数 +``` + +尽管 `f` 和 `g` 总是返回相同的结果,但要做出这样的决定是极其困难的。 我们必须向编译器教授代数。 +所以 Erg 完全放弃了函数比较,并且 `(x -> x) == (x -> x)` 也会导致编译错误。 这是与 Python 不同的规范,应该注意 + +```python +# Python,奇怪的例子 +f = lambda x: x +assert f == f +assert (lambda x: x) ! = (lambda x: x) +``` + +## Appendix2: ()-completion + +```python +f x: Object = ... +# 将完成到 +f(x: Object) = ... + +f a +# 将完成到 +f(a) + +f a, b # 类型错误:f() 接受 1 个位置参数,但给出了 2 个 +f(a, b) # # 类型错误:f() 接受 1 个位置参数,但给出了 2 个 +f((a, b)) # OK +``` + +函数类型`T -> U`实际上是`(T,) -> U`的语法糖。 + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/05_builtin_funcs.md b/doc/zh_TW/syntax/05_builtin_funcs.md new file mode 100644 index 00000000..9a21013c --- /dev/null +++ b/doc/zh_TW/syntax/05_builtin_funcs.md @@ -0,0 +1,49 @@ +# 内置函数 + +## 如果 + +`if` 是一个根据条件改变处理的函数。 + +```python +result: Option Int = if! Bool.sample!(), do: + log "True was chosen" + 1 +print! result # None (or 1) +``` + +`.sample!()` 返回一组随机值。 如果返回值为真,`print! “真”`被执行。 +如果条件为假,您还可以指定要执行的操作; 第二个 do 块称为 else 块。 + +```python +result: Nat = if Bool.sample!(): + do: + log "True was chosen" + 1 + do: + log "False was chosen" + 0 +print! result # 1 (or 0) +``` + +如果进程是单行,则可以省略缩进。 + +```python +result = if Bool.sample!(): + do 1 + do 0 +``` + +## for + +你可以使用 `for` 来编写一个重复的过程。 + +```python +match_s(ss: Iterator(Str), pat: Pattern): Option Str = + for ss, s -> + if pat.match(s).is_some(): + break s +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/06_operator.md b/doc/zh_TW/syntax/06_operator.md new file mode 100644 index 00000000..a7c8955e --- /dev/null +++ b/doc/zh_TW/syntax/06_operator.md @@ -0,0 +1,29 @@ +# 运算符 + +运算符是表示操作的符号。 操作数是运算符(左)右侧的东西。 + +运算符是一种函数,因此它们本身就是可以绑定到变量的一流对象。 绑定时,需要用```括起来。 +对于`+`(和`-`),有一元和二元运算符,所以必须指定`_+_`(二元运算)/`+_`(一元运算)。 + +```python +add = `+` # 语法错误:指定 `_+_` 或 `+_` +add=`_+_` +assert f(1, 2) == 3 +assert f("a", "b") == "ab" + +g = `*` # OK, 这只是二进制 +assert g(1, 2) == 2 +``` + +一些称为特殊形式的基本运算符不能被绑定。 + +```python +def = `=` # 语法错误:无法绑定 `=` 运算符,这是一种特殊形式 +# NG: def x, 1 +function = `->` # 语法错误:无法绑定 `->` 运算符,这是一种特殊形式 +# NG: function x, x + 1 +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/07_side_effect.md b/doc/zh_TW/syntax/07_side_effect.md new file mode 100644 index 00000000..3b7d414a --- /dev/null +++ b/doc/zh_TW/syntax/07_side_effect.md @@ -0,0 +1,121 @@ +# 副作用和程序 + +我们一直忽略了解释“!”的含义,但现在它的含义终于要揭晓了。 这个 `!` 表示这个对象是一个带有“副作用”的“过程”。 过程是具有副作用的函数。 + +```python +f x = print! x # EffectError: 不能为函数分配有副作用的对象 +# 提示:将名称更改为 'f!' +``` + +上面的代码会导致编译错误。 这是因为您在函数中使用了过程。 在这种情况下,您必须将其定义为过程。 + +```python +p! x = print! x +``` + +`p!`, `q!`, ... 是过程的典型变量名。 +以这种方式定义的过程也不能在函数中使用,因此副作用是完全隔离的。 + +## 方法 + +函数和过程中的每一个都可以是方法。 函数式方法只能对`self`进行不可变引用,而程序性方法可以对`self`进行可变引用。 +`self` 是一个特殊的参数,在方法的上下文中是指调用对象本身。 引用 `self` 不能分配给任何其他变量。 + +```python +C!. + method ref self = + x = self # 所有权错误:无法移出`self` + x +``` + +程序方法也可以采取 `self` 的 [ownership](./18_ownership.md)。 从方法定义中删除 `ref` 或 `ref!` + +```python +n = 1 +s = n.into(Str) # '1' +n # 值错误:n 被 .into 移动(第 2 行) +``` + +在任何给定时间,只有一种程序方法可以具有可变引用。 此外,在获取可变引用时,不能从原始对象获取更多可变引用。 从这个意义上说,`ref!` 会对`self` 产生副作用。 + +但是请注意,可以从可变引用创建(不可变/可变)引用。 这允许在程序方法中递归和 `print!` 的`self`。 + +```python +T -> T # OK (move) +T -> Ref T # OK (move) +T => Ref! T # OK (only once) +Ref T -> T # NG +Ref T -> Ref T # OK +Ref T => Ref! +T -> Ref T # NG +T -> Ref T # OK +T => Ref! +``` + +## 附录:副作用的严格定义 + +代码是否具有副作用的规则无法立即理解。 +直到你能理解它们,我们建议你暂时把它们定义为函数,如果出现错误,添加`!`将它们视为过程。 +但是,对于那些想了解该语言的确切规范的人,以下是对副作用的更详细说明。 + +首先,必须声明返回值的等价与 Erg 中的副作用无关。 +有些过程对于任何给定的 `x` 都会导致 `p!(x) == p!(x)`(例如,总是返回 `None`),并且有些函数会导致 `f(x) ! = f(x)`。 + +前者的一个例子是`print!`,后者的一个例子是下面的函数。 + +```python +nan _ = Float.NaN +assert nan(1) ! = nan(1) +``` + +还有一些对象,例如类,等价确定本身是不可能的 + +```python +T = Structural {i = Int} +U = Structural {i = Int} +assert T == U + +C = Class {i = Int} +D = Class {i = Int} +assert C == D # 类型错误:无法比较类 +``` + +言归正传:Erg 中“副作用”的准确定义是 + +* 访问可变的外部信息。 + +“外部”一般是指外部范围; Erg 无法触及的计算机资源和执行前/执行后的信息不包含在“外部”中。 “访问”包括阅读和写作。 + +例如,考虑 `print!` 过程。 乍一看,`print!` 似乎没有重写任何变量。 但如果它是一个函数,它可以重写外部变量,例如,使用如下代码: + +```python +camera = import "some_camera_module" +ocr = import "some_ocr_module" + +n = 0 +_ = + f x = print x # 假设我们可以使用 print 作为函数 + f(3.141592) +cam = camera.new() # 摄像头面向 PC 显示器 +image = cam.shot!() +n = ocr.read_num(image) # n = 3.141592 +``` + +将“camera”模块视为为特定相机产品提供 API 的外部库,将“ocr”视为用于 OCR(光学字符识别)的库。 +直接的副作用是由 `cam.shot!()` 引起的,但显然这些信息是从 `f` 泄露的。 因此,`print!` 本质上不可能是一个函数。 + +然而,在某些情况下,您可能希望临时检查函数中的值,而不想为此目的在相关函数中添加 `!`。 在这种情况下,可以使用 `log` 函数。 +`log` 打印整个代码执行后的值。 这样,副作用就不会传播。 + +```python +log "this will be printed after execution" +print! "this will be printed immediately" +# 这将立即打印 +# 这将在执行后打印 +``` + +如果没有反馈给程序,或者换句话说,如果没有外部对象可以使用内部信息,那么信息的“泄漏”是可以允许的。 只需要不“传播”信息。 + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/08_procedure.md b/doc/zh_TW/syntax/08_procedure.md new file mode 100644 index 00000000..3ce9e05a --- /dev/null +++ b/doc/zh_TW/syntax/08_procedure.md @@ -0,0 +1,12 @@ +# 程序 + +处理可变对象时需要过程,但将可变对象作为参数并不一定使其成为过程。 +这是一个函数接受一个可变对象(不是过程)。 + +```python +peek_str s: Str! = log s +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/09_builtin_procs.md b/doc/zh_TW/syntax/09_builtin_procs.md new file mode 100644 index 00000000..f2e878c2 --- /dev/null +++ b/doc/zh_TW/syntax/09_builtin_procs.md @@ -0,0 +1,14 @@ +# 内置程序 + +## id! + +返回对象的唯一标识号。 +尽管在纯 Erg 语义中,结构相同的对象之间没有区别,但实际上对象在内存中具有不同的位置。 +`id!` 返回一个代表这个位置的数字。 + +```python +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/10_array.md b/doc/zh_TW/syntax/10_array.md new file mode 100644 index 00000000..c77cc7cd --- /dev/null +++ b/doc/zh_TW/syntax/10_array.md @@ -0,0 +1,52 @@ +# Array + +数组是最基本的__collection(聚合)__。 +集合是一个可以在其中包含多个对象的对象。 + +```python +a = [1, 2, 3] +a: [Int; 3] # 类型说明:分号后的数字为元素个数 +# 如果元素个数未知,可以省略 +a: [Int] + +mut_a = [!1, !2, !3] +mut_a[0].inc!() +assert mut_a == [2, 2, 3] +``` + +通常,数组不能包含不同类型的对象。 + +```python. +[1, "a"] # 类型错误:第一个元素是 Int,但第二个元素是 Str +``` + +但是,您可以通过像这样显式指定类型来绕过限制。 + +```python +[1, "a"]: [Int or Str]. +``` + +## 切片 + +一个数组也可以同时取出多个值。 这称为切片。 + +```python +l = [1, 2, 3, 4] +# 与 Python 中的 l[1:3] 相同 +assert l[1.. <3] == [2, 3] +assert l[1..2] == [2, 3] +# 与 l[1] 相同 +assert l[1..1] == [2] +# 与 Python 中的 l[::2] 相同 +assert l[..].step(2) == [2, 4] +``` + +通过切片获得的对象是数组的(不可变的)副本 + +```python +print! Typeof l[1..2] # [Int; 4] +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/11_tuple.md b/doc/zh_TW/syntax/11_tuple.md new file mode 100644 index 00000000..95f2502a --- /dev/null +++ b/doc/zh_TW/syntax/11_tuple.md @@ -0,0 +1,116 @@ +# 元组 + +元组类似于数组,但可以保存不同类型的对象。 +这样的集合称为不等集合。 相比之下,同构集合包括数组、集合等。 + +```python +t = (1, True, "a") +(i, b, s) = t +assert(i == 1 and b == True and s == "a") +``` + +元组`t`可以以`t.n`的形式检索第n个元素; 请注意,与 Python 不同,它不是 `t[n]`。 +这是因为访问元组元素更像是一个属性(在编译时检查元素的存在,并且类型可以根据 `n` 改变)而不是方法(数组的 `[]` 是一种方法)。 + +```python +assert t.0 == 1 +assert t.1 == True +assert t.2 == "a" +``` + +括号 `()` 在不嵌套时是可选的。 + +```python +t = 1, True, "a" +i, b, s = t +``` + +元组可以保存不同类型的对象,因此它们不能像数组一样被迭代。 + +```python +t: ({1}, {2}, {3}) = (1, 2, 3) +(1, 2, 3).iter().map(x -> x + 1) # 类型错误:类型 ({1}, {2}, {3}) 没有方法 `.iter()` +# 如果所有类型都相同,则可以像数组一样用`(T; n)`表示,但这仍然不允许迭代 +t: (Int; 3) = (1, 2, 3) +assert (Int; 3) == (Int, Int, Int) +``` + +但是,非同质集合(如元组)可以通过向上转换、相交等方式转换为同质集合(如数组)。 +这称为均衡。 + +```python +(Int, Bool, Str) can be [T; 3] where T :> Int, T :> Bool, T :> Str +``` + +```python +t: (Int, Bool, Str) = (1, True, "a") # 非同质 +a: [Int or Bool or Str; 3] = [1, True, "a"] # 同质的 +_a: [Show; 3] = [1, True, "a"] # 同质的 +_a.iter().map(x -> log x) # OK +t.try_into([Show; 3])? .iter().map(x -> log x) # OK +``` + +## 单元 + +零元素的元组称为 __unit__。 一个单元是一个值,但也指它自己的类型。 + +```python +unit = () +(): () +``` + +Unit 是所有元素 0 元组的父类。 + +```python +() > (Int; 0) +() > (Str; 0) +``` + +该对象的用途是用于没有参数和没有返回值的过程等。Erg 子例程必须有参数和返回值。 但是,在某些情况下,例如过程,可能没有有意义的参数或返回值,只有副作用。 在这种情况下,我们将单位用作“无意义的正式值” + +```python +# ↓ Actually, this parenthesis is a unit +p!() =. + # `print!` does not return a meaningful value + print! "Hello, world!" +p!: () => () +``` + +但是,在这种情况下,Python 倾向于使用“无”而不是单位。 +在 Erg 中,当您从一开始就确定操作不会返回有意义的值(例如在过程中)时,您应该使用 `()`,并且当操作可能失败并且您可能会返回 `None` 将一无所获,例如在检索元素时。 + +## 参数和元组 + +实际上,Erg 的所有 `Callable` 对象都是一个参数和一个返回值; 一个接受 N 个参数的子例程只是接收“一个具有 N 个元素的元组”作为参数。 + +```python +# f x = ... 被隐式假设为 f(x) = ... 被认为是 +f x = x +assert f(1) == 1 +f(1, 2, 3) # 参数错误:f 接受 1 个位置参数,但给出了 3 个 +g x: Int, . . y: Int = y +assert (2, 3) == g 1, 2, 3 +``` + +这也解释了函数类型。 + +```python +assert f in T: {(T,) -> T | T} +assert g in {(Int, ... (Int; N)) -> (Int; N) | N: Nat} +``` + +准确地说,函数的输入不是元组,而是“具有默认属性的命名元组”。 这是一个特殊的元组,只能在函数参数中使用,可以像记录一样命名,并且可以有默认值。 + +```python +f(x: Int, y=0) = x + y +f: (Int, y=Int) -> Int + +f(x=0, y=1) +f(y=1, x=0) +f(x=0) +f(0) +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/12_dict.md b/doc/zh_TW/syntax/12_dict.md new file mode 100644 index 00000000..08938fcd --- /dev/null +++ b/doc/zh_TW/syntax/12_dict.md @@ -0,0 +1,67 @@ +# 字典 + +Dict 是键/值对的集合。 + +```python +ids = {"Alice": 145, "Bob": 214, "Charlie": 301} +assert ids["Alice"] == 145 +``` + +如果键是“哈希”对象,则键不必是字符串。 + +```python +# 不推荐使用范围对象作为键(与切片混淆) +r = {1..3: "1~3", 4..6: "4~6", 7..9: "7~9"} +assert r[1..3] == "1~3" +l = {[]: "empty", [1]: "1"} +assert l[[]] == "empty" +``` + +对于字典来说,顺序无关紧要。 它也不能有重复的元素。 在这方面,Dict 与 Set 类似。 +您可以说 Dict 是具有值的 Set。 + +```python +{"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214} +``` + +从 dict 文字生成 dict 时,会检查重复键。 +任何重复都会导致编译错误。 + +```python +{"Alice": 145, "Alice": 1} # Key错误:重复键`Alice` +``` + +空字典是用 `{:}` 创建的。 请注意,`{}` 表示一个空集。 + +```python +mut_dict = !{:} +mut_dict.insert! "Alice", 145 +mut_dict.insert! "Bob", 214 +assert mut_dict["Alice"] == 145 +``` + +## 异构字典 + +不需要有单一的键/值类型。 这样的字典称为 __heterogenous dict_。 + +```python +d: {Str: Int, Int: Str} = {"a": 1, 1: "a"} +assert d["a"] == 1 +assert d[1] == "a" +``` + +但是,不能将相同类型的值分配给不同类型的键,或者将不同类型的值分配给相同类型的键。 +在这种情况下,请改用 Or 类型。 + +```python +invalid1 = {1: "a", "a": "b"} +invalid2 = {1: "a", 2: 2} + +# Erg 类型推断不推断 Or 类型,因此需要类型说明 +valid1: {Int or Str: Str} = {1: "a", "a": "b"} +valid2: {Int: Int or Str} = {1: "a", 2: 2} +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/13_record.md b/doc/zh_TW/syntax/13_record.md new file mode 100644 index 00000000..2990ed55 --- /dev/null +++ b/doc/zh_TW/syntax/13_record.md @@ -0,0 +1,199 @@ +# 记录(Record) + +记录是一个集合,它结合了通过键访问的 Dict 和在编译时检查其访问的元组的属性。 +如果您了解 JavaScript,请将其视为一种(更增强的)对象字面量表示法。 + +```python +john = {.name = "John"; .age = 21} + +assert john.name == "John" +assert john.age == 21 +assert john in {.name = Str; .age = Nat} +john["name"] # 错误:john 不可订阅 +``` + +`.name` 和 `.age` 部分称为属性,而 `"John"` 和 `21` 部分称为属性值。 + +与 JavaScript 对象字面量的区别在于它们不能作为字符串访问。 也就是说,属性不仅仅是字符串。 +这是因为对值的访问是在编译时确定的,而且字典和记录是不同的东西。 换句话说,`{"name": "John"}` 是一个字典,`{name = "John"}` 是一个记录。 +那么我们应该如何使用字典和记录呢? +一般来说,我们建议使用记录。 记录具有在编译时检查元素是否存在以及能够指定 __visibility_ 的优点。 +指定可见性等同于在 Java 和其他语言中指定公共/私有。 有关详细信息,请参阅 [可见性](./15_visibility.md) 了解详细信息。 + +```python +a = {x = 1; .y = x + 1} +a.x # 属性错误:x 是私有的 +# 提示:声明为 `.x`。 +assert a.y == 2 +``` + +对于熟悉 JavaScript 的人来说,上面的示例可能看起来很奇怪,但简单地声明 `x` 会使其无法从外部访问 + +您还可以显式指定属性的类型 + +```python +anonymous = { + .name: Option! Str = ! + .age = 20 +} +anonymous.name.set! "John" +``` + +一个记录也可以有方法。 + +```python +o = { + .i = !0 + .inc! ref! self = self.i.inc!() +} + +assert o.i == 0 +o.inc!() +assert o.i == 1 +``` + +关于记录有一个值得注意的语法。 当记录的所有属性值都是类(不是结构类型)时,记录本身表现为一个类型,其自身的属性作为必需属性。 +这种类型称为记录类型。 有关详细信息,请参阅 [记录] 部分。 + +```python +# 记录 +john = {.name = "John"} +# 记录 type +john: {.name = Str} +Named = {.name = Str} +john: Named + +greet! n: Named = + print! "Hello, I am {n.name}" +john # “你好,我是约翰 print! + +Named.name # Str +``` + +## 解构记录 + +记录可以按如下方式解构。 + +```python +record = {x = 1; y = 2} +{x = a; y = b} = record +assert a == 1 +assert b == 2 + +point = {x = 2; y = 3; z = 4} +match point: + {x = 0; y = 0; z = 0} -> "origin" + {x = _; y = 0; z = 0} -> "on the x axis" + {x = 0; ...} -> "x = 0" + {x = x; y = y; z = z} -> "({x}, {y}, {z})" +``` + +当存在与属性同名的变量时,`x = ...`也可以缩写为`x`,例如`x = x`或`x = .x`到`x`,和` .x = .x` 或 `.x = x` 到 `.x`。 +但是,当只有一个属性时,必须在其后加上`;`以与集合区分开来。 + +```python +x = 1 +y = 2 +xy = {x; y} +a = 1 +b = 2 +ab = {.a; .b} +assert ab.a == 1 +assert ab.b == 2 + +record = {x;} +tuple = {x} +assert tuple.1 == 1 +``` + +此语法可用于解构记录并将其分配给变量 + +```python +# 一样 `{x = x; y = y} = xy` +{x; y} = xy +assert x == 1 +assert y == 2 +# 一样 `{.a = a; .b = b} = ab` +{a; b} = ab +assert a == 1 +assert b == 2 +``` + +## 空记录 + +空记录由`{=}`表示。 空记录也是它自己的类,如 Unit + +```python +empty_record = {=} +empty_record: {=} +# Object: Type = {=} +empty_record: Object +empty_record: Structural {=} +{x = 3; y = 5}: Structural {=} +``` + +空记录不同于空 Dict `{:}` 或空集 `{}`。 特别要注意的是,它与 `{}` 的含义相反(在 Python 中,`{}` 是一个空字典,而在 Erg 中它是 Erg 中的 `!{:}`)。 +作为枚举类型,`{}` 是一个空类型,其元素中不包含任何内容。 `Never` 类型是这种类型的一个分类。 +相反,记录类 `{=}` 没有必需的实例属性,因此所有对象都是它的元素。 `Object` 是 this 的别名。 +一个`Object`(`Object`的一个补丁)是`的一个元素。 __sizeof__` 和其他非常基本的提供方法。 + +```python +AnyPatch = Patch Structural {=} + . __sizeof__ self = ... + .clone self = ... + ... +Never = Class {} +``` + +请注意,没有其他类型或类在结构上与 `{}`、`Never` 类型等效,如果用户在右侧使用 `{}`、`Class {}` 定义类型,则会出错。 +这意味着,例如,`1..10 或 -10。 -1`,但 `1..10 和 -10... -1`。 例如,当它应该是 1..10 或 -10...-1 时是 `-1`。 +此外,如果您定义的类型(例如 `Int 和 Str`)会导致组合 `Object`,则会警告您只需将其设置为 `Object`。 + +## 即时封锁 + +Erg 有另一种语法 Instant 块,它只返回最后评估的值。 不能保留属性。 + +```python +x = + x = 1 + y = x + 1 + y ** 3 +assert x == 8 + +y = + .x = 1 # 语法错误:无法在实体块中定义属性 +``` + +## 数据类 + +如果您尝试自己实现方法,则必须直接在实例中定义裸记录(由记录文字生成的记录)。 +这是低效的,并且随着属性数量的增加,错误消息等变得难以查看和使用。 + +```python +john = { + name = "John Smith" + age = !20 + .greet! ref self = print! "Hello, my name is {self::name} and I am {self::age} years old." + .inc_age! ref! self = self::age.update! x -> x + 1 +} +john + 1 +# 类型错误:{name = Str; 没有实现 + 年龄=诠释; 。迎接! =参考(自我)。 () => 无; inc_age! =参考! () => 无}, 整数 +``` + +因此,在这种情况下,您可以继承一个记录类。 这样的类称为数据类。 +这在 [class](./type/04_class.md) 中有描述。 + +```python +Person = Inherit {name = Str; age = Nat} +Person. + greet! ref self = print! "Hello, my name is {self::name} and I am {self::age} years old." + inc_age! ref! self = self::age.update! x -> x + 1 + +john = Person.new {name = "John Smith"; age = 20} +john + 1 +# 类型错误:Person、Int 没有实现 + +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/14_set.md b/doc/zh_TW/syntax/14_set.md new file mode 100644 index 00000000..e209411d --- /dev/null +++ b/doc/zh_TW/syntax/14_set.md @@ -0,0 +1,45 @@ +# Set + +一个Set代表一个集合,它在结构上是一个重复的无序数组。 + +```python +assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3} +assert {1, 2} == {1, 1, 2} # 重复的被自动删除 +assert {1, 2} == {2, 1} +``` + +Set可以执行集合操作。 + +```python +assert 1 in {1, 2, 3} +assert not 1 in {} +assert {1} or {2} == {1, 2} +assert {1, 2} and {2, 3} == {2} +assert {1, 2} not {2} == {1} +``` + +Set是同质集合。 为了使不同类的对象共存,它们必须同质化 + +```python +s: {Int or Str} = {"a", 1, "b", -1} +``` + +## Sets为类型 +Sets也可以被视为类型。 这种类型称为 _枚举类型_。 + +```python +i: {1, 2, 3} = 1 +assert i in {1, 2, 3} +``` + +Set的元素直接是类型的元素。 +请注意,这些Set本身是不同的。 + +```python +mut_set = {1, 2, 3}.into {Int; !3} +mut_set.insert!(4) +``` + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/15_type.md b/doc/zh_TW/syntax/15_type.md new file mode 100644 index 00000000..37dd77c6 --- /dev/null +++ b/doc/zh_TW/syntax/15_type.md @@ -0,0 +1,7 @@ +# 类型 + +类型是 Erg 中一个非常重要的特性,所以我们有一个 [dedicated section](./type/01_type_system.md)。 请看那里。 + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/16_iterator.md b/doc/zh_TW/syntax/16_iterator.md new file mode 100644 index 00000000..a2733c5c --- /dev/null +++ b/doc/zh_TW/syntax/16_iterator.md @@ -0,0 +1,89 @@ +# 迭代器 + +迭代器是用于检索容器元素的对象。 + +```python +for! 0..9, i => + print! i +``` + +此代码打印数字 0 到 9。 +每个数字(=Int 对象)都分配给`i`,并执行以下操作(=`print!i`)。 这种重复执行称为__iteration__。 + +现在让我们看看 `for!` 过程的类型签名。 + +```python +for!: |T: Type, I <: Iterable T| (I, T => None) => None +``` + +第一个参数似乎接受“Iterable”类型的对象。 + +`Iterable` 是一个具有`.Iterator` 属性的类型,`.iter` 方法在request 方法中。 + +```python +Iterable T = Trait { + .Iterator = {Iterator} + .iter = Self(T). () -> Self.Iterator T +} +``` + +`.Iterator` 属性的类型 `{Iterator}` 是所谓的 set-kind(kind 在 [here](./type/advanced/kind.md) 中描述) + +```python +assert [1, 2, 3] in Iterable(Int) +assert 1..3 in Iterable(Int) +assert [1, 2, 3].Iterator == ArrayIterator +assert (1..3).Iterator == RangeIterator + +log [1, 2, 3].iter() # <数组迭代器对象> +log (1..3).iter() # +``` + +`ArrayIterator` 和 `RangeIterator` 都是实现 `Iterator` 的类,它们的存在只是为了提供 `Array` 和 `Range` 迭代函数。 +这种设计模式称为伴生类 [1](#1)。 +而“IteratorImpl”补丁是迭代功能的核心。 `Iterator` 只需要一个`.next` 方法,`IteratorImpl` 确实提供了几十种方法。 `ArrayIterator`和`RangeIterator`只需实现`.next`方法就可以使用`IteratorImpl`的实现方法。 为了方便起见,标准库实现了许多迭代器。 + +```mermaid +classDiagram + class Array~T~ { + ... + iter() ArrayIterator~T~ + } + class Range~T~ { + ... + iter() RangeIterator~T~ + } + class Iterable~T~ { + <> + iter() Iterator~T~ + } + Iterable~T~ <|.. Array~T~: Impl + Iterable~T~ <|.. Range~T~: Impl + class ArrayIterator~T~ { + array: Array~T~ + next() T + } + class RangeIterator~T~ { + range: Range~T~ + next() T + } + class Iterator~T~ { + <> + next() T + } + Iterator~T~ <|.. ArrayIterator~T~: Impl + Iterator~T~ <|.. RangeIterator~T~: Impl + + Array <-- ArrayIterator + Range <-- RangeIterator +``` + +诸如 `Iterable` 之类的以静态分派但统一的方式提供用于处理特征(在本例中为 `Iterator`)的接口的类型称为伴生类适配器。 + +--- + +1 这个模式似乎没有统一的名称,但是在 Rust 中,有 [companion struct 模式]( https://gist.github.com/qnighy/be99c2ece6f3f4b1248608a04e104b38#:~:text=%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82 %8B%E3%80%82-,companion%20struct,-%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A8%E3%80% 81%E3 %81%9D%E3%81%AE),并以此命名。 [↩](#f1) + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/17_mutability.md b/doc/zh_TW/syntax/17_mutability.md new file mode 100644 index 00000000..25145f88 --- /dev/null +++ b/doc/zh_TW/syntax/17_mutability.md @@ -0,0 +1,103 @@ +# 可变性 + +正如我们已经看到的,所有 Erg 变量都是不可变的。 但是,Erg 对象具有可变性的概念。 +以下面的代码为例。 + +```python +a = [1, 2, 3] +a = a + [4, 5, 6] +print! a # [1, 2, 3, 4, 5, 6] +``` + +上面的代码实际上不能被 Erg 执行。 这是因为它不可重新分配。 + +可以执行此代码。 + +```python +b = ![1, 2, 3] +b.concat! [4, 5, 6] +print! b # [1, 2, 3, 4, 5, 6] +``` + +`a, b` 的最终结果看起来一样,但它们的含义却大不相同。 +虽然 `a` 是表示 `Nat` 数组的变量,但第一行和第二行指向的对象是不同的。 名称`a`相同,但内容不同。 + +```python +a = [1, 2, 3] +print! id! a # 0x000002A798DFE940 +_a = a + [4, 5, 6] +print! id! _a # 0x000002A798DFE980 +``` + +`id!` 过程返回对象驻留的内存地址。 + +`b` 是一个 `Nat` “动态” 数组。 对象的内容发生了变化,但变量指向的是同一个东西 + +```python +b = ![1, 2, 3] +print! id! b # 0x000002A798DFE220 +b.concat! [4, 5, 6] +print! id! b # 0x000002A798DFE220 +``` + +```python +i = !0 +if! True. do! + do! i.inc!() # or i.add!(1) + do pass +print! i # 1 +``` + +`!` 是一个特殊的运算符,称为 __mutation 运算符__。 它使不可变对象可变。 +标有“!”的对象的行为可以自定义。 + +```python +Point = Class {.x = Int; .y = Int} + +# 在这种情况下 .x 是可变的,而 .y 保持不变 +Point! = Class {.x = Int!; .y = Int} +Point!. + inc_x! ref!(self) = self.x.update! x -> x + 1 + +p = Point!.new {.x = !0; .y = 0} +p.inc_x!() +print! p.x # 1 +``` + +## 常量 + +与变量不同,常量在所有范围内都指向同一事物。 +常量使用 `=` 运算符声明。 + +```python +PI = 3.141592653589 +match! x: + PI => print! "this is pi" +``` + +常量在全局以下的所有范围内都是相同的,并且不能被覆盖。因此,它们不能被 ``=`` 重新定义。此限制允许它用于模式匹配。 +`True` 和 `False` 可以用于模式匹配的原因是因为它们是常量。 +此外,常量总是指向不可变对象。诸如 `Str!` 之类的类型不能是常量。 +所有内置类型都是常量,因为它们应该在编译时确定。可以生成非常量的类型,但不能用于指定类型,只能像简单记录一样使用。相反,类型是其内容在编译时确定的记录。 + +## 变量、名称、标识符、符号 + +让我们理清一些与 Erg 中的变量相关的术语。 + +变量是一种为对象赋予名称以便可以重用(或指向该名称)的机制。 +标识符是指定变量的语法元素。 +符号是表示名称的语法元素、记号。 + +只有非符号字符是符号,符号不称为符号,尽管它们可以作为运算符的标识符。 +例如,`x` 是一个标识符和一个符号。 `x.y` 也是一个标识符,但它不是一个符号。 `x` 和 `y` 是符号。 +即使 `x` 没有绑定到任何对象,`x` 仍然是一个符号和一个标识符,但它不会被称为变量。 +`x.y` 形式的标识符称为字段访问器。 +`x[y]` 形式的标识符称为下标访问器。 + +变量和标识符之间的区别在于,如果我们在 Erg 的语法理论意义上谈论变量,则两者实际上是相同的。 +在 C 中,类型和函数不能分配给变量; int 和 main 是标识符,而不是变量(严格来说可以赋值,但有限制)。 +然而,在尔格语中,“一切都是对象”。不仅函数和类型,甚至运算符都可以分配给变量。 + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/18_ownership.md b/doc/zh_TW/syntax/18_ownership.md new file mode 100644 index 00000000..0f473a8f --- /dev/null +++ b/doc/zh_TW/syntax/18_ownership.md @@ -0,0 +1,110 @@ +#所有权制度 + +由于 Erg 是一种使用 Python 作为宿主语言的语言,因此内存管理的方法取决于 Python 的实现。 +但语义上 Erg 的内存管理与 Python 的不同。 一个显着的区别在于所有权制度和禁止循环引用。 + +## 所有权 + +Erg 有一个受 Rust 启发的所有权系统。 +Rust 的所有权系统通常被认为是深奥的,但 Erg 的所有权系统被简化为直观。 +在 Erg 中,__mutable objects__ 是拥有的,并且在所有权丢失后无法引用。 + +```python +v = [1, 2, 3].into [Int; !3] + +push! vec, x = + vec.push!(x) + vec + +# v ([1, 2, 3])的内容归w所有 +w = push! v, 4 +print! v # 错误:v 被移动了 +print!w # [1, 2, 3, 4] +``` + +例如,当一个对象被传递给一个子程序时,就会发生所有权转移。 +如果您想在赠送后仍然拥有所有权,则需要克隆、冻结或借用。 +但是,如后所述,可以借用的情况有限。 + +## 复制 + +复制一个对象并转移其所有权。 它通过将 `.clone` 方法应用于实际参数来做到这一点。 +复制的对象与原始对象完全相同,但相互独立,不受更改影响。 + +复制相当于 Python 的深拷贝,由于它完全重新创建相同的对象,因此计算和内存成本通常高于冻结和借用。 +需要复制对象的子例程被称为“参数消耗”子例程。 + +```python +capitalize s: Str!= + s. capitalize!() + s + +s1 = !"hello" +s2 = capitalize s1.clone() +log s2, s1 # !"HELLO hello" +``` + +## 冻结 + +我们利用了不可变对象可以从多个位置引用的事实,并将可变对象转换为不可变对象。 +这称为冻结。 例如,在从可变数组创建迭代器时会使用冻结。 +由于您不能直接从可变数组创建迭代器,请将其转换为不可变数组。 +如果您不想破坏数组,请使用 [`.freeze_map` 方法](./type/mut.md)。 + +```python +# 计算迭代器产生的值的总和 +sum|T <: Add + HasUnit| i: Iterator T = ... + +x = [1, 2, 3].into [Int; !3] +x.push!(4) +i = x.iter() # 类型错误:[Int; !4] 没有方法 `iter` +y = x.freeze() +i = y.iter() +assert sum(i) == 10 +y # y 仍然可以被触摸 +``` + +## 借 + +借用比复制或冻结便宜。 +可以在以下简单情况下进行借款: + +```python +peek_str ref(s: Str!) = + log s + +s = !"hello" +peek_str s +``` + +借来的值称为原始对象的 __reference__。 +您可以“转租”对另一个子例程的引用,但您不能使用它,因为您只是借用它。 + +```python +steal_str ref(s: Str!) = + # 由于日志函数只借用参数,所以可以转租 + log s + # 错误,因为丢弃函数消耗了参数 + discard s # OwnershipError: 不能消费借来的值 + # 提示:使用 `clone` 方法 +``` + +```python +steal_str ref(s: Str!) = + # 这也不好(=消耗右边) + x = s # OwnershipError: 不能消费借来的值 + x +``` + +Erg 的引用比 Rust 的更严格。 引用是语言中的一等对象,但不能显式创建,它们只能指定为通过 `ref`/`ref!` 传递的参数。 +这意味着您不能将引用填充到数组中或创建将引用作为属性的类。 + +但是,这样的限制是语言中的自然规范,一开始就没有引用,而且它们并没有那么不方便。 + +## 循环引用 + +Erg 旨在防止无意的内存泄漏,如果内存检查器检测到循环引用,则会发出错误。 在大多数情况下,这个错误可以通过弱引用 `Weak` 来解决。 但是,由于无法生成循环图等具有循环结构的对象,因此我们计划实现一个 API,可以将循环引用作为不安全操作生成。 + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/19_visibility.md b/doc/zh_TW/syntax/19_visibility.md new file mode 100644 index 00000000..0e79c0e0 --- /dev/null +++ b/doc/zh_TW/syntax/19_visibility.md @@ -0,0 +1,191 @@ +# 可见性 + +Erg 变量具有 __visibility__ 的概念。 +到目前为止,我们看到的所有变量都称为 __private variables__。 这是一个外部不可见的变量。 +例如,`foo` 模块中定义的私有变量不能被另一个模块引用。 + +```python +# foo.er +x = "this is an invisible variable" +``` + +```python +#bar.er +foo = import "foo" +foo.x # AttributeError: 模块 'foo' 没有属性 'x' ('x' 是私有的) +``` + +另一方面,也有__public variables__,可以从外部引用。 +公共变量用`.`定义。 + +```python +# foo.er +.x = "this is a visible variable" +``` + +```python +#bar.er +foo = import "foo" +assert foo.x == "this is a visible variable" +``` + +您不需要向私有变量添加任何内容,但您也可以添加 `::` 或 `self::`(用于类型等的`Self::`)以表明它们是私有的。 增加。 如果它是一个模块,它也可以是 `module::` + +```python +::x = "this is an invisible variable" +assert ::x == x +assert self ::x == ::x +assert module::x == ::x +``` + +In the context of purely sequential execution, private variables are almost synonymous with local variables. It can be referenced from the inner scope. + +```python +::x = "this is a private variable" +y = + x + 1 # 完全是 module::x +``` + +通过使用`::`,可以区分作用域内同名的变量。 +在左侧指定要引用的变量的范围。 为顶层指定 `module`。 +如果未指定,则照常引用最里面的变量。 + +```python +::x = 0 +assert x == 0 +y = + ::x = 1 + assert x == 1 + z = + ::x = 2 + assert ::x == 2 + assert z::x == 2 + assert y::x == 1 + assert module::x == 0 +``` + +在匿名子程序作用域中,`self` 指定了它自己的作用域 + +```python +x = 0 +f = x -> + log module::x, self::x +f1# 0 1 +``` + +`::` 还负责访问私有实例属性。 + +```python +x = 0 +C = Class {x = Int} +C. + # 顶级 x 被引用(警告使用 module::x) + f1 self = x + # 实例属性 x 被引用 + f2 self = self::x +``` + +## 外部模块中的可见性 + +在一个模块中定义的类实际上可以定义来自外部模块的方法。 + +```python +# foo.er +.Foo = Class() +``` + +```python +#bar.er +{Foo; ...} = import "foo" + +Foo:: + private self = pass +Foo. + public self = self::private() + +.f() = + foo = Foo.new() + foo.public() + foo::private() # 属性错误 +``` + +但是,这两种方法都只在该模块中可用。 +外部定义的私有方法对 Foo 类的方法仅在定义模块内可见。 +公共方法暴露在类之外,但不在模块之外。 + +```python +# baz.er +{Foo; ...} = import "foo" + +foo = Foo.new() +foo.public() # 属性错误:“Foo”没有属性“public”(“public”在模块“bar”中定义) +``` + +此外,方法不能在要重新导出的类型中定义。 +这是为了避免混淆方法是否找到,具体取决于导入方法的模块。 + +```python +#bar.er +{.Foo; ...} = import "foo" + +.Foo:: + private self = pass # 错误 +Foo. + public self = self::private() # 错误 +``` + +如果你想做这样的事情,定义一个 [patch](./type/07_patch.md)。 + +```python +#bar.er +{Foo; ...} = import "foo" + +FooImpl = Patch Foo +FooImpl :=: + private self = pass +Foo Impl. + public self = self::private() +``` + +```python +# baz.er +{Foo; ...} = import "foo" +{FooImpl; ...} = import "bar" + +foo = Foo.new() +foo.public() +``` + +## 受限公共变量 + +可变可见性不限于完全公共/私有。 +您也可以有限制地发布。 + +```python +# foo.er +.record = { + .a = { + .(.record)x = 0 + .(module)y = 0 + .z = 0 + } + _ = .a.x # OK + _ = .a.y # OK + _ = .a.z # OK +} + +_ = .record.a.x # 可见性错误 +_ = .record.a.y # OK +_ = .record.a.z # OK +``` + +```python +foo = import "foo" +_ = foo.record.a.x # 可见性错误 +_ = foo.record.a.y # 可见性错误 +_ = foo.record.a.z # OK +``` + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/20_naming_rule.md b/doc/zh_TW/syntax/20_naming_rule.md new file mode 100644 index 00000000..7847b7ce --- /dev/null +++ b/doc/zh_TW/syntax/20_naming_rule.md @@ -0,0 +1,50 @@ +# 命名约定 + +如果要将变量用作常量表达式,请确保它以大写字母开头。 两个或多个字母可能是小写的。 + +```python +i: Option Type = Int +match i: + t: Type -> log "type" + None -> log "None" +``` + +具有副作用的对象总是以 `!` 结尾。 程序和程序方法,以及可变类型。 +然而,`Proc` 类型本身是不可变的。 + +```python +# Callable == Func or Proc +c: Callable = print! +match c: + p! -> log "proc" # `: Proc` 可以省略,因为它是不言自明的 + f -> log "func" +``` + +如果您想向外界公开一个属性,请在开头使用 `.` 定义它。 如果你不把`.`放在开头,它将是私有的。 为避免混淆,它们不能在同一范围内共存。 + +```python +o = {x = 1; .x = 2} # 语法错误:同名的私有变量和公共变量不能共存 +``` + +## 文字标识符 + +可以通过将字符串括在单引号 ('') 中来规避上述规则。 也就是说,程序对象也可以在没有 `!` 的情况下分配。 但是,在这种情况下,即使该值是常量表达式,也不会被视为常量。 +像这样用单引号括起来的字符串称为文字标识符。 +这在调用Python等其他语言的API(FFI)时使用。 + +```python +bar! = pyimport("foo").'bar' +``` + +在 Erg 中也有效的标识符不需要用 '' 括起来。 + +此外,文字标识符可以包含符号和空格,因此通常不能用作标识符的字符串可以用作标识符。 + +```python +'∂/∂t' y +'test 1: pass x to y'() +``` + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/21_lambda.md b/doc/zh_TW/syntax/21_lambda.md new file mode 100644 index 00000000..c7252620 --- /dev/null +++ b/doc/zh_TW/syntax/21_lambda.md @@ -0,0 +1,96 @@ +# 匿名函数 + +匿名函数是一种无需命名即可动态创建函数对象的语法。 + +```python +# `->` 是匿名函数操作符 +# 同 `f x, y = x + y` +f = (x, y) -> x + y +# same as `g(x, y: Int): Int = x + y` +g = (x, y: Int): Int -> x + y +``` + +如果只有一个参数,您可以省略 `()`。 + +```python +assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4] +assert ((i, j) -> [i, j])(1, 2) == [1, 2] +``` + +在下面的情况下,它是 `0..9, (i -> ...)` 而不是 `(0..9, i) -> ...` +`->` 在左侧只接受一个参数。 多个参数作为单个元组接收 + +```python +for 0..9, i: Int -> + ... +``` + +在匿名函数中,由于空格,解析存在差异 + +```python +# 在这种情况下,解释为 `T(() -> Int)` +i: T() -> Int +# 在这种情况下,它被解释为 (U()) -> Int +k: U() -> Int +``` + +匿名函数可以不带参数使用。 + +```python +# `=>` 是一个匿名过程操作符 +p! = () => print! # `p!` 被调用 +# `() ->`, `() =>` 有语法糖 `do`, `do!` +# p! = do! print! "`p!` 被调用 +p!() # `p!` 被调用 +``` + +无参数函数可用于延迟初始化 + +```python +time = import "time" +date = import "datetime" +now = if! True: + do!: + time. sleep! 1000 + date.now!() + do date.new("1970", "1", "1", "00", "00") +``` + +您还可以键入和模式匹配。 正因为如此,`match` 函数大多是借助匿名函数的力量来实现的。 +作为 `match` 函数的参数给出的匿名函数从顶部开始按顺序尝试。 因此,您应该在顶部描述特殊情况,在底部描述更一般的情况。 如果你弄错了顺序,编译器会发出警告(如果可能的话) + + +```python +n = (Complex or Ratio or Int).sample!() +i = matchn: + PI -> PI # 如果等于常数 PI + For (i: 1..10) -> i # 整数从 1 到 10 + (i: Int) -> i # Int + (c: Complex) -> c.real() # 对于复杂。 Int < Complex,但可以回退 + _ -> panic "cannot convert to Int" # 如果以上都不适用。 match 必须涵盖所有模式 +``` + +错误处理通常也使用 `?` 或 `match` 完成。 + +```python +res: ParseResult Int +matchres: + i: Int -> i + err: Error -> panic err.msg + +res2: Result Int, Error +match res2: + ok: Not Error -> log Type of ok + err: Error -> panic err.msg +``` + +## 匿名多相关系数 + +```python +# 与此相同 id|T|x:T = x +id = |T| x: T -> x +``` + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/22_subroutine.md b/doc/zh_TW/syntax/22_subroutine.md new file mode 100644 index 00000000..38fafc51 --- /dev/null +++ b/doc/zh_TW/syntax/22_subroutine.md @@ -0,0 +1,62 @@ +# 子程序签名 + +## 函数 + +```python +some_func(x: T, y: U) -> V +some_func: (T, U) -> V +``` + +## 过程 + +```python +some_proc!(x: T, y: U) => V +some_proc!: (T, U) => V +``` + +## 函数方法 + +方法类型不能用`Self`在外部指定 + +```python +.some_method(self, x: T, y: U) => () +# Self.(T, U) => () 拥有 self 的所有权 +.some_method: Ref(Self). (T, U) => () +``` + +## 过程方法(依赖) + +在下文中,假设类型 `T!` 采用类型参数 `N: Nat`。 要在外部指定它,请使用类型变量 + +```python +T!: Nat -> Type +# ~> 表示应用前后类型参数的状态(此时self必须是变量引用) +T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => () +``` + +注意,`.some_method` 的类型是 `Ref!(T(N ~> N+X))。 ({X}) => () | N,X:Nat`。 +对于没有 `ref!` 的方法,即在应用后被剥夺所有权,不能使用类型参数转换(`~>`)。 + +如果取得所有权,则如下所示。 + +```python +# 如果不使用N,可以用_省略。 +# .some_method!: |N, X: Nat| T!(N).({X}) => T!(N+X) +.some_method!|N, X: Nat|(self(N), X: Nat) => T!(N+X) +``` + +## 运算符 + +可以通过用 ` 括起来将其定义为普通函数。 + +中性字母运算符,例如 `and` 和 `or` 可以通过用 ` 括起来定义为中性运算符。 + +```python +and(x, y, z) = x and y and z +`_+_`(x: Foo, y: Foo) = x.a + y.a +`-_`(x: Foo) = Foo.new(-x.a) +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/23_closure.md b/doc/zh_TW/syntax/23_closure.md new file mode 100644 index 00000000..eb3122ac --- /dev/null +++ b/doc/zh_TW/syntax/23_closure.md @@ -0,0 +1,96 @@ +# 关闭 + +Erg 子例程有一个称为“闭包”的功能,可以捕获外部变量。 + +```python +outer = 1 +f x = outer + x +assert f(1) == 2 +``` + +与不可变对象一样,可变对象也可以被捕获。 + +```python +sum = !0 +for! 1..10, i => + sum.add!i +assert sum == 45 + +p!x= + sum.add!x +p!(1) +assert sum == 46 +``` + +但是请注意,函数不能捕获可变对象。 +如果可以在函数中引用可变对象,则可以编写如下代码。 + +```python +# !!! 这段代码实际上给出了一个错误!!! +i = !0 +f x = i + x +assert f 1 == 1 +i.add! 1 +assert f 1 == 2 +``` + +该函数应该为相同的参数返回相同的值,但假设被打破了。 +请注意,`i` 仅在调用时进行评估。 + +如果您想在定义函数时获取可变对象的内容,请调用`.clone` + +```python +i = !0 +immut_i = i.clone().freeze() +fx = immut_i + x +assert f 1 == 1 +i.add! 1 +assert f 1 == 1 +``` + +## avoid mutable state, functional programming + +```python +# Erg +sum = !0 +for! 1..10, i => + sum.add!i +assert sum == 45 +``` + +上面的等效程序可以用 Python 编写如下: + +```python +# Python +sum = 0 +for i in range(1, 10): + sum += i +assert sum == 45 +``` + +但是,Erg 建议使用更简单的表示法。 +与其使用子例程和可变对象来传递状态,不如使用一种使用函数来定位状态的风格。这称为函数式编程 + +```python +# 功能风格 +sum = (1..10).sum() +assert sum == 45 +``` + +上面的代码给出了与之前完全相同的结果,但是您可以看到这个代码要简单得多。 + +`fold` 函数可以用来做比 sum 更多的事情。 +`fold` 是一个迭代器方法,它为每次迭代执行参数 `f`。 +累加结果的计数器的初始值在 `init` 中指定,并在 `acc` 中累加。 + +```python +# 从0开始,结果会 +sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i) +assert sum == 45 +``` + +Erg 被设计为对使用不可变对象进行编程的自然简洁描述。 + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/24_module.md b/doc/zh_TW/syntax/24_module.md new file mode 100644 index 00000000..eee8832e --- /dev/null +++ b/doc/zh_TW/syntax/24_module.md @@ -0,0 +1,42 @@ +# module + +Erg allows you to think of the file itself as a single record. This is called a module. + +```python: foo.er +# foo.er +.i = 1 +``` + +```python +# 定义 foo 模块与定义这条记录几乎相同 +foo = {.i = 1} +``` + +```python: bar.er +#bar.er +foo = import "foo" +print! foo # +assert foo.i == 1 +``` + +由于模块类型也是记录类型,因此可以进行解构赋值 + +```python +{sin; cos; ...} = import "math" +``` + +## 模块可见性 + +```console +└─┬ ./src + ├─ lib.er + ├─ foo.er + ├─bar.er + └─┬ bar + ├─ baz.er + └─ qux.er +``` + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/25_object_system.md b/doc/zh_TW/syntax/25_object_system.md new file mode 100644 index 00000000..116cd662 --- /dev/null +++ b/doc/zh_TW/syntax/25_object_system.md @@ -0,0 +1,82 @@ +# 目的 + +可以分配给变量的所有数据。 `Object` 类的属性如下。 + +* `.__repr__`:返回对象的(非丰富)字符串表示 +* `.__sizeof__`:返回对象的大小(包括堆分配) +* `.__dir__`: 返回对象属性列表 +* `.__hash__`:返回对象的哈希值 +* `.__getattribute__`: 获取并返回对象的属性 +* `.clone`:创建并返回一个对象的克隆(在内存中有一个独立的实体) +* `.copy`:返回对象的副本(指向内存中的同一事物) + +## 记录 + +由记录文字(`{attr = value; ...}`)生成的对象。 +这个对象有基本的方法,比如`.clone`和`.__sizeof__`。 + +```python +obj = {.x = 1} +assert obj.x == 1 + +obj2 = {...x; .y = 2} +assert obj2.x == 1 and obj2.y == 2 +``` + +## 属性 + +与对象关联的对象。 特别是,将 self (`self`) 作为其隐式第一个参数的子例程属性称为方法。 + +```python +# 请注意,private_attr 中没有`.` +record = {.public_attr = j; private_attr = 2; .method = self -> self.i + 1} +record. public_attr == 2 +record.private_attr # AttributeError: private_attr 是私有的 +assert record.method() == 3 +``` + +## 元素 + +属于特定类型的对象(例如,“1”是“Int”类型的元素)。所有对象至少是`{=}`类型的元素。 +类的元素有时称为实例。 + +## 子程序 + +表示作为函数或过程(包括方法)实例的对象。代表子程序的类是“子程序”。 +实现 `.__call__` 的对象通常称为 `Callable`。 + +## 可调用 + +一个实现`.__call__`的对象。它也是 `Subroutine` 的超类。 + +## 类型 + +定义需求属性并使对象通用化的对象。 +主要有两种类型:多态类型和单态类型。典型的单态类型有`Int`、`Str`等,多态类型有`Option Int`、`[Int; 3]`等 +此外,定义改变对象状态的方法的类型称为 Mutable 类型,需要在变量属性中添加 `!`(例如动态数组:`[T; !_]`)。 + +## 班级 + +具有 `.__new__`、`.__init__` 方法等的类型。实现基于类的面向对象。 + +## 功能 + +对外部变量(不包括静态变量)有读权限但对外部变量没有读/写权限的子程序。换句话说,它没有外部副作用。 +Erg 函数的定义与 Python 的不同,因为它们不允许副作用。 + +## 程序 + +它对外部变量具有读取和“自我”权限,对静态变量具有读/写权限,并允许使用所有子例程。它可能有外部副作用。 + +## 方法 + +隐式将“self”作为第一个参数的子例程。它与简单的函数/过程是不同的类型。 + +## 实体 + +不是子例程和类型的对象。 +单态实体(`1`、`"a"` 等)也称为值对象,多态实体(`[1, 2, 3], {"a": 1}`)也称为容器对象。 + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/26_pattern_matching.md b/doc/zh_TW/syntax/26_pattern_matching.md new file mode 100644 index 00000000..047fc29d --- /dev/null +++ b/doc/zh_TW/syntax/26_pattern_matching.md @@ -0,0 +1,193 @@ +# 模式匹配,可反驳 + +## Erg 中可用的模式 + +### 变量模式 + +```python +# 基本任务 +i = 1 +# 有类型 +i: Int = 1 +# 匿名类型 +i: {1, 2, 3} = 2 + +# 功能 +fn x = x + 1 +# 等于 +fn x: Add(Int) = x + 1 +# (匿名)函数 +fn = x -> x + 1 +fn: Int -> Int = x -> x + 1 + +# 高阶类型 +a: [Int; 4] = [0, 1, 2, 3] +# or +a: Array Int, 4 = [0, 1, 2, 3] +``` + +### 文字字面量 + +```python +# 如果在编译时无法确定 `i` 为 1,则引发 TypeError。 +# 省略 `_: {1} = i` +1 = i + +# 简单的模式匹配 +match x: + 1 -> "1" + 2 -> "2" + _ -> "other" + +# 斐波那契函数 +fib0 = 0 +fib1 = 1 +fibn: Nat = fibn-1 + fibn-2 +``` + +### 常量模式 + +```python +cond=False +match! cond: + True => print! "cond is True" + _ => print! "cond is False" + +PI = 3.141592653589793 +E = 2.718281828459045 +num = PI +name = match num: + PI -> "pi" + E -> "e" + _ -> "unnamed" +``` + +### 筛子图案 + +```python +# 这两个是一样的 +Array(T, N: {N | N >= 3}) +Array(T, N | N >= 3) + +f M, N | M >= 0, N >= 1 = ... +f(1, 0) # 类型错误:N(第二个参数)必须为 1 或更多 +``` + +### 丢弃(通配符)模式 + +```python +_ = 1 +_: Int = 1 +zero_ = 0 +right(_, r) = r +``` + +### 可变长度模式 + +它与稍后描述的元组/数组/记录模式结合使用。 + +```python +[i,...j] = [1, 2, 3, 4] +assert j == [2, 3, 4] +first|T|(fst: T, ...rest: T) = fst +assert first(1, 2, 3) == 1 +``` + +### 元组模式 + +```python +(i, j) = (1, 2) +((k, l), _) = ((1, 2), (3, 4)) +# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) +m, n = 1, 2 + +f(x, y) = ... +``` + +### 数组模式 + +```python +[i, j] = [1, 2] +[[k, l], _] = [[1, 2], [3, 4]] + +length[] = 0 +length[_, ...rest] = 1 + lengthrest +``` + +#### record 模式 + +```python +record = {i = 1; j = 2; k = 3} +{j; ...} = record # i, k 将被释放 + +{sin; cos; tan; ...} = import "math" +{*} = import "math" # import all + +person = {name = "John Smith"; age = 20} +age = match person: + {name = "Alice"; _} -> 7 + {_; age} -> age + +f {x: Int; y: Int} = ... +``` + +### 数据类模式 + +```python +Point = Inherit {x = Int; y = Int} +p = Point::{x = 1; y = 2} +Point::{x; y} = p + +Nil T = Class Impl := Phantom T +Cons T = Inherit {head = T; rest = List T} +List T = Enum Nil(T), Cons(T) +List T. + first self = + match self: + Cons::{head; ...} -> x + _ -> ... + second self = + match self: + Cons::{rest=Cons::{head; ...}; ...} -> head + _ -> ... +``` + +### 枚举模式 + +* 其实只是枚举类型 + +```python +match x: + i: {1, 2} -> "one or two: {i}" + _ -> "other" +``` + +### Range 模式 + +* 实际上,它只是一个区间类型。 + +```python +# 0 < i < 1 +i: 0<..<1 = 0.5 +# 1 < j <= 2 +_: {[I, J] | I, J: 1<..2} = [1, 2] +# 1 <= i <= 5 +match i + i: 1..5 -> ... +``` + +### 不是模式的东西,不能被模式化的东西 + +模式是可以唯一指定的东西。 在这方面,模式匹配不同于普通的条件分支。 + +条件规格不是唯一的。 例如,要检查数字 `n` 是否为偶数,正统是 `n % 2 == 0`,但也可以写成 `(n / 2).round() == n / 2`。 +非唯一形式无论是正常工作还是等效于另一个条件都不是微不足道的。 + +#### Set + +没有固定的模式。 因为集合没有办法唯一地检索元素。 +您可以通过迭代器检索它们,但不能保证顺序。 + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/27_comprehension.md b/doc/zh_TW/syntax/27_comprehension.md new file mode 100644 index 00000000..6e301665 --- /dev/null +++ b/doc/zh_TW/syntax/27_comprehension.md @@ -0,0 +1,65 @@ +# Comprehension + +Array 和 `[expr | (name <- iterable)+ (predicate)*]`, +set 和 `{expr | (name <- iterable)+ (predicate)*}`, +你可以创建一个字典 `{key: value | (name <- iterable)+ (predicate)*}`. + +由`|`分隔的子句的第一部分称为布局子句(位置子句),第二部分称为绑定子句(绑定子句),第三部分称为保护子句(条件子句)。 +保护子句可以省略,但绑定子句不能省略,保护子句不能在绑定子句之前。 + +理解示例 + +```python +# 布局子句是 i +# 绑定子句是 i <- [0, 1, 2] +assert [i | i <- [0, 1, 2]] == [0, 1, 2] + +# 布局子句是 i / 2 +# 绑定子句是 i <- 0..2 +assert [i/2 | i <- 0..2] == [0.0, 0.5, 1.0] + +# 布局子句是 (i, j) +# 绑定子句 i <- 0..2, j <- 0..2 +# 保护子句是 (i + j) % 2 == 0 +assert [(i, j) | i <- 0..2; j <- 0..2; (i + j) % 2 == 0] == [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)] + +assert {i % 2 | i <- 0..9} == {0, 1} +assert {k: v | k <- ["a", "b"]; v <- [1, 2]} == {"a": 1, "b": 2} +``` + +Erg推导式受到 Haskell 的启发,但有一些不同。 +对于 Haskell 列表推导,变量的顺序会对结果产生影响,但在 Erg 中这并不重要。 + +``` haskell +-- Haskell +[(i, j) | i <- [1..3], j <- [3..5]] == [(1,3),(1,4),(1,5),(2 ,3),(2,4),(2,5),(3,3),(3,4),(3,5)] +[(i, j) | j <- [3..5], i <- [1..3]] == [(1,3),(2,3),(3,3),(1 ,4),(2,4),(3,4),(1,5),(2,5),(3,5)] +``` + +```python +# Erg +assert [(i, j) | i <- 1..<3; j <- 3..<5] == [(i, j) | j <- 3..<5; i <- 1.. <3] +``` + +该规范与 Python 的规范相同。 + +```python +# Python +assert [(i, j) for i in range(1, 3) for j in range(3, 5)] == [(i, j) for j in range(3, 5) for i in range(1, 3)] +``` + +## 筛子类型 + +与推导类似的是筛类型。 筛子类型是以`{Name: Type | Predicate}`创建的(枚举类型) +sieve类型的情况下,只能指定一个Name,不能指定布局(但是如果是tuple类型可以处理多个值),Predicate可以在编译时计算,即 ,只能指定一个常量表达式。 + +```python +Nat = {I: Int | I >= 0} +# 如果谓词表达式只有and,可以替换为: +# Nat2D = {(I, J): (Int, Int) | I >= 0; J >= 0} +Nat2D = {(I, J): (Int, Int) | I >= 0 and J >= 0} +``` + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/28_spread_syntax.md b/doc/zh_TW/syntax/28_spread_syntax.md new file mode 100644 index 00000000..81b98343 --- /dev/null +++ b/doc/zh_TW/syntax/28_spread_syntax.md @@ -0,0 +1,42 @@ +# 传播赋值 + +在分解赋值中,将 `...` 放在变量前面会将所有剩余元素展开到该变量中。 这称为扩展赋值。 + +```python +[x,...y] = [1, 2, 3] +assert x == 1 +assert y == [2, 3] +x, ...y = (1, 2, 3) +assert x == 1 +assert y == (2, 3) +``` + +## 提取赋值 + +如果在 `...` 之后没有写入任何内容,则忽略并分配剩余的元素。 这种类型的扩展赋值具体称为抽取赋值。 +提取分配是一种方便的语法,用于本地化模块或记录中的特定属性。 + +```python +{sin; cos; tan; ..} = import "math" +``` + +After that, you can use `sin, cos, tan` locally. + +You can do the same with records. + +```python +record = {x = 1; y = 2} +{x; y; ...} = record +``` + +If you want to expand all, use `{*} = record`. It is `open` in OCaml. + +```python +record = {x = 1; y = 2} +{*} = records +assert x == 1 and y == 2 +``` + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/29_decorator.md b/doc/zh_TW/syntax/29_decorator.md new file mode 100644 index 00000000..9046f20c --- /dev/null +++ b/doc/zh_TW/syntax/29_decorator.md @@ -0,0 +1,120 @@ +# 装饰器(修饰符) + +装饰器用于向类型或函数添加或演示特定状态或行为。 +装饰器的语法如下。 + +```python +@deco +X=... +``` + +你可以有多个装饰器,只要它们不冲突。 + +装饰器不是一个特殊的对象,它只是一个单参数函数。 装饰器等价于下面的伪代码。 + +```python +X=... +X = deco(X) +``` + +Erg 不允许重新分配变量,因此上面的代码不起作用。 +对于简单的变量,它与`X = deco(...)` 相同,但对于即时块和子例程,你不能这样做,所以你需要一个装饰器。 + +```python +@deco +f x = + y = ... + x + y + +# 还可以防止代码变成水平的 +@LongNameDeco1 +@LongNameDeco2 +C = Class... +``` + +下面是一些常用的内置装饰器。 + +## 可继承 + +指示定义类型是可继承的类。 如果为参数 `scope` 指定 `"public"`,甚至可以继承外部模块的类。 默认情况下它是`"private"`,不能被外部继承。 + +## 最后 + +使该方法不可覆盖。 将它添加到类中使其成为不可继承的类,但由于它是默认值,因此没有意义。 + +## 覆盖 + +覆盖属性时使用。 默认情况下,如果您尝试定义与基类相同的属性,Erg 将抛出错误。 + +## 实现 + +表示参数 trait 已实现。 + +```python +Add = Trait { + .`_+_` = Self.(Self) -> Self +} +Sub = Trait { + .`_-_` = Self.(Self) -> Self +} + +C = Class({i = Int}, Impl := Add and Sub) +C. + @Impl Add + `_+_` self, other = C.new {i = self::i + other::i} + @Impl Sub + `_-_` self, other = C.new {i = self::i - other::} +``` + +## 附 + +指定默认情况下随 trait 附带的附件补丁。 +这允许您重现与 Rust 特征相同的行为。 + +```python +# foo.er +Add R = Trait { + .AddO = Type + .`_+_` = Self.(R) -> Self.AddO +} +@Attach AddForInt, AddForOdd +ClosedAdd = Subsume Add(Self) + +AddForInt = Patch(Int, Impl := ClosedAdd) +AddForInt.AddO = Int +AddForOdd = Patch(Odd, Impl := ClosedAdd) +AddForOdd.AddO = Even +``` + +当从其他模块导入特征时,这将自动应用附件补丁。 + +```Python +# 本来应该同时导入IntIsBinAdd和OddIsBinAdd,但是如果是附件补丁可以省略 +{BinAdd; ...} = import "foo" + +assert Int. AddO == Int +assert Odd.AddO == Even +``` + +在内部,它只是使用 trait 的 .attach 方法附加的。 可以使用 trait 的 `.detach` 方法消除冲突。 + +```python +@Attach X +T = Trait... +assert X in T. attaches +U = T.detach(X).attach(Y) +assert X not in U. attaches +assert Y in U. attaches +``` + +## 已弃用 + +指示变量规范已过时且不推荐使用。 + +## 测试 + +表示这是一个测试子例程。 测试子程序使用 `erg test` 命令运行。 + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/30_error_handling.md b/doc/zh_TW/syntax/30_error_handling.md new file mode 100644 index 00000000..5b64a6f8 --- /dev/null +++ b/doc/zh_TW/syntax/30_error_handling.md @@ -0,0 +1,108 @@ +# 错误处理系统 + +主要使用Result类型。 +在 Erg 中,如果您丢弃 Error 类型的对象(顶层不支持),则会发生错误。 + +## 异常,与 Python 互操作 + +Erg 没有异常机制(Exception)。 导入 Python 函数时 + +* 将返回值设置为 `T 或 Error` 类型 +* `T or Panic` 类型(可能导致运行时错误) + +有两个选项,`pyimport` 默认为后者。 如果要作为前者导入,请使用 +在 `pyimport` `exception_type` 中指定 `Error` (`exception_type: {Error, Panic}`)。 + +## 异常和结果类型 + +`Result` 类型表示可能是错误的值。 `Result` 的错误处理在几个方面优于异常机制。 +首先,从类型定义中可以看出子程序可能会报错,实际使用时也很明显。 + +```python +# Python +try: + x = foo().bar() + y = baz() + qux() +except e: + print(e) +``` + +在上面的示例中,仅凭此代码无法判断哪个函数引发了异常。 即使回到函数定义,也很难判断函数是否抛出异常。 + +```python +# Erg +try!: + do!: + x = foo!()?.bar() + y = baz!() + qux!()? + e => + print! e +``` + +另一方面,在这个例子中,我们可以看到 `foo!` 和 `qux!` 会引发错误。 +确切地说,`y` 也可能是 `Result` 类型,但您最终必须处理它才能使用里面的值。 + +使用 `Result` 类型的好处不止于此。 `Result` 类型也是线程安全的。 这意味着错误信息可以(轻松)在并行执行之间传递。 + +## 语境 + +由于 `Error`/`Result` 类型本身不会产生副作用,不像异常,它不能有发送位置(Context)等信息,但是如果使用 `.context` 方法,可以将信息放在 `错误`对象。 可以添加。 `.context` 方法是一种使用 `Error` 对象本身并创建新的 `Error` 对象的方法。 它们是可链接的,并且可以包含多个上下文。 +```python +f() = + todo() \ + .context "to be implemented in ver 1.2" \ + .context "and more hints ..." + +f() +# Error: not implemented yet +# hint: to be implemented in ver 1.2 +# hint: and more hints ... +``` + +请注意,诸如 `.msg` 和 `.kind` 之类的 `Error` 属性不是次要的,因此它们不是上下文,并且不能像最初创建时那样被覆盖。 + +## 堆栈跟踪 + +`Result` 类型由于其方便性在其他语言中经常使用,但与异常机制相比,它的缺点是难以理解错误的来源。 +因此,在 Erg 中,`Error` 对象具有名为 `.stack` 的属性,并再现了类似伪异常机制的堆栈跟踪。 +`.stack` 是调用者对象的数组。 每次 Error 对象被`return`(包括通过`?`)时,它都会将它的调用子例程推送到`.stack`。 +如果它是 `?`ed 或 `.unwrap`ed 在一个不可能 `return` 的上下文中,它会因为回溯而恐慌。 + +```python +f x = + ... + y = foo.try_some(x)? + ... + +g x = + y = f(x)? + ... + +i = g(1)? +# Traceback (most recent call first): +# ... +# Foo.try_some, line 10, file "foo.er" +# 10 | y = foo.try_some(x)? +# module::f, line 23, file "foo.er" +# 23 | y = f(x)? +# module::g, line 40, file "foo.er" +# 40 | i = g(1)? +# Error: ... +``` + +## 恐慌 + +Erg 还有一种处理不可恢复错误的机制,称为 __panicing__。 +不可恢复的错误是由外部因素引起的错误,例如软件/硬件故障、严重到无法继续执行代码的错误或程序员未预料到的错误。 等如果发生这种情况,程序将立即终止,因为程序员的努力无法恢复正常运行。 这被称为“恐慌”。 + +恐慌是通过 `panic` 功能完成的。 + +```python +panic "something went wrong!" +``` + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/31_pipeline.md b/doc/zh_TW/syntax/31_pipeline.md new file mode 100644 index 00000000..acaeef49 --- /dev/null +++ b/doc/zh_TW/syntax/31_pipeline.md @@ -0,0 +1,32 @@ +# 管道运算符 + +管道运算符的使用方式如下: + +```python +assert f(g(x)) == (x |> g |> f) +assert f(g(x, y)) == ((x, y) |> g |> f) +``` + +换句话说,`Callable(object)` 的顺序可以更改为 `object |> Callable`。 +管道运算符也可用于方法。 对于方法,`object.method(args)` 更改为 `object |>.method(args)`。 +它看起来只是更多的`|>`,但由于粘合强度较低,您可以减少`()`的数量。 + +```python +rand = -1.0..1.0 |>.sample!() +log rand # 0.2597... + +1+1*2 |>.times do log("a", end := "") # aaa + +evens = 1..100 |>.iter |>.filter i -> i % 2 == 0 |>.collect Array +# 在没有管道操作符的情况下实现, +_evens = (1..100).iter().filter(i -> i % 2 == 0).collect(Array) +# or +__evens = 1..100 \ + .iter() \ + .filter i -> i % 2 == 0 \ + .collect Array +``` + +

+ 上一页 | 下一页 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/32_integration_with_Python.md b/doc/zh_TW/syntax/32_integration_with_Python.md new file mode 100644 index 00000000..d18ac194 --- /dev/null +++ b/doc/zh_TW/syntax/32_integration_with_Python.md @@ -0,0 +1,83 @@ +# 与 Python 集成 + +## 导出到 Python + +编译 Erg 脚本时,会生成一个 .pyc 文件,可以简单地将其作为 Python 模块导入。 +但是,无法从 Python 访问在 Erg 端设置为私有的变量。 + +```python +# foo.er +.public = "this is a public variable" +private = "this is a private variable" +``` + +```console +erg --compile foo.er +``` + +```python +import foo + +print(foo.public) +print(foo.private) # 属性错误: +``` + +## 从 Python 导入 + +默认情况下,从 Python 导入的所有对象都是“Object”类型。 由于此时无法进行比较,因此有必要细化类型。 + +## 标准库中的类型规范 + +Python 标准库中的所有 API 都是由 Erg 开发团队指定的类型。 + +```python +time = pyimport "time" +time.sleep! 1 +``` + +## 用户脚本的类型规范 + +创建一个类型为 Python `foo` 模块的 `foo.d.er` 文件。 +Python 端的类型提示被忽略,因为它们不是 100% 保证的。 + +```python +# foo.py +X = ... +def bar(x): + ... +def baz(): + ... +... +``` + +```python +# foo.d.er +foo = pyimport "foo" +.X = declare foo.'X', Int +.bar = declare foo.'bar', Int -> Int +.baz! = declare foo.'baz', () => Int +``` + +```python +foo = pyimport "foo" +assert foo.bar(1) in Int +``` + +这通过在运行时执行类型检查来确保类型安全。 ``declare`` 函数大致如下工作 + + +```python +declare|S: Subroutine| sub!: S, T = + # 实际上,=> 可以强制转换为没有块副作用的函数 + x => + assert x in T.Input + y = sub!(x) + assert y in T.Output + y +``` + +由于这是运行时开销,因此计划使用 Erg 的类型系统对 Python 脚本进行静态类型分析 + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/33_package_system.md b/doc/zh_TW/syntax/33_package_system.md new file mode 100644 index 00000000..a2a817fd --- /dev/null +++ b/doc/zh_TW/syntax/33_package_system.md @@ -0,0 +1,83 @@ +# 打包系统 + +Erg包大致可以分为app包,即应用程序,以及lib包,即库。 +应用包的入口点是`src/app.er`。 `app.er` 中定义的`main` 函数被执行。 +lib 包的入口点是`src/lib.er`。导入包相当于导入 `lib.er`。 + +一个包有一个称为模块的子结构,在 Erg 中是一个 Erg 文件或由 Erg 文件组成的目录。外部 Erg 文件/目录是作为模块对象的可操作对象。 + +为了将目录识别为模块,有必要在目录中放置一个“(目录名称).er”文件。 +这类似于 Python 的 `__init__.py`,但与 `__init__.py` 不同的是,它放在目录之外。 + +例如,考虑以下目录结构。 + +```console +└─┬ ./src + ├─ app.er + ├─ foo.er + ├─ bar.er + └─┬ bar + ├─ baz.er + └─ qux.er +``` + +您可以在 `app.er` 中导入 `foo` 和 `bar` 模块。由于 `bar.er` 文件,`bar` 目录可以被识别为一个模块。 +`foo` 模块是由文件组成的模块,`bar` 模块是由目录组成的模块。 `bar` 模块还包含 `baz` 和 `qux` 模块。 +该模块只是 `bar` 模块的一个属性,可以从 `app.er` 访问,如下所示。 + +```python +# app.er +foo = import "foo" +bar = import "bar" +baz = bar.baz +# or `baz = import "bar/baz"` + +main args = + ... +``` + +请注意用于访问子模块的 `/` 分隔符。 这是因为可以有诸如 `bar.baz.er` 之类的文件名。 +不鼓励使用此类文件名,因为 `.er` 前缀在 Erg 中是有意义的。 +例如,用于测试的模块。 以 `.test.er` 结尾的文件是一个(白盒)测试模块,它在运行测试时执行一个用 `@Test` 修饰的子例程。 + +```console +└─┬ ./src + ├─ app.er + ├─ foo.er + └─ foo.test.er +./src + +```python +# app.er +foo = import "foo" + +main args = + ... +``` + +此外,以 .private.er 结尾的文件是私有模块,只能由同一目录中的模块访问。 + +```console +└─┬ + ├─ foo.er + ├─ bar.er + └─┬ bar + ├─ baz.private.er + └─ qux.er +``` + +```python +# foo.er +bar = import "bar" +bar.qux +bar.baz # AttributeError: module 'baz' is private +``` + +```python +# qux.er +baz = import "baz" +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/34_generator.md b/doc/zh_TW/syntax/34_generator.md new file mode 100644 index 00000000..8d260ba1 --- /dev/null +++ b/doc/zh_TW/syntax/34_generator.md @@ -0,0 +1,35 @@ +# 生成器 + +生成器是在块中使用 `yield!` 过程的特殊过程。 + +```python +g!() = + yield! 1 + yield! 2 + yield! 3 +``` + +`yield!` 是在调用`self!.yield!` 的子程序块中定义的过程。 和`return`一样,它把传递给它的值作为返回值返回,但它具有保存block当前执行状态,再次调用时从头开始执行的特性。 +生成器既是过程又是迭代器; Python 生成器是一个创建迭代器的函数,而 Erg 直接迭代。 过程本身通常不是可变对象(没有`!`),但生成器是可变对象,因为它自己的内容可以随着每次执行而改变。 + +```python +# Generator! +g!: Generator!((), Int) +assert g!() == 1 +assert g!() == 2 +assert g!() == 3 +``` + +Python 风格的生成器可以定义如下。 + +```python +make_g() = () => + yield! 1 + yield! 2 + yield! 3 +make_g: () => Generator! +``` + +

+ 上一页 | Next +

diff --git a/doc/zh_TW/syntax/SUMMARY.md b/doc/zh_TW/syntax/SUMMARY.md new file mode 100644 index 00000000..f9486625 --- /dev/null +++ b/doc/zh_TW/syntax/SUMMARY.md @@ -0,0 +1,69 @@ +# 概括 + +- [基础](./00_basic.md) +- [文字](./01_literal.md) +- [名称](02_name.md) +- [声明](./03_declaration.md) +- [函数](./04_function.md) +- [内置函数](./05_builtin_funcs.md) +- [操作员](./06_operator.md) +- [副作用](./07_side_effect.md) +- [程序](./08_procedure.md) +- [内置程序](./09_builtin_procs.md) +- [数组](./10_array.md) +- [元组](./11_tuple.md) +- [字典](./12_dict.md) +- [记录](./13_record.md) +- [设置](./14_set.md) +- [类型](./15_type.md) + - [类型系统](./type/01_type_system.md) + - [基础](./type/02_basic.md) + - [特质](./type/03_trait.md) + - [类](./type/04_class.md) + - [继承](./type/05_inheritance.md) + - [NST 与 SST](./type/06_nst_vs_sst.md) + - [补丁](./type/07_patch.md) + - [值类型](./type/08_value.md) + - [属性类型](./type/09_attributive.md) + - [间隔类型](./type/10_interval.md) + - [枚举类型](./type/11_enum.md) + - [细化类型](./type/12_refinement.md) + - [代数类型](./type/13_algebraic.md) + - [依赖类型](./type/14_dependent.md) + - [量化类型](./type/15_quantified.md) + - [子类型](./type/16_subtyping.md) + - [类型转换](./type/17_type_casting.md) + - [可变类型](./type/18_mut.md) + - [高级](./type/advanced.md) + - [默认参数](./type/advanced/default_param.md) + - [类型擦除](./type/advanced/erasure.md) + - [存在](./type/advanced/existential.md) + - [GADTs](./type/advanced/GADTs.md) + - [关键字参数](./type/advanced/keyword_param.md) + - [种类](./type/advanced/kind.md) + - [标记特征](./type/advanced/marker_trait.md) + - [可变结构](./type/advanced/mut_struct.md) + - [幻象类型](./type/advanced/phantom.md) + - [投影类型](./type/advanced/projection.md) + - [量化依赖类型](./type/advanced/quantified_dependent.md) + - [共享](./type/advanced/shared.md) +- [迭代器](./16_iterator.md) +- [可变性](./17_mutability.md) +- [所有权](./18_ownership.md) +- [可见性](./19_visibility.md) +- [命名规则](20_naming_rule.md) +- [Lambda](./21_lambda.md) +- [子程序](./22_subroutine.md) +- [关闭](./23_closure.md) +- [模块](./24_module.md) +- [对象系统](./25_object_system.md) +- [模式匹配](./26_pattern_matching.md) +- [理解](./27_comprehension.md) +- [扩展语法](./28_spread_syntax.md) +- [装饰器](./29_decorator.md) +- [错误处理](./30_error_handling.md) +- [管道](./31_pipeline.md) +- [与 Python 集成](./32_integration_with_python.md) +- [包系统](./33_package_system.md) +- [发电机](./34_generator.md) +- [索引](./indexes.md) \ No newline at end of file diff --git a/doc/zh_TW/syntax/container_ownership.md b/doc/zh_TW/syntax/container_ownership.md new file mode 100644 index 00000000..09bbfb3c --- /dev/null +++ b/doc/zh_TW/syntax/container_ownership.md @@ -0,0 +1,42 @@ +# 下标(索引访问) + +`[]` 不同于普通的方法。 + +```python +a = [!1, !2] +a[0].inc!() +assert a == [2, 2] +``` + +回想一下,子例程的返回值不能是引用。 +这里的 `a[0]` 的类型显然应该是 `Ref!(Int!)`(`a[0]` 的类型取决于上下文)。 +所以 `[]` 实际上是特殊语法的一部分,就像 `.` 一样。 与 Python 不同,它不能被重载。 +也无法在方法中重现 `[]` 的行为。 + +```python +C = Class {i = Int!} +C. get(ref self) = + self::i # 类型错误:`self::i` 是 `Int!`(需要所有权)但 `get` 不拥有 `self` +C.steal(self) = + self::i +#NG +C.new({i = 1}).steal().inc!() # 所有权警告:`C.new({i = 1}).steal()` 不属于任何人 +# 提示:分配给变量或使用 `uwn_do!` +# OK (分配) +c = C.new({i = 1}) +i = c.steal() +i.inc!() +assert i == 2 +# or (own_do!) +own_do! C.new({i = 1}).steal(), i => i.inc!() +``` + +此外,`[]` 可以不承认,但元素不会移动 + +```python +a = [!1, !2] +i = a[0] +i.inc!() +assert a[1] == 2 +a[0] # 所有权错误:`a[0]` 被移动到 `i` +``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/grammar.md b/doc/zh_TW/syntax/grammar.md new file mode 100644 index 00000000..8e4e8a06 --- /dev/null +++ b/doc/zh_TW/syntax/grammar.md @@ -0,0 +1,90 @@ +# Erg 的语法(版本 0.1.0, 临时) +``` +special_op ::= '=' | '->' | '=>' | '.' | ',' | ':' | '::' | '|>' | '&' +separator ::= ';' | '\n' +escape ::= '\' +comment_marker ::= '#' +reserved_symbol ::= special_op | separator | comment_marker +number ::= [0-9] +first_last_dight ::= number +dight ::= number | '_' +bin_dight ::= [0-1] +oct_dight ::= [0-8] +hex_dight ::= [0-9] + | [a-f] + | [A-F] +int ::= first_last_dight + | first_last_dight dight* first_last_dight + | '0' ('b' | 'B') binary_dight+ + | '0' ('o' | 'O') octa_dight+ + | '0' ('x' | 'X') hex_dight+ +ratio ::= '.' dight* first_last_dight + | first_last_dight dight* '.' dight* first_last_dight +bool ::= 'True' | 'False' +none ::= 'None' +ellipsis ::= 'Ellipsis' +not_implemented ::= 'NotImplemented' +parenthesis ::= '(' | ')' +bracket ::= '{' | '}' +square_bracket ::= '[' | ']' +enclosure ::= parenthesis | bracket | square_bracket +infix_op ::= '+' | '-' | '*' | '/' | '//' | '**' + | '%' | '&&' | '||' | '^^' | '<' | '<=' | '>' | '>=' + | 'and' | 'or' | 'is' | 'as' | 'isnot' | 'in' | 'notin' | 'dot' | 'cross' +prefix_op ::= '+' | '-' | '*' | '**' | '..' | '..<' | '~' | '&' | '!' +postfix_op ::= '?' | '..' | '<..' +operator ::= infix_op | prefix_op | postfix_op +char ::= /* ... */ +str ::= '\"' char* '\" +symbol_head ::= /* char except dight */ +symbol ::= symbol_head /* char except (reserved_symbol | operator | escape | ' ') */ +subscript ::= accessor '[' expr ']' +attr ::= accessor '.' symbol +accessor ::= symbol | attr | subscript +literal ::= int | ratio | str | bool | none | ellipsis | not_implemented +pos_arg ::= expr +kw_arg ::= symbol ':' expr +arg ::= pos_arg | kw_arg +enc_args ::= pos_arg (',' pos_arg)* ','? +args ::= '()' | '(' arg (',' arg)* ','? ')' | arg (',' arg)* +var_pattern ::= accessor | `...` accessor | '[' single_patterns ']' +var_decl_opt_t = var_pattern (':' type)? +var_decl = var_pattern ':' type +param_pattern ::= symbol | `...` symbol | literal | '[' param_patterns ']' +param_decl_opt_t = param_pattern (':' type)? +param_decl = param_pattern ':' type +params_opt_t ::= '()' (':' type)? + | '(' param_decl_opt_t (',' param_decl_opt_t)* ','? ')' (':' type)? + | param_decl_opt_t (',' param_decl_opt_t)* +params ::= '()' ':' type + | '(' param_decl (',' param_decl)* ','? ')' ':' type +subr_decl ::= accessor params +subr_decl_opt_t ::= accessor params_opt_t +decl ::= var_decl | subr_decl +decl_opt_t = var_decl_opt_t | subr_decl_opt_t +body ::= expr | indent line+ dedent +def ::= ('@' decorator '\n')* decl_opt_t '=' body +call ::= accessor args | accessor call +decorator ::= call +lambda_func ::= params_opt_t '->' body +lambda_proc ::= params_opt_t '=>' body +lambda ::= lambda_func | lambda_proc +normal_array ::= '[' enc_args ']' +array_comprehension ::= '[' expr | (generator)+ ']' +array ::= normal_array | array_comprehension +record ::= '{' '=' '}' + | '{' def (';' def)* ';'? '}' +set ::= '{' '}' + | '{' expr (',' expr)* ','? '}' +dict ::= '{' ':' '}' + | '{' expr ':' expr (',' expr ':' expr)* ','? '}' +tuple ::= '(' ')' + | '(' expr (',' expr)* ','? ')' +indent ::= /* ... */ +expr ::= accessor | literal + | prefix | infix | postfix + | array | record | set | dict | tuple + | call | def | lambda +line ::= expr separator+ +program ::= expr? | (line | comment)* +``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/indexes.md b/doc/zh_TW/syntax/indexes.md new file mode 100644 index 00000000..54ba47a3 --- /dev/null +++ b/doc/zh_TW/syntax/indexes.md @@ -0,0 +1,452 @@ +# 指数 + +有关不在此索引中的 API,请参阅 [此处](../API/index.md)。 +有关术语,请参见 [此处](../dev_guide/terms.md)。 + +## 符号 + +* ! + * !-type → [可变性](./type/mut.md) +* [#](./00_basic.md/#comment) +* $ +* % +* & + * && +* ′ (single quote) +* () +* * + * [*-less multiplication](./01_literal.md/#less-multiplication) +* + (前置) + * +_ → + (前置) +* + (中置) +* , +* − (前置) + * −_ → − (前置) +* − (中置) + * −> +* . → [可见性] +* / +* : + * :: → [可见性] +* ; +* < + * <: + * << + * <= +* = + * == + * => +* > + * >> + * >= +* ? +* @ +* [] +* \ +* ^ + * ^^ +* _ + * _+_ → + (infix) + * _-_ → − (infix) +*`` +* {} + * {} type +* {:} +* {=} + * {=} type +* | + * || +* ~ + +## 字母 + +### A + +* algebraic type +* And +* and +* assert +* attribute + +### B + +* Base +* Bool + +### C + +* Class + +### D + +* Deprecated +* distinct + +### E + +* enum type +* Eq +* Erg + +### F + +* for + +### G + +### H + +### I + +* if +* import +* in +* Int + +### J + +### K + +### L + +* let-polymorphism → [rank 1 polymorphism] +* log + +### M + +* match + +### N + +* Nat +* Never +* None +* None +* Not +* not + +### O + +* Option +* Or +* or +* Ord + +### P + +* panic +* [print!](./../API/procs.md#print) +* Python + +### Q + +### R + +* ref +* ref! +* Result +* rootobj + +### S + +* self +* [Self](./type/special.md) +* [side-effect](./07_side_effect.md) +* Str + +### T + +* Traits +* True +* Type +* type + +### U + +### V + +### W + +* while! + +### X + +### Y + +### Z + +## 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) + +## 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函数) +* 逗号 → [,] + +## 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) + * 封闭式通用 + * 打开通用 + * 通用函数 → 多相关函数 + * 通用量化 +* 前缀运算符 +* 相互递归 +* 下标 → [索引] +* [属性] + * [属性子类型] + +## 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) + +## 没有一行 + +* [理解](./27_comprehension.md) +* ~~中缀运算符~~ → [中缀运算符] +* [命名空间] + +## is a line + +* [数组](./10_array.md) +* [派生类型](./type/variances.md/#用户定义的类型变体) +* [模式(匹配)](./26_pattern_matching.md) +* [包](./33_package_ssystem.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) +* 底部 + * 底部类型 → [{}] + * 底层 → [从不] +* [多态性] + +## ma line + +* ~~ 前缀运算符 ~~ → 前缀运算符 +* [标记类型](./type/advanced/marker_trait.md) +* [匿名函数](./21_lambda.md) +* 可变 → [可变] +* [移动] +* 方法 +* 元字符 +* [模块](./24_module.md) +* [字符串] → [字符串] + * [字符串插值](./01_literal.md/#str字面量) +* 返回值 + +## or line + +* [幽灵类型](./type/advanced/phantom.md) +* 请求属性 +* [元素] +* [称呼] + +## 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) + +## line + +* 通配符 \ No newline at end of file diff --git a/doc/zh_TW/syntax/quick_tour.md b/doc/zh_TW/syntax/quick_tour.md new file mode 100644 index 00000000..886c4f8c --- /dev/null +++ b/doc/zh_TW/syntax/quick_tour.md @@ -0,0 +1,267 @@ +# 快速浏览 + +`syntax` 下面的文档是为了让编程初学者也能理解而编写的。 +对于已经掌握 Python、Rust、Haskell 等语言的人来说,可能有点啰嗦。 + +所以,这里是 Erg 语法的概述。 +请认为未提及的部分与 Python 相同。 + +## 变量,常量 + +变量用 `=` 定义。 与 Haskell 一样,变量一旦定义就不能更改。 但是,它可以在另一个范围内被遮蔽。 + +```python +i = 0 +if True: + i = 1 +assert i == 0 +``` + +任何以大写字母开头的都是常数。 只有可以在编译时计算的东西才能是常量。 +此外,自定义以来,常量在所有范围内都是相同的。 + +```python +PI = 3.141592653589793 +match random.random!(0..10): + PIs: + log "You get PI, it's a miracle!" +``` + +## 类型声明 + +与 Python 不同的是,只能先声明变量类型。 +当然,声明的类型和实际分配的对象的类型必须兼容。 + +```python +i: Int +i = 10 +``` + +## 函数 + +你可以像在 Haskell 中一样定义它。 + +```python +fib0 = 0 +fib1 = 1 +fibn = fib(n - 1) + fib(n - 2) +``` + +匿名函数可以这样定义: + +```python +i -> i + 1 +assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4] +``` + +## 运算符 + +特定于 Erg 的运算符是: + +### 变异运算符 (!) + +这就像 Ocaml 中的`ref`。 + +```python +i = !0 +i.update! x -> x + 1 +assert i == 1 +``` + +## 程序 + +具有副作用的子例程称为过程,并标有`!`。 + +```python +print! 1 # 1 +``` + +## 泛型函数(多相关) + +```python +id|T|(x: T): T = x +id(1): Int +id("a"): Str +``` + +## 记录 + +您可以使用类似 ML 的语言中的记录等价物(或 JS 中的对象字面量)。 + +```python +p = {x = 1; y = 2} +``` + +## 所有权 + +Ergs 由可变对象(使用 `!` 运算符突变的对象)拥有,并且不能从多个位置重写。 + +```python +i = !0 +j = i +assert j == 0 +i#移动错误 +``` + +另一方面,不可变对象可以从多个位置引用。 + +## 可见性 + +使用 `.` 前缀变量使其成为公共变量并允许从外部模块引用它。 + +```python +# foo.er +.x = 1 +y = 1 +``` + +```python +foo = import "foo" +assert foo.x == 1 +foo.y # 可见性错误 +``` + +## 模式匹配 + +### 变量模式 + +```python +# 基本任务 +i = 1 +# with 类型 +i: Int = 1 +# 函数 +fn x = x + 1 +fn: Int -> Int = x -> x + 1 +``` + +### 文字模式 + +```python +# 如果 `i` 在编译时无法确定为 1,则发生 类型错误 +# 简写:`_ {1} = i` +1 = i +# 简单的模式匹配 +match x: + 1 -> "1" + 2 -> "2" + _ -> "other" +# 斐波那契函数 +fib0 = 0 +fib1 = 1 +fibn: Nat = fibn-1 + fibn-2 +``` + +### 常量模式 + +```python +PI = 3.141592653589793 +E = 2.718281828459045 +num = PI +name = match num: + PI -> "pi" + E -> "e" + _ -> "unnamed" +``` + +### 丢弃(通配符)模式 + +```python +_ = 1 +_: Int = 1 +right(_, r) = r +``` + +### 可变长度模式 + +与稍后描述的元组/数组/记录模式结合使用。 + +```python +[i,...j] = [1, 2, 3, 4] +assert j == [2, 3, 4] +first|T|(fst: T, ...rest: T) = fst +assert first(1, 2, 3) == 1 +``` + +### 元组模式 + +```python +(i, j) = (1, 2) +((k, l), _) = ((1, 2), (3, 4)) +# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) +m, n = 1, 2 +``` + +### 数组模式 + +```python +length[] = 0 +length[_, ...rest] = 1 + lengthrest +``` + +#### 记录模式 + +```python +{sin; cos; tan; ...} = import "math" +{*} = import "math" # 全部导入 + +person = {name = "John Smith"; age = 20} +age = match person: + {name = "Alice"; _} -> 7 + {_; age} -> age +``` + +### 数据类模式 + +```python +Point = Inherit {x = Int; y = Int} +p = Point::{x = 1; y = 2} +Point::{x; y} = p +``` + +## 理解(Comprehensions) + +```python +odds = [i | i <- 1..100; i % 2 == 0] +``` + +## 班级 + +Erg 不支持多级/多级继承。 + +## 特质 + +它们类似于 Rust 特征,但在更字面意义上,允许组合和解耦,并将属性和方法视为平等。 +此外,它不涉及实施。 + +```python +XY = Trait {x = Int; y = Int} +Z = Trait {z = Int} +XYZ = XY and Z +Show = Trait {show: Self.() -> Str} + +@Impl XYZ, Show +Point = Class {x = Int; y = Int; z = Int} +Point. + ... +``` + +## 修补 + +您可以为类和特征提供实现。 + +## 筛子类型 + +谓词表达式可以是类型限制的。 + +```python +Nat = {I: Int | I >= 0} +``` + +## 带值的参数类型(依赖类型) + +```python +a: [Int; 3] +b: [Int; 4] +a + b: [Int; 7] +``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/01_type_system.md b/doc/zh_TW/syntax/type/01_type_system.md new file mode 100644 index 00000000..7ed2b019 --- /dev/null +++ b/doc/zh_TW/syntax/type/01_type_system.md @@ -0,0 +1,228 @@ +# Erg 的类型系统 + +下面简单介绍一下 Erg 的类型系统。 详细信息在其他部分进行说明。 + +## 如何定义 + +Erg 的独特功能之一是(普通)变量、函数(子例程)和类型(Kind)定义之间的语法没有太大区别。 所有都是根据普通变量和函数定义的语法定义的。 + +```python +f i: Int = i + 1 +f # <函数 f> +f(1) # 2 +f.method self = ... # 语法错误:无法为子例程定义方法 + +T I: Int = {...} +T # +T(1) # 类型 T(1) +T.method self = ... +D = Class {private = Int; .public = Int} +D # <类 'D'> +o1 = {private = 1; .public = 2} # o1 是一个不属于任何类的对象 +o2 = D.new {private = 1; .public = 2} # o2 是 D 的一个实例 +o2 = D.new {.public = 2} # 初始化错误:类 'D' 需要属性 'private'(: Int) 但未定义 +``` + +## Classification + +Erg 中的所有对象都是强类型的。 +顶层类型是`{=}`,实现了`__repr__`、`__hash__`、`clone`等(不是必须的方法,这些属性不能被覆盖)。 +Erg 的类型系统包含结构子类型 (SST)。 该系统类型化的类型称为结构类型。 +结构类型主要分为三种:Attributive(属性类型)、Refinement(细化类型)和Algebraic(代数类型)。 + +| | Record | Enum | Interval | Union | Intersection | Diff | +| --------- | ----------- | ---------- | -------------- | ----------- | ------------ | ------------ | +| kind | Attributive | Refinement | Refinement | Algebraic | Algebraic | Algebraic | +| generator | record | set | range operator | or operator | and operator | not operator | + +也可以使用名义子类型(NST),将 SST 类型转换为 NST 类型称为类型的名义化。 结果类型称为名义类型。 +在 Erg 中,名义类型是类和特征。 当我们简单地说类/特征时,我们通常指的是记录类/特征。 + +| | Type | Abstraction | Subtyping procedure | +| --- | -------------- | ---------------- | ------------------- | +| NST | NominalType | Trait | Inheritance | +| SST | StructuralType | Structural Trait | (Implicit) | + +整个名义类型的类型(`NominalType`)和整个结构类型的类型(`StructuralType`)是整个类型(`Type`)的类型的子类型。 + +Erg 可以将参数(类型参数)传递给类型定义。带有类型参数的 `Option`、`Array` 等称为多项式类型。这些本身不是类型,但它们通过应用参数成为类型。诸如 `Int`、`Str` 等没有参数的类型称为简单类型(标量类型)。 + +一个类型可以看成一个集合,并且存在包含关系。例如,“Num”包含“Add”、“Sub”等,“Int”包含“Nat”。 +所有类的上类是`Object == Class {:}`,所有类型的下类是`Never == Class {}`。这在下面描述。 + +## 类型 + +像 `Array T` 这样的类型可以看作是 `Type -> Type` 类型的函数,它以 `T` 类型为参数并返回 `Array T` 类型(在类型论中也称为 Kind)。像 `Array T` 这样的类型专门称为多态类型,而 `Array` 本身称为一元 Kind。 + +已知参数和返回类型的函数的类型表示为`(T, U) -> V`。如果要指定同一类型的整个双参数函数,可以使用 `|T| (T, T) -> T`,如果要指定整个 N 参数函数,可以使用 `Func N`。但是,`Func N` 类型没有关于参数数量或其类型的信息,因此所有返回值在调用时都是`Obj` 类型。 + +`Proc` 类型表示为 `() => Int` 等等。此外,`Proc` 类型实例的名称必须以 `!` 结尾。 + +`Method` 类型是一个函数/过程,其第一个参数是它所属的对象 `self`(通过引用)。对于依赖类型,也可以在应用方法后指定自己的类型。这是 `T!(!N)` 类型和 `T!(N ~> N-1)。 () => Int` 等等。 + +Erg 的数组(Array)就是 Python 所说的列表。 `[诠释; 3]`是一个数组类,包含三个`Int`类型的对象。 + +> __Note__: `(Type; N)` 既是类型又是值,所以可以这样使用。 +> +> ```python. +> Types = (Int, Str, Bool) +> +> for! Types, T => +> print! T +> # Int Str Bool +> a: Types = (1, "aaa", True) +> ``` + +```python +pop|T, N|(l: [T; N]): ([T; N-1], T) = + [...l, last] = l + (l, last) + +lpop|T, N|(l: [T; N]): (T, [T; N-1]) = + [first, ...l] = l + (first, l) +``` + +以 `!` 结尾的类型可以重写内部结构。 例如,`[T; !N]` 类是一个动态数组。 +要从“T”类型的对象创建“T!”类型的对象,请使用一元运算符“!”。 + +```python +i: Int! = !1 +i.update! i -> i + 1 +assert i == 2 +arr = [1, 2, 3] +arr.push! 4 # 导入错误 +mut_arr = [1, 2, 3].into [Int; !3] +mut_arr.push4 +assert mut_arr == [1, 2, 3, 4]. +``` + +## 类型定义 + +类型定义如下。 + +```python +Point2D = {.x = Int; .y = Int} +``` + +请注意,如果从变量中省略 `.`,它将成为类型中使用的私有变量。 但是,这也是必需的属性。 +由于类型也是对象,因此类型本身也有属性。 这样的属性称为类型属性。 在类的情况下,它们也称为类属性。 + +## 数据类型 + +如前所述,Erg 中的“类型”大致表示一组对象。 + +下面是 `Add` 类型的定义,需要 `+`(中间运算符)。 `R, O` 是所谓的类型参数,可以是真正的类型(类),例如 `Int` 或 `Str`。 在其他语言中,类型参数被赋予特殊的符号(泛型、模板等),但在 Erg 中,它们可以像普通参数一样定义。 +类型参数也可以用于类型对象以外的类型。 例如数组类型`[Int; 3]` 是 `Array Int, 3` 的语法糖。 如果类型实现重叠,用户必须明确选择一个。 + +```python +Add R = Trait { + .AddO = Type + . `_+_` = Self.(R) -> Self.AddO +} +``` + +.`_+_`是Add.`_+_`的缩写。 前缀运算符 .`+_` 是 `Num` 类型的方法。 + +```python +Num = Add and Sub and Mul and Eq +NumImpl = Patch Num +NumImpl. + `+_`(self): Self = self + ... +``` + +多态类型可以像函数一样对待。 通过将它们指定为 `Mul Int、Str` 等,它们可以是单态的(在许多情况下,它们是用实际参数推断出来的,而没有指定它们)。 + +```python +1 + 1 +`_+_` 1, 1 +Nat.`_+_` 1, 1 +Int.`_+_` 1, 1 +``` + +前四行返回相同的结果(准确地说,底部的返回 `Int`),但通常使用顶部的。 +`Ratio.`_+_`(1, 1)` 将返回 `2.0` 而不会出错。 +这是因为 `Int <: Ratio`,所以 `1` 向下转换为 `Ratio`。 +但这不是演员。 + +```python +i = 1 +if i: # 类型错误:i:Int 不能转换为 Bool,请改用 Int.is_zero()。 + log "a" + log "b" +``` + +这是因为 `Bool <: Int` (`True == 1`, `False == 0`)。转换为子类型通常需要验证。 + +## 类型推理系统 + +Erg 使用静态鸭子类型,因此几乎不需要显式指定类型。 + +```python +f x, y = x + y +``` + +在上面的代码中,带有 `+` 的类型,即 `Add` 是自动推断的; Erg 首先推断出最小的类型。如果`f 0, 1`,它将推断`f x:{0},y:{1}`,如果`n:Nat; f n, 1`,它会推断`f x: Nat, y: {1}`。最小化之后,增加类型直到找到实现。在 `{0}, {1}` 的情况下,`Nat` 与 `Nat` 是单态的,因为 `Nat` 是具有 `+` 实现的最小类型。 +如果是 `{0}, {-1}`,它与 `Int` 是单态的,因为它不匹配 `Nat`。如果子类型和超类型之间没有关系,则首先尝试具有最低浓度(实例数)(或者在多态类型的情况下参数更少)的那个。 +`{0}` 和 `{1}` 是枚举类型,它们是部分类型,例如 `Int` 和 `Nat`。 +例如,可以为枚举类型指定名称和请求/实现方法。在有权访问该类型的命名空间中,满足请求的对象可以使用实现方法。 + +```python +Binary = Patch {0, 1} +Binary. + # self 包含一个实例。 在此示例中,为 0 或 1。 + # 如果你想重写self,你必须追加! 必须添加到类型名称和方法名称。 + is_zero(self) = match self: + 0 -> True + 1 -> False # 你也可以使用 _ -> False + is_one(self) = not self.is_zero() + to_bool(self) = match self: + 0 -> False + 1 -> True +``` + +此后,代码“0.to_bool()”是可能的(尽管“0 as Bool == False”是内置定义的)。 +这是一个实际上可以重写 `self` 的类型的示例,如代码所示。 + +```python +Binary! = Patch {0, 1}! +Binary! + switch! ref! self = match! self: + 0 => self = 1 + 1 => self = 0 + +b = !1 +b.switch!() +print! b # => 0 +``` + +## 结构类型(匿名类型) + +```python +Binary = {0, 1} +``` + +上面代码中的 `Binary` 是一个类型,其元素是 `0` 和 `1`。 它也是 `Int` 类型的子类型,它同时具有 `0` 和 `1`。 +像 `{}` 这样的对象本身就是一种类型,可以在分配或不分配给上述变量的情况下使用。 +这样的类型称为结构类型。 当我们想强调它作为后者而不是类(命名类型)的用途时,它也被称为未命名类型。 `{0, 1}`这样的结构类型称为枚举类型,还有区间类型、记录类型等。 + +### 类型标识 + +无法指定以下内容。 例如,您不能指定 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int`。 +例如,`Int`和`Str`都是`Add`,但是`Int`和`Str`不能相加。 + +```python +add l: Add, r: Add = + l + r # 类型错误: `_+_` 没有实现: |T, U <: Add| (T, U) -> <失败> +``` + +此外,下面的类型 `A` 和 `B` 不被认为是同一类型。 但是,类型“O”被认为是匹配的 + +```python +... |R1; R2; O; A <: Add(R1, O); B <: Add(R2, O)| +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/type/02_basic.md b/doc/zh_TW/syntax/type/02_basic.md new file mode 100644 index 00000000..adca8428 --- /dev/null +++ b/doc/zh_TW/syntax/type/02_basic.md @@ -0,0 +1,161 @@ +# 类型的基本语法 + +## 类型规范 + +在 Erg 中,可以在 `:` 之后指定变量的类型,如下所示。这可以与作业同时完成。 + +```python +i: Int # 将变量 i 声明为 Int 类型 +i: Int = 1 +j = 1 # 类型说明可以省略 +``` + +您还可以指定普通表达式的类型。 + +```python +i = 1: Int +f([1, "a"]: [Int or Str]) +``` + +对于简单的变量赋值,大多数类型说明可以省略。 +在定义子例程和类型时,类型规范更有用。 + +```python +# 参数的类型规范 +f x, y: Array Int = ... +T X, Y: Array Int = ... +``` + +请注意,在上述情况下,`x, y` 都是 `Array Int`。 + +```python +# 大写变量的值必须是常量表达式 +f X: Int = X +``` + +或者,如果你不需要关于类型参数的完整信息,你可以用 `_` 省略它 + +```python +g v: [T; _] = ... +``` + +但是请注意,类型规范中的 `_` 意味着 `Object`。 + +```python +f x: _, y: Int = x + y # 类型错误:Object 和 Int 之间没有实现 + +``` + +## 子类型规范 + +除了 `:`(类型声明运算符),Erg 还允许您使用 `<:`(部分类型声明运算符)来指定类型之间的关系。 +`<:` 的左边只能指定一个类。 使用 `Subtypeof` 或类似的运算符来比较结构类型。 + +这也经常在定义子例程或类型时使用,而不是简单地指定变量。 + +```python +# 参数的子类型规范 +f X <: T = ... + +# 所需属性的子类型规范(.Iterator 属性必须是 Iterator 类型的子类型) +Iterable T = Trait { + .Iterator = {Iterator} # {Iterator} == {I: Type | I <: Iterator} + .iter = Self.() -> Self.Iterator T + ... +} +``` + +也可以在定义类时使用子类型规范来静态检查该类是否是指定类型的子类型。 + +```python +# C 类是 Show 的子类型 +C = Class Object, Impl := Show +C.show self = ... # 显示所需的属性。 +``` + +您也可以仅在特定情况下指定子类型 + +```python +K T: Eq +K Int <: Show and Eq +K T = Class Object +K(T). + `==` self, other = ... +K(Int). + show self = ... +``` + +实现结构类型时建议使用子类型规范。 +这是因为,由于结构子类型的性质,拼写错误或类型规范错误在实现所需属性时不会导致错误 + +```python +C = Class Object +C.shoe self = ... # Show 由于 Typo 没有实现(它被认为只是一种独特的方法) +``` + +## 属性定义 + +只能在模块中为特征和类定义属性 + +```python +C = Class() +C.pub_attr = "this is public" +C::private_attr = "this is private" + +c = C.new() +assert c.pub_attr == "this is public" +``` + +定义批处理定义的语法称为批处理定义,其中在 `C.` 或 `C::` 之后添加换行符,并且定义在缩进下方组合在一起 + +```python +C = Class() +C.pub1 = ... +C.pub2 = ... +C::priv1 = ... +C::priv2 = ... +# 相当于 +C = Class() +C. + pub1 = ... + C. pub2 = ... +C:: + priv1 = ... + priv2 = ... +``` + +## 别名 + +类型可以有别名。 这允许缩短长类型,例如记录类型 + +```python +Id = Int +Point3D = {x = Int; y = Int; z = Int} +IorS = Int or Str +Vector = Array Int +``` + +此外,当显示错误时,如果定义了复合类型(在上面的示例中,右侧类型不是第一个类型),编译器将为它们使用别名。 + +但是,每个模块只允许一个相同类型的别名,多个别名将导致警告。 +这意味着应将具有不同用途的类型定义为单独的类型。 +目的还在于防止在已经具有别名的类型之上添加别名。 + +```python +Id = Int +UserId = Int # 类型警告:重复别名:Id 和 UserId + +Ids = Array Id +Ints = Array Int # 类型警告:重复别名:Isd 和 Ints + +IorS = Int or Str +IorSorB = IorS or Bool +IorSorB_ = Int or Str or Bool # 类型警告:重复别名:IorSorB 和 IorSorB_ + +Point2D = {x = Int; y = Int} +Point3D = {.... Point2D; z = Int} +Point = {x = Int; y = Int; z = Int} # 类型警告:重复别名:Point3D 和 Point +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/type/03_trait.md b/doc/zh_TW/syntax/type/03_trait.md new file mode 100644 index 00000000..0fbca1ef --- /dev/null +++ b/doc/zh_TW/syntax/type/03_trait.md @@ -0,0 +1,187 @@ +# 特质 + +Trait 是一种名义类型,它将类型属性要求添加到记录类型。 +它类似于 Python 中的抽象基类 (ABC),但区别在于能够执行代数运算。 + +```python +Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int} +``` + +特质不区分属性和方法。 + +注意,trait 只能声明,不能实现(实现是通过一个叫做 patching 的特性来实现的,后面会讨论)。 +可以通过指定部分类型来检查特征在类中的实现。 + +```python +Point2D <: Norm +Point2D = Class {.x = Int; .y = Int} +Point2D.norm self = self.x**2 + self.y**2 +``` + +Error if the required attributes are not implemented. + +```python +Point2D <: Norm # 类型错误:Point2D 不是 Norm 的子类型 +Point2D = Class {.x = Int; .y = Int} +``` + +特征与结构类型一样,可以应用组合、替换和消除等操作(例如“T 和 U”)。 由此产生的特征称为即时特征。 + +```python +T = Trait {.x = Int} +U = Trait {.y = Int} +V = Trait {.x = Int; y: Int} +assert Structural(T and U) == Structural V +assert Structural(V not U) == Structural T +W = Trait {.x = Ratio} +assert Structural(W) ! = Structural(T) +assert Structural(W) == Structural(T.replace {.x = Ratio}) +``` + +Trait 也是一种类型,因此可以用于普通类型规范 + +```python +points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)] +assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25]. +``` + +## 特征包含 + +扩展运算符 `...` 允许您将包含某个特征的特征定义为超类型。 这称为特征的 __subsumption__。 +在下面的示例中,`BinAddSub` 包含 `BinAdd` 和 `BinSub`。 +这对应于类中的继承,但与继承不同的是,可以使用“和”组合多个基类型。 也允许被 `not` 部分排除的特征。 + +```python +Add R = Trait { + .AddO = Type + . `_+_` = Self.(R) -> Self.AddO +} + +Sub R = Trait { + .SubO = Type + . `_-_` = Self.(R) -> Self.SubO +} + +BinAddSub = Subsume Add(Self) and Sub(Self) +``` + +## 结构特征 + +特征可以结构化 + +```python +SAdd = Structural Trait { + . `_+_` = Self.(Self) -> Self +} +# |A <: SAdd| 不能省略 +add|A <: SAdd| x, y: A = x.`_+_` y + +C = Class {i = Int} +C. + new i = Self.__new__ {i;} + `_+_` self, other: Self = Self.new {i = self::i + other::i} + +assert add(C.new(1), C.new(2)) == C.new(3) +``` + +名义特征不能简单地通过实现请求方法来使用,而必须明确声明已实现。 +在以下示例中,`add`不能与`C`类型的参数一起使用,因为没有明确的实现声明。 它必须是`C = Class {i = Int}, Impl := Add`。 + +```python +Add = Trait { + .`_+_` = Self.(Self) -> Self +} +# |A <: 添加| 可以省略 +add|A <: Add| x, y: A = x.`_+_` y + +C = Class {i = Int} +C. + new i = Self.__new__ {i;} + `_+_` self, other: Self = Self.new {i = self::i + other::i} + +add C.new(1), C.new(2) # 类型错误:C 不是 Add 的子类 +# 提示:继承或修补“添加” +``` + +不需要为此实现声明结构特征,但类型推断不起作用。 使用时需要指定类型。 + +## 多态特征 + +特征可以带参数。 这与多态类型相同。 + +```python +Mapper T: Type = Trait { + .mapIter = {Iterator} + .map = Self(T). (T -> U) -> Self.MapIter U +} + +# ArrayIterator <: Mapper +# ArrayIterator.MapIter == ArrayMapper +# [1, 2, 3].iter(): ArrayIterator Int +# [1, 2, 3].iter().map(x -> "{x}"): ArrayMapper Str +assert [1, 2, 3].iter().map(x -> "{x}").collect(Array) == ["1", "2", "3"]. +``` + +## Override特征 + +派生特征可以Override基本特征的类型定义。 +在这种情况下,Override方法的类型必须是基方法类型的子类型。 + +```python +# `Self.(R) -> O` is a subtype of ``Self.(R) -> O or Panic +Div R, O: Type = Trait { + . `/` = Self.(R) -> O or Panic +} +SafeDiv R, O = Subsume Div, { + @Override + . `/` = Self.(R) -> O +} +``` + +## 在 API 中实现和解决重复的特征 + +`Add`、`Sub` 和 `Mul` 的实际定义如下所示。 + +```python +Add R = Trait { + .Output = Type + . `_+_` = Self.(R) -> .Output +} +Sub R = Trait { + .Output = Type + . `_-_` = Self.(R) -> .Output +} +Mul R = Trait { + .Output = Type + . `*` = Self.(R) -> .Output +} +``` + +`.Output` 重复。 如果要同时实现这些多个特征,请指定以下内容 + +```python +P = Class {.x = Int; .y = Int} +# P|Self <: Add(P)|可简写为 P|<: Add(P)| +P|Self <: Add(P)|. + Output = P + `_+_` self, other = P.new {.x = self.x + other.x; .y = self.y + other.y} +P|Self <: Mul(Int)|. + Output = P + `*` self, other = P.new {.x = self.x * other; .y = self.y * other} +``` + +以这种方式实现的重复 API 在使用时几乎总是类型推断,但也可以通过使用 `||` 显式指定类型来解决。 + +```python +print! P.Output # 类型错误:不明确的类型 +print! P|<: Mul(Int)|.Output # +``` + +## 附录:与 Rust 特征的区别 + +Erg 的特征忠实于 [Schärli 等人] (https://www.ptidej.net/courses/ift6251/fall06/presentations/061122/061122.doc.pdf) 提出的特征。 +为了允许代数运算,特征被设计为不能有方法实现目录,但可以在必要时进行修补。 + +

+ 上一页 | 下一步 +

\ No newline at end of file diff --git a/doc/zh_TW/syntax/type/04_class.md b/doc/zh_TW/syntax/type/04_class.md new file mode 100644 index 00000000..a95fabe5 --- /dev/null +++ b/doc/zh_TW/syntax/type/04_class.md @@ -0,0 +1,287 @@ +# Class + +Erg 中的类大致是一种可以创建自己的元素(实例)的类型。 +这是一个简单类的示例。 + +```python +Person = Class {.name = Str; .age = Nat} +# 如果 `.new` 没有定义,那么 Erg 将创建 `Person.new = Person::__new__` +Person. + new name, age = Self::__new__ {.name = name; .age = age} + +john = Person.new "John Smith", 25 +print! john # +print! classof(john) # Person +``` + +赋予“Class”的类型(通常是记录类型)称为需求类型(在本例中为“{.name = Str; .age = Nat}”)。 +可以使用 `::__new__ { = ; 创建实例 ...}` 可以创建。 +`{.name = "约翰·史密斯"; .age = 25}` 只是一条记录,但它通过传递 `Person.new` 转换为 `Person` 实例。 +创建此类实例的子例程称为构造函数。 +在上面的类中,`.new` 方法被定义为可以省略字段名等。 + +请注意,以下不带换行符的定义将导致语法错误。 + +```python +Person.new name, age = ... # 语法错误:不能直接在对象上定义属性 +``` + +> __Warning__:这是最近添加的规范,后续文档中可能不会遵循。 如果你发现它,请报告它。 + +## 实例和类属性 + +在 Python 和其他语言中,实例属性通常在块侧定义如下,但请注意,这样的写法在 Erg 中具有不同的含义。 + +```python +# Python +class Person: + name: str + age: int +``` + +```python +# 在Erg中,这个符号意味着类属性的声明(不是实例属性) +Person = Class() +Person. + name: Str + age: Int +``` + +```python +# 以上 Python 代码的 Erg 代码 +Person = Class { + .name = Str + .age = Nat +} +``` + +元素属性(在记录中定义的属性)和类型属性(也称为实例/类属性,尤其是在类的情况下)是完全不同的东西。 类型属性是类型本身的属性。 当一个类型的元素本身没有所需的属性时,它指的是一个类型属性。 元素属性是元素直接拥有的唯一属性。 +为什么要进行这种区分? 如果所有属性都是元素属性,那么在创建对象时复制和初始化所有属性将是低效的。 +此外,以这种方式划分属性明确了诸如“该属性是共享的”和“该属性是分开持有的”之类的角色。 + +下面的例子说明了这一点。 `species` 属性对所有实例都是通用的,因此将其用作类属性更自然。 但是,属性 `name` 应该是实例属性,因为每个实例都应该单独拥有它。 + +```python +Person = Class {name = Str} +Person:: + species = "human" +Person. + describe() = + log "species: {species}" + greet self = + log "Hello, My name is {self::name}." + +Person.describe() # 类型:Person +Person.greet() # 类型错误: 未绑定的方法 Person.greet 需要一个参数 + +john = Person.new {name = "John"} +john.describe() # 类型: human +john.greet() # 你好,我是约翰 + +alice = Person.new {name = "Alice"} +alice.describe() # 类型: human +alice.greet() # 你好,我是爱丽丝 +``` + +顺便说一下,如果实例属性和类型属性具有相同的名称和相同的类型,则会发生编译错误。 这是为了避免混淆。 + +```python +C = Class {.i = Int} +C.i = 1 # 属性错误:`.i` 已在实例字段中定义 +``` + +## 类(Class), 类型(Type) + +请注意,`1` 的类和类型是不同的。 +只有一个类 `Int` 是 `1` 的生成器。 可以通过`classof(obj)`或`obj.__class__`获取对象所属的类。 +相比之下,`1`有无数种。 例如,`{1}, {0, 1}, 0..12, Nat, Int, Num`。 +但是,可以将最小类型定义为单一类型,在本例中为“{1}”。 可以通过`Typeof(obj)`获取对象所属的类型。 这是一个编译时函数。 +对象可以使用补丁方法以及类方法。 +Erg 不允许您添加类方法,但您可以使用 [patch](./07_patch.md) 来扩展类。 + +您还可以从现有类([Inheritable](./../27_decorator.md/#inheritable) 类)继承。 +您可以使用 `Inherit` 创建一个继承类。 左侧的类型称为派生类,右侧的“继承”的参数类型称为基类(继承类)。 + +```python +MyStr = Inherit Str +# other: 如果你设置 ``other: Str'',你可以使用 MyStr。 +MyStr. + `-` self, other: Str = self.replace other, "" + +abc = MyStr.new("abc") +# 这里的比较是向上的 +assert abc - "b" == "ac" +``` + +与 Python 不同,默认情况下,定义的 Erg 类是 `final`(不可继承的)。 +要使类可继承,必须将 `Inheritable` 装饰器附加到该类。 +Str` 是可继承的类之一。 + +```python +MyStr = Inherit Str # OK +MyStr2 = Inherit MyStr # NG + +@Inheritable +InheritableMyStr = Inherit Str +MyStr3 = Inherit InheritableMyStr # OK +``` + +`Inherit Object` 和 `Class()` 在实践中几乎是等价的。 一般使用后者。 + +类具有与类型不同的等价检查机制。 +类型基于其结构进行等效性测试。 + +```python +Person = {.name = Str; .age = Nat} +Human = {.name = Str; .age = Nat} + +assert Person == Human +``` + +class has no equivalence relation defined. + +```python +Person = Class {.name = Str; .age = Nat} +Human = Class {.name = Str; .age = Nat} + +Person == Human # 类型错误:无法比较类 +``` + +## 与结构类型的区别 + +我们说过类是一种可以生成自己的元素的类型,但这并不是严格的描述。 事实上,一个记录类型+补丁可以做同样的事情。 + +```python +Person = {.name = Str; .age = Nat} +PersonImpl = Patch Person +PersonImpl. + new name, age = {.name; .age} + +john = Person.new("John Smith", 25) +``` + +使用类有四个优点。 +第一个是构造函数经过有效性检查,第二个是它的性能更高,第三个是您可以使用符号子类型(NST),第四个是您可以继承和覆盖。 + +我们之前看到记录类型 + 补丁也可以定义一个构造函数(某种意义上),但这当然不是一个合法的构造函数。 这当然不是一个合法的构造函数,因为它可以返回一个完全不相关的对象,即使它调用自己`.new`。 在类的情况下,`.new` 被静态检查以查看它是否生成满足要求的对象。 + +~ + +类的类型检查只是检查对象的`。 __class__` 对象的属性。 因此可以快速检查一个对象是否属于一个类型。 + +~ + +Erg 在课堂上启用 NST; NST 的优点包括健壮性。 +在编写大型程序时,经常会出现对象的结构巧合匹配的情况。 + +```python +Dog = {.name = Str; .age = Nat} +DogImpl = Patch Dog +DogImpl. + bark = log "Yelp!" +... +Person = {.name = Str; .age = Nat} +PersonImpl = Patch Person +PersonImpl. + greet self = log "Hello, my name is {self.name}." + +john = {.name = "John Smith"; .age = 20} +john.bark() # "Yelp!" +``` + +`Dog` 和 `Person` 的结构完全一样,但让动物打招呼,让人类吠叫显然是无稽之谈。 +前者是不可能的,所以让它不适用更安全。 在这种情况下,最好使用类。 + +```python +Dog = Class {.name = Str; .age = Nat} +Dog.bark = log "Yelp!" +... +Person = Class {.name = Str; .age = Nat} +Person.greet self = log "Hello, my name is {self.name}." + +john = Person.new {.name = "John Smith"; .age = 20} +john.bark() # 类型错误: `Person` 对象没有方法 `.bark`。 +``` + +另一个特点是补丁添加的类型属性是虚拟的,实现类不作为实体保存。 +也就是说,`T.x`、`T.bar` 是可以通过与 `{i = Int}` 兼容的类型访问(编译时绑定)的对象,并且未在 `{i = Int}` 或 ` C`。 +相反,类属性由类本身持有。 因此,它们不能被不处于继承关系的类访问,即使它们具有相同的结构。 + +```python +C = Class {i = Int} +C. + foo self = ... +print! dir(C) # ["foo", ...]. + +T = Patch {i = Int} +T. + x = 1 + bar self = ... +print! dir(T) # ["bar", "x", ...]. +assert T.x == 1 +assert {i = 1}.x == 1 +print! T.bar # <函数 bar> +{i = Int}.bar # 类型错误:Record({i = Int}) 没有方法 `.bar`。 +C.bar # 类型错误:C 没有方法 `.bar` 打印! +print! {i = 1}.bar # <方法 bar> +C.new({i = 1}).bar # <方法 bar> +``` + +## 与数据类的区别 + +有两种类型的类:常规类,通过`Class`成为记录类,以及从记录类继承(`Inherit`)的数据类。 +数据类继承了记录类的功能,具有分解赋值、默认实现的`==`和`hash`等特性。另一方面,数据类有自己的等价关系和格式展示。 +另一方面,如果要定义自己的等价关系或格式显示,则应使用普通类。 + +```python +C = Class {i = Int} +c = C.new {i = 1} +d = C.new {i = 2} +print! c # +c == d # 类型错误:`==` 没有为 `C` 实现 + +D = Inherit {i = Int} +e = D.new {i = 1} +f = D.new {i = 2} +print! e # D{i = 1} +assert e ! = f +``` + +## 枚举类 + +为了便于定义“Or”类型的类,提供了一个“Enum”。 + +```python +X = Class() +Y = Class() +XorY = Enum X, Y +``` + +每种类型都可以通过`XorY.X`、`XorY.Y`来访问,构造函数可以通过`XorY.cons(X)`获得。 +`.cons` 是一个接受类并返回其构造函数的方法。 + +```python +x1 = XorY.new X.new() +x2 = XorY.cons(X)() +assert x1 == x2 +``` + +## 类关系 + +类是需求类型的子类型。 类中可以使用需求类型的方法(包括补丁方法)。 + +```python +T = Trait {.foo = Foo} +C = Class(... , impl: T) +C. + foo = foo + bar x = ... +assert C < T +assert C.foo == foo +assert not T < C +assert T.foo == Foo +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/type/05_inheritance.md b/doc/zh_TW/syntax/type/05_inheritance.md new file mode 100644 index 00000000..c4efa961 --- /dev/null +++ b/doc/zh_TW/syntax/type/05_inheritance.md @@ -0,0 +1,253 @@ +# 继承 + +继承允许您定义一个新类,为现有类添加功能或专业化。 +继承类似于包含在特征中。 继承的类成为原始类的子类型。 + +```python +NewInt = Inherit Int +NewInt. + plus1 self = self + 1 + +assert NewInt.new(1).plus1() == 2 +assert NewInt.new(1) + NewInt.new(1) == 2 +``` + +如果你希望新定义的类是可继承的,你必须给它一个 `Inheritable` 装饰器。 + +您可以指定一个可选参数 `additional` 以允许该类具有其他实例属性,但前提是该类是一个值类。 但是,如果类是值类,则不能添加实例属性。 + +```python +@Inheritable +Person = Class {name = Str} +Student = Inherit Person, additional: {id = Int} + +john = Person.new {name = "John"} +alice = Student.new {name = "Alice", id = 123} + +MailAddress = Inherit Str, additional: {owner = Str} # 类型错误:实例变量不能添加到值类中 +``` + +Erg 的特殊设计不允许继承“Never”类型。 Erg 的特殊设计不允许继承 `Never` 类型,因为 `Never` 是一个永远无法实例化的独特类。 + +## 枚举类的继承 + +[Or 类型](./13_algebraic.md) 也可以被继承。 在这种情况下,您可以通过指定可选参数 `Excluding` 来删除任何选项(可以使用 `or` 进行多项选择)。 +不能添加其他选项。 添加选项的类不是原始类的子类型。 + +```python +Number = Class Int or Float or Complex +Number.abs(self): Float = + match self: + i: Int -> i.abs().into Float + f: Float -> f.abs() + c: Complex -> c.abs().into Float + +# c: 复杂不能出现在匹配选项中 +RealNumber = Inherit Number, Excluding: Complex +``` + +同样,也可以指定[细化类型](./12_refinement.md)。 + +```python +Months = Class 0..12 +MonthsNot31Days = Inherit Months, Excluding: {1, 3, 5, 7, 8, 10, 12} + +StrMoreThan3 = Class StrWithLen N | N >= 3 +StrMoreThan4 = Inherit StrMoreThan3, Excluding: StrWithLen N | N == 3 +``` + +## 覆盖 + +该类与补丁相同,可以将新方法添加到原始类型,但可以进一步“覆盖”该类。 +这种覆盖称为覆盖。要覆盖,必须满足三个条件。 +首先,覆盖必须有一个 `Override` 装饰器,因为默认情况下它会导致错误。 +另外,覆盖不能改变方法的类型。它必须是原始类型的子类型。 +如果你重写了一个被另一个方法引用的方法,你也必须重写所有被引用的方法。 + +为什么这个条件是必要的?这是因为重写不仅会改变一种方法的行为,而且可能会影响另一种方法的行为。 + +让我们从第一个条件开始。此条件是为了防止“意外覆盖”。 +换句话说,必须使用 `Override` 装饰器来防止派生类中新定义的方法的名称与基类的名称冲突。 + +接下来,考虑第二个条件。这是为了类型一致性。由于派生类是基类的子类型,因此它的行为也必须与基类的行为兼容。 + +最后,考虑第三个条件。这种情况是 Erg 独有的,在其他面向对象语言中并不常见,同样是为了安全。让我们看看如果不是这种情况会出现什么问题。 + +```python +# 反面示例 +@Inheritable +Base! = Class {x = Int!} +Base! + f! ref! self = + print! self::x + self.g!() + g! ref! self = self::x.update! x -> x + 1 + +Inherited! = Inherit Base! +Inherited! + @Override + g! ref! self = self.f!() # 无限递归警告:此代码陷入无限循环 + # 覆盖错误:方法 `.g` 被 `.f` 引用但未被覆盖 +``` + +在继承类 `Inherited!` 中,`.g!` 方法被重写以将处理转移到 `.f!`。 但是,基类中的 `.f!` 方法会将其处理转移到 `.g!`,从而导致无限循环。 `.f` 是 `Base!` 类中的一个没有问题的方法,但它被覆盖以一种意想不到的方式使用,并且被破坏了。 + +Erg 已将此规则构建到规范中。 + +```python +# OK. +@Inheritable +Base! = Class {x = Int!} +Base! + f! ref! self = + print! self::x + self.g!() + g! ref! self = self::x.update! x -> x + 1 + +Inherited! = Inherit Base! +Inherited! + @Override + f! ref! self = + print! self::x + self::x.update! x -> x + 1 + @Override + g! ref! self = self.f!() +``` + +然而,这个规范并没有完全解决覆盖问题。 然而,这个规范并没有完全解决覆盖问题,因为编译器无法检测覆盖是否解决了问题。 +创建派生类的程序员有责任纠正覆盖的影响。 只要有可能,尝试定义一个别名方法。 + +### 替换特征(或看起来像什么) + +尽管无法在继承时替换特征,但有一些示例似乎可以这样做。 + +例如,`Int`,`Real` 的子类型(实现了 `Add()`),似乎重新实现了 `Add()`。 + +```python +Int = Class ... , Impl := Add() and ... +``` + +但实际上 `Real` 中的 `Add()` 代表 `Add(Real, Real)`,而在 `Int` 中它只是被 `Add(Int, Int)` 覆盖。 +它们是两个不同的特征(`Add` 是一个 [covariate](./advanced/variance.md),所以`Add(Real, Real) :> Add(Int, Int)`)。 + +## 多重继承 + +Erg 不允许普通类之间的交集、差异和互补。 +```python +Int and Str # 类型错误:无法合并类 +``` + +该规则防止从多个类继承,即多重继承。 + +```python +IntAndStr = Inherit Int and Str # 语法错误:不允许类的多重继承 +``` + +但是,可以使用多个继承的 Python 类。 + +## 多层(多级)继承 + +Erg 继承也禁止多层继承。 也就是说,您不能定义从另一个类继承的类。 +从“Object”继承的可继承类可能会异常继承。 + +同样在这种情况下,可以使用 Python 的多层继承类。 + +## 重写继承的属性 + +Erg 不允许重写从基类继承的属性。 这有两个含义。 + +第一个是对继承的源类属性的更新操作。 例如,它不能重新分配,也不能通过 `.update!` 方法更新。 + +覆盖与重写不同,因为它是一种用更专业的方法覆盖的操作。 覆盖也必须替换为兼容的类型。 + +```python +@Inheritable +Base! = Class {.pub = !Int; pri = !Int} +Base! + var = !1 + inc_pub! ref! self = self.pub.update! p -> p + 1 + +Inherited! = Inherit Base! +Inherited! + var.update! v -> v + 1 + # 类型错误:不能更新基类变量 + @Override + inc_pub! ref! self = self.pub + 1 + # 覆盖错误:`.inc_pub!` 必须是 `Self! 的子类型! () => ()` +``` + +第二个是对继承源的(变量)实例属性的更新操作。 这也是被禁止的。 基类的实例属性只能从基类提供的方法中更新。 +无论属性的可见性如何,都无法直接更新。 但是,它们可以被读取。 + +```python +@Inheritable +Base! = Class {.pub = !Int; pri = !Int} +Base! + inc_pub! ref! self = self.pub.update! p -> p + 1 + inc_pri! ref! self = self::pri.update! p -> p + 1 + +self = self.pub.update! +Inherited! + # OK + add2_pub! ref! self = + self.inc_pub!() + self.inc_pub!() + # NG, `Child` 不能触摸 `self.pub` 和 `self::pri`。 + add2_pub! ref! self = + self.pub.update! p -> p + 2 +``` + +毕竟 Erg 继承只能添加新的属性和覆盖基类的方法。 + +## 使用继承 + +虽然继承在正确使用时是一项强大的功能,但它也有一个缺点,即它往往会使类依赖关系复杂化,尤其是在使用多层或多层继承时。复杂的依赖关系会降低代码的可维护性。 +Erg 禁止多重和多层继承的原因是为了降低这种风险,并且引入了类补丁功能以降低依赖关系的复杂性,同时保留继承的“添加功能”方面。 + +那么,反过来说,应该在哪里使用继承呢?一个指标是何时需要“基类的语义子类型”。 +Erg 允许类型系统自动进行部分子类型确定(例如,Nat,其中 Int 大于或等于 0)。 +但是,例如,仅依靠 Erg 的类型系统很难创建“表示有效电子邮件地址的字符串类型”。您可能应该对普通字符串执行验证。然后,我们想为已通过验证的字符串对象添加某种“保证”。这相当于向下转换为继承的类。将 `Str object` 向下转换为 `ValidMailAddressStr` 与验证字符串是否采用正确的电子邮件地址格式是一一对应的。 + +```python +ValidMailAddressStr = Inherit Str +ValidMailAddressStr. + init s: Str = + validate s # 邮件地址验证 + Self.new s + +s1 = "invalid mail address" +s2 = "foo@gmail.com" +_ = ValidMailAddressStr.init s1 # 恐慌:无效的邮件地址 +valid = ValidMailAddressStr.init s2 +valid: ValidMailAddressStr # 确保电子邮件地址格式正确 +``` + +另一个指标是您何时想要实现名义多态性。 +例如,下面定义的 `greet!` 过程将接受任何类型为 `Named` 的对象。 +但显然应用 `Dog` 类型的对象是错误的。 所以我们将使用 `Person` 类作为参数类型。 +这样,只有 `Person` 对象、从它们继承的类和 `Student` 对象将被接受为参数。 +这是比较保守的,避免不必要地承担过多的责任。 + +```python +Named = {name = Str; ...} +Dog = Class {name = Str; breed = Str} +Person = Class {name = Str} +Student = Inherit Person, additional: {id = Int} +structural_greet! person: Named = + print! "Hello, my name is {person::name}." +greet! person: Person = + print! "Hello, my name is {person::name}." + +max = Dog.new {name = "Max", breed = "Labrador"} +john = Person.new {name = "John"} +alice = Student.new {name = "Alice", id = 123} + +structural_greet! max # 你好,我是马克斯 +structural_greet! john # 你好,我是约翰 +greet! alice # 你好,我是爱丽丝 +greet! max # 类型错误: +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/type/06_nst_vs_sst.md b/doc/zh_TW/syntax/type/06_nst_vs_sst.md new file mode 100644 index 00000000..7d0393eb --- /dev/null +++ b/doc/zh_TW/syntax/type/06_nst_vs_sst.md @@ -0,0 +1,43 @@ +# 名义子类型与结构子类型 + +```python +Months = 0..12 + +# NST +MonthsClass = Class Months +MonthsClass. + name self = + match self: + 1 -> "january" + 2 -> "february" + 3 -> "march" + ... + +# SST +MonthsImpl = Patch Months +MonthsImpl. + name self = + match self: + 1 -> "January" + 2 -> "February" + 3 -> "March" + ... + +assert 12 in Months +assert 2.name() == "February" +assert not 12 in MonthsClass +assert MonthsClass.new(12) in MonthsClass +# 它可以使用结构类型,即使包装在一个类中。 +assert MonthsClass.new(12) in Months +# 如果两者都存在,则类方法优先 +assert MonthsClass.new(2).name() == "february" +``` + +## 最后,我应该使用哪个,NST 还是 SST? + +如果您无法决定使用哪一个,我们的建议是 NST。 +SST 需要抽象技能来编写在任何用例中都不会崩溃的代码。 好的抽象可以带来高生产力,但错误的抽象(外观上的共性)会导致适得其反的结果。(NST 可以通过故意将抽象保持在最低限度来降低这种风险。如果您不是库实现者,那么仅使用 NST 进行编码并不是一个坏主意。 + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/type/07_patch.md b/doc/zh_TW/syntax/type/07_patch.md new file mode 100644 index 00000000..20adf0c8 --- /dev/null +++ b/doc/zh_TW/syntax/type/07_patch.md @@ -0,0 +1,222 @@ +# 修补 + +Erg 不允许修改现有类型和类。 +这意味着,不可能在类中定义额外的方法,也不能执行特化(一种语言特性,单态化多态声明的类型并定义专用方法,如在 C++ 中)。 +但是,在许多情况下,您可能希望向现有类型或类添加功能,并且有一个称为“修补”的功能允许您执行此操作。 + +```python +StrReverse = Patch Str +StrReverse. + reverse self = self.iter().rev().collect(Str) + +assert "abc".reverse() == "cba" +``` + +补丁的名称应该是要添加的主要功能的简单描述。 +这样,被修补类型的对象(`Str`)可以使用修补程序的方法(`StrReverse`)。 +实际上,内置方法`.reverse`并不是`Str`的方法,而是`StrRReverse`中添加的方法。 + +但是,补丁方法的优先级低于名义类型(类/特质)的方法,并且不能覆盖现有类型。 + +```python +StrangeInt = Patch Int +StrangeInt. + `_+_` = Int.`_-_` # 赋值错误:. `_+_` 已在 Int 中定义 +``` + +如果要覆盖,则必须从类继承。 +但是,基本上建议不要覆盖并定义具有不同名称的方法。 +由于一些安全限制,覆盖不是很容易做到。 + +```python +StrangeInt = Inherit Int +StrangeInt. +# 覆盖方法必须被赋予覆盖装饰器。 + # 另外,你需要覆盖所有依赖于 Int.`_+_` 的 Int 方法。 + @Override + `_+_` = Super.`_-_` # OverrideError: Int.`_+_` 被 ... ````` 引用,所以这些方法也必须被覆盖 +``` + +## 选择修补程序 + +可以为单一类型定义修复程序,并且可以组合在一起。 + +```python +# foo.er + +StrReverse = Patch(Str) +StrReverse. + reverse self = ... +StrMultiReplace = Patch(Str) +StrMultiReverse. + multi_replace self, pattern_and_targets: [(Pattern, Str)] = ... +StrToCamelCase = Patch(Str) +StrToCamelCase. + to_camel_case self = ... +StrToKebabCase = Patch(Str) +StrToKebabCase. + to_kebab_case self = ... + +StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase +StrBoosterPack = StrReverse and StrMultiReplace and StrToCamelCase and StrToKebabCase +``` + +```python +{StrBoosterPack; ...} = import "foo" + +assert "abc".reverse() == "cba" +assert "abc".multi_replace([("a", "A"), ("b", "B")]) == "ABc" +assert "to camel case".to_camel_case() == "toCamelCase" +assert "to kebab case".to_kebab_case() == "to-kebab-case" +``` + +如果定义了多个修复程序,其中一些可能会导致重复实施 + +```python +# foo.er + +StrReverse = Patch(Str) +StrReverse. + reverse self = ... +# 更高效的实现 +StrReverseMk2 = Patch(Str) +StrReverseMk2. + reverse self = ... + +"hello".reverse() # 补丁选择错误: `.reverse` 的多个选择: StrReverse, StrReverseMk2 +``` + +在这种情况下,您可以使用 __related function__ 形式而不是方法形式使其唯一 + +```python +assert StrReverseMk2.reverse("hello") == "olleh" +``` + +You can also make it unique by selectively importing. + +```python +{StrReverseMk2; ...} = import "foo" + +assert "hello".reverse() == "olleh" +``` + +## 胶水补丁 + +维修程序也可以将类型相互关联。 `StrReverse` 补丁涉及 `Str` 和 `Reverse`。 +这样的补丁称为 __glue patch__。 +因为 `Str` 是内置类型,所以用户需要使用胶水补丁来改造特征。 + +```python +Reverse = Trait { + .reverse = Self.() -> Self +} + +StrReverse = Patch Str, Impl := Reverse +StrReverse. + reverse self = + self.iter().rev().collect(Str) +``` + +每个类型/特征对只能定义一个胶水补丁。 +这是因为如果多个胶水修复程序同时“可见”,就不可能唯一确定选择哪个实现。 +但是,当移动到另一个范围(模块)时,您可以交换维修程序。 + +```python +NumericStr = Inherit Str +NumericStr. + ... + +NumStrRev = Patch NumericStr, Impl := Reverse +NumStrRev. + ... +# 重复修补程序错误:数值Str已与“反向”关联` +# 提示:'Str'(NumericStr'的超类)通过'StrReverse'与'Reverse'关联 +``` + +## 附录:与 Rust 特征的关系 + +Erg 修复程序相当于 Rust 的(改造的)`impl` 块。 + +```rust +// Rust +trait Reverse { + fn reverse(self) -> Self; +} + +impl Reverse for String { + fn reverse(self) -> Self { + self.chars().rev().collect() + } +} +``` + +可以说,Rust 的特征是 Erg 的特征和修复程序的特征。 这使得 Rust 的特征听起来更方便,但事实并非如此。 + +```python +# Erg +Reverse = Trait { + .reverse = Self.() -> Self +} + +StrReverse = Patch(Str, Impl := Reverse) +StrReverse. + reverse self = + self.iter().rev().collect(Str) +``` + +因为 impl 块在 Erg 中被对象化为补丁,所以在从其他模块导入时可以选择性地包含。 作为副作用,它还允许将外部特征实现到外部结构。 +此外,结构类型不再需要诸如 `dyn trait` 和 `impl trait` 之类的语法。 + +```python +# Erg +reversible: [Reverse; 2] = [[1, 2, 3], "hello"] + +iter|T|(i: Iterable T): Iterator T = i.iter() +``` + +```rust +// Rust +let reversible: [Box; 2] = [Box::new([1, 2, 3]), Box::new("hello")]; + +fn iter(i: I) -> impl Iterator where I: IntoIterator { + i.into_iter() +} +``` + +## 通用补丁 + +补丁不仅可以为一种特定类型定义,还可以为“一般功能类型”等定义。 +在这种情况下,要给出自由度的项作为参数给出(在下面的情况下,`T:Type`)。 以这种方式定义的补丁称为全对称补丁。 +如您所见,全对称补丁正是一个返回补丁的函数,但它本身也可以被视为补丁。 + +```python +FnType T: Type = Patch(T -> T) +FnType(T). + type = T + +assert (Int -> Int).type == Int +``` + +## 结构补丁 + +此外,可以为满足特定结构的任何类型定义修复程序。 +但是,这比名义上的维修程序和类方法具有较低的优先级。 + +在定义结构修复程序时应使用仔细的设计,因为某些属性会因扩展而丢失,例如以下内容。 + +```python +# 这不应该是 `Structural` +Norm = Structural Patch {x = Int; y = Int} +Norm. + norm self = self::x**2 + self::y**2 + +Point2D = Class {x = Int; y = Int} +assert Point2D.new({x = 1; y = 2}).norm() == 5 + +Point3D = Class {x = Int; y = Int; z = Int} +assert Point3D.new({x = 1; y = 2; z = 3}).norm() == 14 # AssertionError: +``` + +

+ 上一页 | 下一页 +

diff --git a/doc/zh_TW/syntax/type/08_value.md b/doc/zh_TW/syntax/type/08_value.md new file mode 100644 index 00000000..1483139a --- /dev/null +++ b/doc/zh_TW/syntax/type/08_value.md @@ -0,0 +1,37 @@ +# 值类型 + +值类型是可以在编译时评估的 Erg 内置类型,具体来说: + +```python +Value = ( + Int + or Nat + or Ratio + or Float + or Complex + or Bool + or Str + or NoneType + or Array Const + or Tuple Const + or Set Const + or ConstFunc(Const, _) + or ConstProc(Const, _) + or ConstMethod(Const, _) +) +``` + +应用于它们的值类型对象、常量和编译时子例程称为 __constant 表达式__。 + +```python +1, 1.0, 1+2im, True, None, "aaa", [1, 2, 3], Fib(12) +``` + +小心子程序。子例程可能是也可能不是值类型。 +由于子程序的实质只是一个指针,因此可以将其视为一个值[1](#1),但是在编译不是子程序的东西时不能使用 在恒定的上下文中。 不是值类型,因为它没有多大意义。 + +将来可能会添加归类为值类型的类型。 + +--- + +1 Erg 中的术语“值类型”与其他语言中的定义不同。 纯 Erg 语义中没有内存的概念,并且因为它被放置在堆栈上而说它是值类型,或者因为它实际上是一个指针而说它不是值类型是不正确的。 值类型仅表示它是“值”类型或其子类型。 [↩](#f1) diff --git a/doc/zh_TW/syntax/type/09_attributive.md b/doc/zh_TW/syntax/type/09_attributive.md new file mode 100644 index 00000000..96cae23e --- /dev/null +++ b/doc/zh_TW/syntax/type/09_attributive.md @@ -0,0 +1,9 @@ +# 属性类型 + +属性类型是包含 Record 和 Dataclass、Patch、Module 等的类型。 +属于属性类型的类型不是值类型。 + +## 记录类型复合 + +可以展平复合的记录类型。 +例如,`{... {.name = Str; .age = Nat}; ... {.name = Str; .id = Nat}}` 变成 `{.name = Str; .age = 自然; .id = Nat}`。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/10_interval.md b/doc/zh_TW/syntax/type/10_interval.md new file mode 100644 index 00000000..2ecd67e8 --- /dev/null +++ b/doc/zh_TW/syntax/type/10_interval.md @@ -0,0 +1,36 @@ +# 间隔类型 + +`Range` 对象最基本的用途是作为迭代器。 + +```python +for! 0..9, i => + print! i +``` + +请注意,与 Python 不同,它包含一个结束编号。 + +然而,这不仅仅用于 `Range` 对象。 也可以使用类型。 这种类型称为Interval类型。 + +```python +i: 0..10 = 2 +``` + +`Nat` 类型等价于 `0.. ExtraStatus,Status的元素可以使用ExtraStatus的方法 +Status = Trait {"Ok", "Error"} + # ... +ExtraStatus = Trait {"Ok", "Error", "Unknown"} + # ... +``` + +方法也可以通过补丁添加。 + +使用“或”运算符明确指示包含或向现有 Enum 类型添加选项。 + +```python +ExtraStatus = Status or {"Unknown"} +``` + +一个元素所属的所有类都相同的枚举类型称为同质枚举类型。 + +默认情况下,可以将需求类型为同类枚举类型的类视为元素所属类的子类。 + +如果您不想这样做,可以将其设为包装类 + +```python +Abc = Class {"A", "B", "C"} +Abc.new("A").is_uppercase() + +OpaqueAbc = Class {inner = {"A", "B", "C"}}. + new inner: {"A", "B", "C"} = Self.new {inner;} +OpaqueAbc.new("A").is_uppercase() # 类型错误 +``` diff --git a/doc/zh_TW/syntax/type/12_refinement.md b/doc/zh_TW/syntax/type/12_refinement.md new file mode 100644 index 00000000..7c51a5fb --- /dev/null +++ b/doc/zh_TW/syntax/type/12_refinement.md @@ -0,0 +1,75 @@ +# 细化类型 + +细化类型是受谓词表达式约束的类型。 枚举类型和区间类型是细化类型的语法糖。 + +细化类型的标准形式是`{Elem: Type | (预)*}`。 这意味着该类型是其元素为满足 `Pred` 的 `Elem` 的类型。 +可用于筛选类型的类型仅为 [Const type](./advanced/const.md)。 + +```python +Nat = 0.. _ +Odd = {N: Int | N % 2 == 1} +Char = StrWithLen 1 +# StrWithLen 1 == {_: StrWithLen N | N == 1} +[Int; 3] == {_: Array Int, N | N == 3} +Array3OrMore == {A: Array _, N | N >= 3} +``` + +当有多个 pred 时,可以用 `;` 或 `and` 或 `or` 分隔。 `;` 和 `and` 的意思是一样的。 + +`Odd` 的元素是 `1, 3, 5, 7, 9, ...`。 +它被称为细化类型,因为它的元素是现有类型的一部分,就好像它是细化一样。 + +`Pred` 被称为(左侧)谓词表达式。 和赋值表达式一样,它不返回有意义的值,左侧只能放置一个模式。 +也就是说,诸如`X**2 - 5X + 6 == 0`之类的表达式不能用作细化类型的谓词表达式。 在这方面,它不同于右侧的谓词表达式。 + +```python +{X: Int | X**2 - 5X + 6 == 0} # 语法错误:谓词形式无效。 只有名字可以在左边 +``` + +如果你知道如何解二次方程,你会期望上面的细化形式等价于`{2, 3}`。 +但是,Erg 编译器对代数的了解很少,因此无法解决右边的谓词。 + +## 智能投射 + +很高兴您定义了 `Odd`,但事实上,它看起来不能在文字之外使用太多。 要将普通 `Int` 对象中的奇数提升为 `Odd`,即将 `Int` 向下转换为 `Odd`,您需要传递 `Odd` 的构造函数。 +对于细化类型,普通构造函数 `.new` 可能会出现恐慌,并且有一个名为 `.try_new` 的辅助构造函数返回一个 `Result` 类型。 + +```python +i = Odd.new (0..10).sample!() +i: Odd # or Panic +``` + +它也可以用作 `match` 中的类型说明。 + +```python +# i: 0..10 +i = (0..10).sample! +match i: + o: Odd -> + log "i: Odd" + n: Nat -> # 0..10 < Nat + log "i: Nat" +``` + +但是,Erg 目前无法做出诸如“偶数”之类的子决策,因为它不是“奇数”等。 + +## 枚举、区间和筛选类型 + +前面介绍的枚举/区间类型是细化类型的语法糖。 +`{a, b, ...}` 是 `{I: Typeof(a) | I == a 或 I == b 或 ... }`,并且 `a..b` 被去糖化为 `{I: Typeof(a) | 我 >= a 和我 <= b}`。 + +```python +{1, 2} == {I: Int | I == 1 or I == 2} +1..10 == {I: Int | I >= 1 and I <= 10} +1... <10 == {I: Int | I >= 1 and I < 10} +``` + +## 细化模式 + +正如 `_: {X}` 可以重写为 `X`(常量模式),`_: {X: T | Pred}` 可以重写为`X: T | Pred` + +```python +# 方法 `.m` 是为长度为 3 或更大的数组定义的 +Array(T, N | N >= 3) + .m(&self) = ... +``` diff --git a/doc/zh_TW/syntax/type/13_algebraic.md b/doc/zh_TW/syntax/type/13_algebraic.md new file mode 100644 index 00000000..5567aafc --- /dev/null +++ b/doc/zh_TW/syntax/type/13_algebraic.md @@ -0,0 +1,85 @@ +# 代数类型 + +代数类型是通过将类型视为代数来操作类型而生成的类型。 +它们处理的操作包括Union、Intersection、Diff、Complement等。 +普通类只能进行Union,其他操作会导致类型错误。 + +## 联合(Union) + +联合类型可以为类型提供多种可能性。 顾名思义,它们是由“或”运算符生成的。 +一个典型的 Union 是 `Option` 类型。 `Option` 类型是 `T 或 NoneType` 补丁类型,主要表示可能失败的值。 + + +```python +IntOrStr = Int or Str +assert dict.get("some key") in (Int or NoneType) + +# 隐式变为 `T != NoneType` +Option T = T or NoneType +``` + +## 路口 + +交集类型是通过将类型与 `and` 操作组合得到的。 + +```python +Num = Add and Sub and Mul and Eq +``` + +如上所述,普通类不能与“and”操作结合使用。 这是因为实例只属于一个类。 + +## 差异 + +Diff 类型是通过 `not` 操作获得的。 +最好使用 `and not` 作为更接近英文文本的符号,但建议只使用 `not`,因为它更适合与 `and` 和 `or` 一起使用。 + +```python +CompleteNum = Add and Sub and Mul and Div and Eq and Ord +Num = CompleteNum not Div not Ord + +True = Bool not {False} +OneTwoThree = {1, 2, 3, 4, 5, 6} - {4, 5, 6, 7, 8, 9, 10} +``` + +## 补充 + +补码类型是通过 `not` 操作得到的,这是一个一元操作。 `not T` 类型是 `{=} not T` 的简写。 +类型为“非 T”的交集等价于 Diff,类型为“非 T”的 Diff 等价于交集。 +但是,不推荐这种写法。 + +```python +# 非零数类型的最简单定义 +NonZero = Not {0} +# 不推荐使用的样式 +{True} == Bool and not {False} # 1 == 2 + - 1 +Bool == {True} not not {False} # 2 == 1 - -1 +``` + +## 真代数类型 + +有两种代数类型:可以简化的表观代数类型和不能进一步简化的真实代数类型。 +“表观代数类型”包括 Enum、Interval 和 Record 类型的 `or` 和 `and`。 +这些不是真正的代数类型,因为它们被简化了,并且将它们用作类型说明符将导致警告; 要消除警告,您必须简化它们或定义它们的类型。 + +```python +assert {1, 2, 3} or {2, 3} == {1, 2, 3} +assert {1, 2, 3} and {2, 3} == {2, 3} +assert -2..-1 or 1..2 == {-2, -1, 1, 2} + +i: {1, 2} or {3, 4} = 1 # 类型警告:{1, 2} 或 {3, 4} 可以简化为 {1, 2, 3, 4} +p: {x = Int, ...} and {y = Int; ...} = {x = 1; y = 2; z = 3} +# 类型警告:{x = Int, ...} 和 {y = Int; ...} 可以简化为 {x = Int; y = 整数; ...} + +Point1D = {x = Int; ...} +Point2D = Point1D and {y = Int; ...} # == {x = Int; y = Int; ...} +q: Point2D = {x = 1; y = 2; z = 3} +``` + +真正的代数类型包括类型“或”和“与”。 类之间的“或”等类属于“或”类型。 + +```python +assert Int or Str == Or(Int, Str) +assert Int and Marker == And(Int, Marker) +``` + +Diff, Complement 类型不是真正的代数类型,因为它们总是可以被简化。 diff --git a/doc/zh_TW/syntax/type/14_dependent.md b/doc/zh_TW/syntax/type/14_dependent.md new file mode 100644 index 00000000..70ef8633 --- /dev/null +++ b/doc/zh_TW/syntax/type/14_dependent.md @@ -0,0 +1,74 @@ +# 依赖类型 + +依赖类型是一个特性,可以说是 Erg 的最大特性。 +依赖类型是将值作为参数的类型。 普通的多态类型只能将类型作为参数,但依赖类型放宽了这个限制。 + +依赖类型等价于`[T; N]`(`数组(T,N)`)。 +这种类型不仅取决于内容类型“T”,还取决于内容数量“N”。 `N` 包含一个`Nat` 类型的对象。 + +```python +a1 = [1, 2, 3] +assert a1 in [Nat; 3] +a2 = [4, 5, 6, 7] +assert a1 in [Nat; 4] +assert a1 + a2 in [Nat; 7] +``` + +如果函数参数中传递的类型对象与返回类型有关,则写: + +```python +narray: |N: Nat| {N} -> [{N}; N] +narray(N: Nat): [N; N] = [N; N] +assert array(3) == [3, 3, 3] +``` + +定义依赖类型时,所有类型参数都必须是常量。 + +依赖类型本身存在于现有语言中,但 Erg 具有在依赖类型上定义过程方法的特性 + +```python +x=1 +f x = + print! f::x, module::x + +# Phantom 类型有一个名为 Phantom 的属性,其值与类型参数相同 +T X: Int = Class Impl := Phantom X +T(X). + x self = self::Phantom + +T(1).x() # 1 +``` + +可变依赖类型的类型参数可以通过方法应用程序进行转换。 +转换规范是用 `~>` 完成的 + +```python +# 注意 `Id` 是不可变类型,不能转换 +VM!(State: {"stopped", "running"}! := _, Id: Nat := _) = Class(..., Impl := Phantom! State) +VM!(). + # 不改变的变量可以通过传递`_`省略。 + start! ref! self("stopped" ~> "running") = + self.initialize_something!() + self::set_phantom!("running") + +# 你也可以按类型参数切出(仅在定义它的模块中) +VM!.new() = VM!(!"stopped", 1).new() +VM!("running" ~> "running").stop!ref!self = + self.close_something!() + self::set_phantom!("stopped") + +vm = VM!.new() +vm.start!() +vm.stop!() +vm.stop!() # 类型错误:VM!(!"stopped", 1) 没有 .stop!() +# 提示:VM!(!"running", 1) 有 .stop!() +``` + +您还可以嵌入或继承现有类型以创建依赖类型。 + +```python +MyArray(T, N) = Inherit[T; N] + +# self 的类型:Self(T, N) 与 .array 一起变化 +MyStruct!(T, N: Nat!) = Class {.array: [T; !N]} +``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/15_quantified.md b/doc/zh_TW/syntax/type/15_quantified.md new file mode 100644 index 00000000..fb4af5b7 --- /dev/null +++ b/doc/zh_TW/syntax/type/15_quantified.md @@ -0,0 +1,280 @@ +# 类型变量,量化类型 + +类型变量是用于例如指定子程序参数类型的变量,它的类型是任意的(不是单态的)。 +首先,作为引入类型变量的动机,考虑 `id` 函数,它按原样返回输入。 + +```python +id x: Int = x +``` + +返回输入的“id”函数是为“Int”类型定义的,但这个函数显然可以为任何类型定义。 +让我们使用 `Object` 来表示最大的类。 + +```python +id x: Object = x + +i = id 1 +s = id "foo" +b = id True +``` + +当然,它现在接受任意类型,但有一个问题:返回类型被扩展为 `Object`。 返回类型扩展为 `Object`。 +如果输入是“Int”类型,我想查看返回类型“Int”,如果输入是“Str”类型,我想查看“Str”。 + +```python +print! id 1 # +id(1) + 1 # 类型错误:无法添加 `Object` 和 `Int +``` + +要确保输入的类型与返回值的类型相同,请使用 __type 变量__。 +类型变量在`||`(类型变量列表)中声明。 + +```python +id|T: Type| x: T = x +assert id(1) == 1 +assert id("foo") == "foo" +assert id(True) == True +``` + +这称为函数的 __universal quantification(泛化)__。 有细微的差别,但它对应于其他语言中称为泛型的函数。 泛化函数称为__多态函数__。 +定义一个多态函数就像为所有类型定义一个相同形式的函数(Erg 禁止重载,所以下面的代码真的不能写)。 + +```python +id|T: Type| x: T = x +# 伪代码 +id x: Int = x +id x: Str = x +id x: Bool = x +id x: Ratio = x +id x: NoneType = x +... +``` + +此外,类型变量“T”可以推断为“Type”类型,因为它在类型规范中使用。 所以 `|T: Type|` 可以简单地缩写为 `|T|`。 +你也可以省略`|T, N| 脚; N]` 如果可以推断它不是类型对象(`T: Type, N: Nat`)。 + +如果类型对于任意类型来说太大,您也可以提供约束。 +约束也有优势,例如,子类型规范允许使用某些方法。 + +```python +# T <: Add +# => T 是 Add 的子类 +# => 可以做加法 +add|T <: Add| l: T, r: T = l + r +``` + +在本例中,`T` 必须是`Add` 类型的子类,并且要分配的`l` 和`r` 的实际类型必须相同。 +在这种情况下,“T”由“Int”、“Ratio”等满足。因此,例如,“Int”和“Str”的添加没有定义,因此被拒绝。 + +您也可以像这样键入它。 + +```python +f| + Y, Z: Type + X <: Add Y, O1 + O1 <: Add Z, O2 + O2 <: Add X, _ +| x: X, y: Y, z: Z = + x + y + z + x +``` + +如果注释列表很长,您可能需要预先声明它。 + +```python +f: |Y, Z: Type, X <: Add(Y, O1), O1 <: Add(Z, O2), O2 <: Add(X, O3)| (X, Y, Z) -> O3 +f|X, Y, Z| x: X, y: Y, z: Z = + x + y + z + x +``` + +与许多具有泛型的语言不同,所有声明的类型变量都必须在临时参数列表(`x: X, y: Y, z: Z` 部分)或其他类型变量的参数中使用。 +这是 Erg 语言设计的一个要求,即所有类型变量都可以从真实参数中推断出来。 +因此,无法推断的信息,例如返回类型,是从真实参数传递的; Erg 允许从实参传递类型。 + +```python +Iterator T = Trait { + # 从参数传递返回类型。 + # .collect: |K: Type -> Type| Self(T). ({K}) -> K(T) + .collect(self(T), K: Type -> Type): K(T) = ... + ... +} + +it = [1, 2, 3].iter().map i -> i + 1 +it.collect(Array) # [2, 3, 4]. +``` + +类型变量只能在 `||` 期间声明。 但是,一旦声明,它们就可以在任何地方使用,直到它们退出作用域 + +```python +f|X|(x: X): () = + y: X = x.clone() + log X.__name__ + log X + +f 1 +# Int +# +``` + +您也可以在使用时明确单相如下 + +```python +f: Int -> Int = id|Int| +``` + +在这种情况下,指定的类型优先于实际参数的类型(匹配失败将导致类型错误,即实际参数的类型错误)。 +即如果传递的实际对象可以转换为指定的类型,则进行转换; 否则会导致编译错误。 + +```python +assert id(1) == 1 +assert id|Int|(1) in Int +assert id|Ratio|(1) in Ratio +# 你也可以使用关键字参数 +assert id|T: Int|(1) == 1 +id|Int|("str") # 类型错误: id|Int| is type `Int -> Int`但得到了 Str +``` + +当此语法与理解相冲突时,您需要将其括在 `()` 中。 + +```python +# {id|Int| x | x <- 1..10} 将被解释为 {id | ...} +{(id|Int| x) | x <- 1..10} +``` + +不能使用与已存在的类型相同的名称来声明类型变量。 这是因为所有类型变量都是常量。 + +```python +I: Type +# ↓ 无效类型变量,已经存在 +f|I: Type| ... = ... +``` + +## 在方法定义中输入参数 + +默认情况下,左侧的类型参数被视为绑定变量。 + +```python +K(T: Type, N: Nat) = ... +K(T, N). + foo(x) = ... +``` + +使用另一个类型变量名称将导致警告。 + +```python +K(T: Type, N: Nat) = ... +K(U, M). # 警告:K 的类型变量名是 'T' 和 'N' + foo(x) = ... +``` + +自定义以来,所有命名空间中的常量都是相同的,因此它们当然不能用于类型变量名称 + +```python +N = 1 +K(N: Nat) = ... # 名称错误:N 已定义 + +L(M: Nat) = ... +# 仅当 M == N == 1 时才定义 +L(N). + foo(self, x) = ... +# 为任何定义 M: Nat +L(M). + .bar(self, x) = ... +``` + +每个类型参数不能有多个定义,但可以定义具有相同名称的方法,因为未分配类型参数的依赖类型(非原始类型)和分配的依赖类型(原始类型)之间没有关系 )。 + +```python +K(I: Int) = ... +K. + # K 不是真正的类型(atomic Kind),所以我们不能定义方法 + # 这不是方法(更像是静态方法) + foo(x) = ... +K(0). + foo(self, x): Nat = ... +``` + +## 所有对称类型 + +上一节中定义的 `id` 函数是一个可以是任何类型的函数。 那么 `id` 函数本身的类型是什么? + +```python +print! classof(id) # |T: Type| T -> T +``` + +我们得到一个类型`|T: Type| T -> T`。 这称为一个 __封闭的全称量化类型/全称类型__,即`['a. ...]'` 在 ML 和 `forall t. ...` 在 Haskell 中。 为什么使用形容词“关闭”将在下面讨论。 + +封闭的全称量化类型有一个限制:只有子程序类型可以被通用量化,即只有子程序类型可以放在左子句中。 但这已经足够了,因为子程序是 Erg 中最基本的控制结构,所以当我们说“我要处理任意 X”时,即我想要一个可以处理任意 X 的子程序。所以,量化类型具有相同的含义 作为多态函数类型。 从现在开始,这种类型基本上被称为多态函数类型。 + +与匿名函数一样,多态类型具有任意类型变量名称,但它们都具有相同的值。 + +```python +assert (|T: Type| T -> T) == (|U: Type| U -> U) +``` + +当存在 alpha 等价时,等式得到满足,就像在 lambda 演算中一样。 由于对类型的操作有一些限制,所以总是可以确定等价的(如果我们不考虑 stoppage 属性)。 + +## 多态函数类型的子类型化 + +多态函数类型可以是任何函数类型。 这意味着与任何函数类型都存在子类型关系。 让我们详细看看这种关系。 + +类型变量在左侧定义并在右侧使用的类型,例如 `OpenFn T: Type = T -> T`,称为 __open 通用类型__。 +相反,在右侧定义和使用类型变量的类型,例如 `ClosedFn = |T: Type| T -> T`,被称为 __封闭的通用类型__。 + +开放通用类型是所有同构“真”类型的超类型。 相反,封闭的通用类型是所有同构真类型的子类型。 + +```python +(|T: Type| T -> T) < (Int -> Int) < (T -> T) +``` + +您可能还记得封闭的较小/开放的较大。 +但为什么会这样呢? 为了更好地理解,让我们考虑每个实例。 + +```python +# id: |T: Type| T -> T +id|T|(x: T): T = x + +# iid: Int -> Int +iid(x: Int): Int = x + +# 按原样返回任意函数 +id_arbitrary_fn|T|(f1: T -> T): (T -> T) = f +# id_arbitrary_fn(id) == id +# id_arbitrary_fn(iid) == iid + +# return the poly correlation number as it is +id_poly_fn(f2: (|T| T -> T)): (|T| T -> T) = f +# id_poly_fn(id) == id +id_poly_fn(iid) # 类型错误 + +# 按原样返回 Int 类型函数 +id_int_fn(f3: Int -> Int): (Int -> Int) = f +# id_int_fn(id) == id|Int| +# id_int_fn(iid) == iid +``` + +由于 `id` 是 `|T: Type| 类型T -> T`,可以赋值给`Int-> Int`类型的参数`f3`,我们可以考虑`(|T| T -> T) < (Int -> Int)`。 +反之,`Int -> Int`类型的`iid`不能赋值给`(|T| T -> T)`类型的参数`f2`,但可以赋值给`(|T| T -> T)`的参数`f1`输入 `T -> T`,所以 `(Int -> Int) < (T -> T)`。 +因此,确实是`(|T| T -> T) < (Int -> Int) < (T -> T)`。 + +## 量化类型和依赖类型 + +依赖类型和量化类型(多态函数类型)之间有什么关系,它们之间有什么区别? +我们可以说依赖类型是一种接受参数的类型,而量化类型是一种赋予参数任意性的类型。 + +重要的一点是封闭的多态类型本身没有类型参数。例如,多态函数类型`|T| T -> T` 是一个接受多态函数 __only__ 的类型,它的定义是封闭的。您不能使用其类型参数`T`来定义方法等。 + +在 Erg 中,类型本身也是一个值,因此带参数的类型(例如函数类型)可能是依赖类型。换句话说,多态函数类型既是量化类型又是依赖类型。 + +```python +PolyFn = Patch(|T| T -> T) +PolyFn. + type self = T # 名称错误:找不到“T” +DepFn T = Patch(T -> T) +DepFn. + type self = + log "by DepFn" + T + +assert (Int -> Int).type() == Int # 由 DepFn +assert DepFn(Int).type() == Int # 由 DepFn +``` diff --git a/doc/zh_TW/syntax/type/16_subtyping.md b/doc/zh_TW/syntax/type/16_subtyping.md new file mode 100644 index 00000000..86c44646 --- /dev/null +++ b/doc/zh_TW/syntax/type/16_subtyping.md @@ -0,0 +1,76 @@ +# 子类型 + +在 Erg 中,可以使用比较运算符 `<`、`>` 确定类包含。 + +```python +Nat < Int +Int < Object +1... _ < Nat +{1, 2} > {1} +{=} > {x = Int} +{I: Int | I >= 1} < {I: Int | I >= 0} +``` + +请注意,这与 `<:` 运算符的含义不同。 它声明左侧的类是右侧类型的子类型,并且仅在编译时才有意义。 + +```python +C <: T # T: 结构类型 +f|D <: E| ... + +assert F < G +``` + +您还可以为多态子类型规范指定 `Self <: Add`,例如 `Self(R, O) <: Add(R, O)`。 + +## 结构类型和类类型关系 + +结构类型是结构类型的类型,如果它们具有相同的结构,则被认为是相同的对象。 + +```python +T = Structural {i = Int} +U = Structural {i = Int} + +assert T == U +t: T = {i = 1} +assert t in T +assert t in U +``` + +相反,类是符号类型的类型,不能在结构上与类型和实例进行比较 + +```python +C = Class {i = Int} +D = Class {i = Int} + +assert C == D # 类型错误:无法比较类 +c = C.new {i = 1} +assert c in C +assert not c in D +``` + +## 子程序的子类型化 + +子例程的参数和返回值只采用一个类。 +换句话说,您不能直接将结构类型或特征指定为函数的类型。 +必须使用部分类型规范将其指定为“作为该类型子类型的单个类”。 + +```python +# OK +f1 x, y: Int = x + y +# NG +f2 x, y: Add = x + y +# OK +# A 是一些具体的类 +f3 x, y: A = x + y +``` + +子程序中的类型推断也遵循此规则。 当子例程中的变量具有未指定的类型时,编译器首先检查它是否是其中一个类的实例,如果不是,则在特征范围内查找匹配项。 如果仍然找不到,则会发生编译错误。 此错误可以通过使用结构类型来解决,但由于推断匿名类型可能会给程序员带来意想不到的后果,因此它被设计为由程序员使用 `Structural` 显式指定。 + +## 类向上转换 + +```python +i: Int +i as (Int or Str) +i as (1..10) +i as {I: Int | I >= 0} +``` diff --git a/doc/zh_TW/syntax/type/17_type_casting.md b/doc/zh_TW/syntax/type/17_type_casting.md new file mode 100644 index 00000000..5fd31369 --- /dev/null +++ b/doc/zh_TW/syntax/type/17_type_casting.md @@ -0,0 +1,72 @@ +# 投掷 + +## 向上转型 + +因为 Python 是一种使用鸭子类型的语言,所以没有强制转换的概念。没有必要向上转型,本质上也没有向下转型。 +但是,Erg 是静态类型的,因此有时必须进行强制转换。 +一个简单的例子是 `1 + 2.0`:`+`(Int, Ratio) 或 Int(<: Add(Ratio, Ratio)) 操作在 Erg 语言规范中没有定义。这是因为 `Int <: Ratio`,所以 1 向上转换为 1.0,即 Ratio 的一个实例。 + +~~ Erg扩展字节码在BINARY_ADD中增加了类型信息,此时类型信息为Ratio-Ratio。在这种情况下,BINARY_ADD 指令执行 Int 的转换,因此没有插入指定转换的特殊指令。因此,例如,即使您在子类中重写了某个方法,如果您将父类指定为类型,则会执行类型强制,并在父类的方法中执行该方法(在编译时执行名称修改以引用父母的方法)。编译器只执行类型强制验证和名称修改。运行时不强制转换对象(当前。可以实现强制转换指令以优化执行)。 ~~ + +```python +@Inheritable +Parent = Class() +Parent. + greet!() = print! "Hello from Parent" + +Child = Inherit Parent +Child. + # Override 需要 Override 装饰器 + @Override + greet!() = print! "Hello from Child" + +greet! p: Parent = p.greet!() + +parent = Parent.new() +child = Child.new() + +parent # 来自Parent的问候! +child # 来自child的问候! +``` + +此行为不会造成与 Python 的不兼容。 首先,Python 没有指定变量的类型,所以可以这么说,所有的变量都是类型变量。 由于类型变量会选择它们可以适应的最小类型,因此如果您没有在 Erg 中指定类型,则可以实现与 Python 中相同的行为。 + +```python +@Inheritable +Parent = Class() +Parent. + greet!() = print! "Hello from Parent" + +Child = Inherit Parent +Child. + greet!() = print! "Hello from Child" Child. + +greet! some = some.greet!() + +parent = Parent.new() +child = Child.new() + +parent # 来自Parent的问候! +child # 来自child的问候! +``` + +您还可以使用 `.from` 和 `.into`,它们会为相互继承的类型自动实现 + +```python +assert 1 == 1.0 +assert Ratio.from(1) == 1.0 +assert 1.into() == 1.0 +``` + +## 向下转型 + +由于向下转换通常是不安全的并且转换方法很重要,我们改为实现“TryFrom.try_from” + +```python +IntTryFromFloat = Patch Int +IntTryFromFloat. + try_from r: Float = + if r.ceil() == r: + then: r.ceil() + else: Error "conversion failed". +``` diff --git a/doc/zh_TW/syntax/type/18_mut.md b/doc/zh_TW/syntax/type/18_mut.md new file mode 100644 index 00000000..30f660a2 --- /dev/null +++ b/doc/zh_TW/syntax/type/18_mut.md @@ -0,0 +1,163 @@ +# 可变类型 + +> __Warning__:本节中的信息是旧的并且包含一些错误。 + +默认情况下,Erg 中的所有类型都是不可变的,即它们的内部状态无法更新。 +但是你当然也可以定义可变类型。 变量类型用 `!` 声明。 + +```python +Person! = Class({name = Str; age = Nat!}) +Person!. + greet! ref! self = print! "Hello, my name is {self::name}. I am {self::age}." + inc_age!ref!self = self::name.update!old -> old + 1 +``` + +准确地说,基类型是可变类型或包含可变类型的复合类型的类型必须在类型名称的末尾有一个“!”。 没有 `!` 的类型可以存在于同一个命名空间中,并被视为单独的类型。 +在上面的例子中,`.age` 属性是可变的,`.name` 属性是不可变的。 如果即使一个属性是可变的,那么整个属性也是可变的。 + +可变类型可以定义重写实例的过程方法,但具有过程方法并不一定使它们可变。 例如数组类型`[T; N]` 实现了一个 `sample!` 随机选择一个元素的方法,但当然不会破坏性地修改数组。 + +对可变对象的破坏性操作主要是通过 .update! 方法完成的。 `.update!` 方法是一个高阶过程,它通过应用函数 `f` 来更新 `self` + +```python +i = !1 +i.update! old -> old + 1 +assert i == 2 +``` + +`.set!` 方法只是丢弃旧内容并用新值替换它。 .set!x = .update!_ -> x。 + +```python +i = !1 +i.set! 2 +assert i == 2 +``` + +`.freeze_map` 方法对不变的值进行操作 + +```python +a = [1, 2, 3].into [Nat; !3] +x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(Array) +``` + +在多态不可变类型中,该类型的类型参数“T”被隐式假定为不可变。 + +```python +# ImmutType < Type +KT: ImmutType = Class ... +K!T: Type = Class ... +``` + +在标准库中,变量 `(...)!` 类型通常基于不可变 `(...)` 类型。 但是,`T!` 和 `T` 类型没有特殊的语言关系,并且不能这样构造 [1](#1) 。 + +请注意,有几种类型的对象可变性。 +下面我们将回顾内置集合类型的不可变/可变语义。 + +```python +# 数组类型 +## 不可变类型 +[T; N] # 不能执行可变操作 +## 可变类型 +[T; N] # 可以一一改变内容 +[T; !N] # 可变长度,内容不可变但可以通过添加/删除元素来修改 +[!T; N] # 内容是不可变的对象,但是可以替换成不同的类型(实际上可以通过不改变类型来替换) +[!T; !N] # 类型和长度可以改变 +[T; !N] # 内容和长度可以改变 +[!T!; N] # 内容和类型可以改变 +[!T!; !N] # 可以执行各种可变操作 +``` + +当然,您不必全部记住和使用它们。 +对于可变数组类型,只需将 `!` 添加到您想要可变的部分,实际上是 `[T; N]`, `[T!; N]`,`[T; !N]`, ` [T!; !N]` 可以涵盖大多数情况。 + +这些数组类型是语法糖,实际类型是: + +```python +# actually 4 types +[T; N] = Array(T, N) +[T; !N] = Array!(T, !N) +[!T; N] = ArrayWithMutType!(!T, N) +[!T; !N] = ArrayWithMutTypeAndLength!(!T, !N) +[T!; !N] = Array!(T!, !N) +[!T!; N] = ArrayWithMutType!(!T!, N) +[!T!; !N] = ArrayWithMutTypeAndLength!(!T!, !N) +``` + +这就是能够改变类型的意思。 + +```python +a = [1, 2, 3].into [!Nat; 3] +a.map!(_ -> "a") +a: [!Str; 3] +``` + +其他集合类型也是如此。 + +```python +# 元组类型 +## 不可变类型 +(T, U) # 元素个数不变,内容不能变 +## 可变类型 +(T!, U) # 元素个数不变,第一个元素可以改变 +(T,U)! # 元素个数不变,内容可以替换 +... +``` + +```python +# 设置类型 +## 不可变类型 +{T; N} # 不可变元素个数,内容不能改变 +## 可变类型 +{T!; N} # 不可变元素个数,内容可以改变(一个一个) +{T; N}! # 可变元素个数,内容不能改变 +{T!; N}! # 可变元素个数,内容可以改变 +... +``` + +```python +# 字典类型 +## 不可变类型 +{K: V} # 长度不可变,内容不能改变 +## 可变类型 +{K:V!} # 恒定长度,值可以改变(一一) +{K:V}! # 可变长度,内容不能改变,但可以通过添加或删除元素来增加或删除,内容类型也可以改变 +... +``` + +```python +# 记录类型 +## 不可变类型 +{x = Int; y = Str} # 内容不能改变 +## 可变类型 +{x = Int!; y = Str} # 可以改变x的值 +{x = Int; y = Str}! # 替换 {x = Int; 的任何实例 y = Str} +... +``` + +一个类型 `(...)` 简单地变成了 `T! = (...)!` 当 `T = (...)` 被称为简单结构化类型。 简单的结构化类型也可以(语义上)说是没有内部结构的类型。 +数组、元组、集合、字典和记录类型都是非简单的结构化类型,但 Int 和 Sieve 类型是。 + +```python +#筛子类型 +## 枚举 +{1, 2, 3} # 1, 2, 3 之一,不可更改 +{1、2、3}! # 1、2、3,可以改 +##区间类型 +1..12 #1到12,不能改 +1..12! # 1-12中的任意一个,你可以改变 +##筛型(普通型) +{I: Int | I % 2 == 0} #偶数类型,不可变 +{I: Int | I % 2 == 0} #偶数类型,可以改变 +{I: Int | I % 2 == 0}! # 与上面完全相同的类型,但上面的表示法是首选 +``` + +从上面的解释来看,可变类型不仅包括自身可变的,还包括内部类型可变的。 +诸如 `{x: Int!}` 和 `[Int!; 之类的类型3]` 是内部可变类型,其中内部的对象是可变的,而实例本身是不可变的。 + +对于具有内部结构并在类型构造函数本身上具有 `!` 的类型 `K!(T, U)`,`*self` 可以更改整个对象。也可以进行局部更改。 +但是,希望尽可能保持本地更改权限,因此如果只能更改 `T`,最好使用 `K(T!, U)`。 +而对于没有内部结构的类型‘T!’,这个实例只是一个可以交换的‘T’盒子。方法不能更改类型。 + +--- + +1 `T!` 和 `T` 类型没有特殊的语言关系是有意的。这是一个设计。如果存在关系,例如命名空间中存在`T`/`T!`类型,则无法从其他模块引入`T!`/`T`类型。此外,可变类型不是为不可变类型唯一定义的。给定定义 `T = (U, V)`,`T!` 的可能变量子类型是 `(U!, V)` 和 `(U, V!)`。[↩](#f1) \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/19_bound.md b/doc/zh_TW/syntax/type/19_bound.md new file mode 100644 index 00000000..d6aecf50 --- /dev/null +++ b/doc/zh_TW/syntax/type/19_bound.md @@ -0,0 +1,18 @@ +# 类型绑定 + +类型边界为类型规范添加条件。 实现这一点的函数是守卫(守卫子句)。 +此功能可用于函数签名、匿名函数签名以及筛选类型。 +守卫写在返回类型之后。 + +## 谓词 + +您可以使用返回 `Bool` 的表达式(谓词表达式)指定变量满足的条件。 +只能使用 [值对象](./08_value.md) 和运算符。 未来版本可能会支持编译时函数 + +```python +f a: [T; N] | T, N, N > 5 = ... +g a: [T; N | N > 5] | T, N = ... +Odd = {I: Int | I % 2 == 1} +R2Plus = {(L, R) | L, R: Ratio; L > 0 and R > 0} +GeneralizedOdd = {I | U; I <: Div(Nat, U); I % 2 == 0} +``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced.md b/doc/zh_TW/syntax/type/advanced.md new file mode 100644 index 00000000..01dd89dc --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced.md @@ -0,0 +1 @@ +下面,我们将讨论更高级的类型系统。 初学者不必阅读所有部分。 \ 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 new file mode 100644 index 00000000..8210a9dd --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/GADTs.md @@ -0,0 +1,66 @@ +# 广义代数数据类型 (GADT) + +Erg 可以通过对 Or 类型进行分类来创建广义代数数据类型 (GADT)。 + +```python +Nil T = Class(Impl := Phantom T) +Cons T = Class {head = T; rest = List T}, Impl := Unpack +List T: Type = Class(Nil T or Cons T) +List. + nil|T|() = Self(T).new Nil(T).new() + cons head, rest | T = Self(T).new Cons(T).new(head, rest) + head self = match self: + {head; ...}: Cons_ -> head + _: Nil -> panic "empty list" +{nil; cons; ...} = List + +print! cons(1, cons(2, nil())).head() # 1 +print! nil.head() # 运行时错误:“空list” +``` + +我们说 `List.nil|T|() = ...` 而不是 `List(T).nil() = ...` 的原因是我们在使用它时不需要指定类型。 + +```python +i = List.nil() +_: List Int = cons 1, i +``` + +这里定义的 `List T` 是 GADTs,但它是一个幼稚的实现,并没有显示 GADTs 的真正价值。 +例如,上面的 .head 方法会在 body 为空时抛出运行时错误,但是这个检查可以在编译时进行。 + +```python +List: (Type, {"Empty", "Nonempty"}) -> Type +List T, "Empty" = Class(Impl := Phantom T) +List T, "Nonempty" = Class {head = T; rest = List(T, _)}, Impl := Unpack +List. + nil|T|() = Self(T, "Empty").new Nil(T).new() + cons head, rest | T = Self(T, "Nonempty").new {head; rest} +List(T, "Nonempty"). + head {head; ...} = head +{nil; cons; ...} = List + +print! cons(1, cons(2, nil())).head() # 1 +print! nil().head() # 类型错误 +``` + +街上经常解释的 GADT 的一个例子是一个列表,可以像上面那样通过类型来判断内容是否为空。 +Erg 可以进一步细化以定义一个有长度的列表。 + +```python +List: (Type, Nat) -> Type +List T, 0 = Class(Impl := Phantom T) +List T, N = Class {head = T; rest = List(T, N-1)}, Impl := Unpack +List. + nil|T|() = Self(T, 0).new Nil(T).new() + cons head, rest | T, N = Self(T, N).new {head; rest} +List(_, N | N >= 1). + head {head; ...} = head +List(_, N | N >= 2). + pair {head = first; rest = {head = second; ...}} = [first, second] +{nil; cons; ...} = List + +print! cons(1, cons(2, nil)).pair() # [1, 2] +print! cons(1, nil).pair() # 类型错误 +print! cons(1, nil).head() # 1 +print! nil. head() # 类型错误 +``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/_rank2type.md b/doc/zh_TW/syntax/type/advanced/_rank2type.md new file mode 100644 index 00000000..596df334 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/_rank2type.md @@ -0,0 +1,142 @@ +# rank-2 多态性 + +> __Warning__:本文档已过时,一般包含错误。 + +Erg 允许您定义接受各种类型的函数,例如 `id|T|(x: T): T = x`,即多相关。 +那么,我们可以定义一个接受多相关的函数吗? +比如这样的函数(注意这个定义是错误的): + +```python +# 我想要 tuple_map(i -> i * 2, (1, "a")) == (2, "aa") +tuple_map|T|(f: T -> T, tup: (Int, Str)): (Int, Str) = (f(tup.0), f(tup.1)) +``` + +注意 `1` 和 `"a"` 有不同的类型,所以匿名函数一次不是单态的。 需要单相两次。 +这样的函数不能在我们目前讨论的类型范围内定义。 这是因为类型变量没有范围的概念。 +让我们暂时离开类型,看看值级别的范围概念。 + +```python +arr = [1, 2, 3] +arr.map i -> i + 1 +``` + +上面代码中的 `arr` 和 `i` 是不同作用域的变量。 因此,每个寿命都是不同的(`i` 更短)。 + +到目前为止,所有类型变量的类型都具有相同的生命周期。 换句话说,‘T’、‘X’和‘Y’必须同时确定,之后保持不变。 +反之,如果我们可以将 `T` 视为“内部作用域”中的类型变量,我们可以组成一个 `tuple_map` 函数。 __Rank 2 type__ 就是为此目的而准备的。 + +```python +# tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) +tuple_map f: (|T: Type| T -> T), tup: (Int, Str) = (f(tup.0), f(tup.1)) +assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa") +``` + +`{(type) | 形式的类型 (类型变量列表)}` 被称为通用类型(详见[通用类型](./../quantified.md))。 +目前我们看到的`id`函数是一个典型的通用函数=多相关函数。 + +```python +id x = x +id: |T: Type| T -> T +``` + +通用类型与函数类型构造函数`->`的关联有特殊的规则,根据关联的方式,类型的语义是完全不同的。 + +用简单的单参数函数来考虑这一点。 + +```python +f1: (T -> T) -> 整数 | T # 接受任何函数并返回 Int 的函数 +f2: (|T: Type| T -> T) -> Int # 接收多相关并返回 Int 的函数 +f3: Int -> (|T: Type| T -> T) # 一个函数,接受一个 Int 并返回一个封闭的通用函数 +f4: |T: Type|(Int -> (T -> T)) # 同上(首选) +``` + +`f1` 和 `f2` 不同,而 `f3` 和 `f4` 相同,这似乎很奇怪。 让我们实际构造一个这种类型的函数。 + +```python +# id: |T: Type| T -> T +id x = x +# same type as `f1` +take_univq_f_and_return_i(_: (|T: Type| T -> T), i: Int): Int = i +# same type as `f2` +take_arbit_f_and_return_i|T: Type|(_: T -> T, i: Int): Int = i +# same type as `f3` +take_i_and_return_univq_f(_: Int): (|T: Type| T -> T) = id +# same type as `f4` +take_i_and_return_arbit_f|T: Type|(_: Int): (T -> T) = id +``` + +After applying it, you will notice the difference. + +```python +_ = take_univq_f_and_return_i(x -> x, 1) # OK +_ = take_univq_f_and_return_i(x: Int -> x, 1) #NG +_ = take_univq_f_and_return_i(x: Str -> x, 1) # NG +_ = take_arbit_f_and_return_i(x -> x, 1) # OK +_ = take_arbit_f_and_return_i(x: Int -> x, 1) # OK +_ = take_arbit_f_anf_return_i(x: Str -> x, 1) # OK + +f: |T| T -> T = take_i_and_return_univq_f(1) +g: |T| T -> T = take_i_and_return_arbit_f(1) +assert f == g +f2: Int -> Int = take_i_and_return_univq_f|Int|(1) +g2: Int -> Int = take_i_and_return_arbit_f|Int|(1) +assert f2 == g2 +``` + +开放的多相关函数类型具体称为 __任意函数类型__。 任意函数类型有无数种可能性:`Int -> Int`、`Str -> Str`、`Bool -> Bool`、`|T: Type| T -> T`, ... 是。 +另一方面,只有一个封闭的(返回与参数相同类型的对象)多态类型`|T:Type| T -> T`。 这种类型被专门称为 __多态函数类型__。 +也就是说,`f1`可以通过`x: Int -> x+1`、`x: Bool -> not x`、`x -> x`等=`f1`是一个多相关数是的, 但是您只能将 `x -> x` 等传递给 `f2` = `f2` 不是 __多元相关__。 +但是像`f2`这样的函数类型明显不同于普通类型,我们需要新的概念来处理它们。 那是类型的“等级”。 + +关于rank的定义,没有量化的类型,如`Int`、`Str`、`Bool`、`T`、`Int -> Int`、`Option Int`等,都被视为“rank” 0”。 + +```python +# K 是多项式类型,例如 Option +R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0) +``` + +接下来,具有一阶全称的类型,例如`|T| T -> T`,或者在返回值类型中包含它们的类型是“rank 1”。 +此外,具有二阶全称量化的类型(具有 rank 1 类型作为参数的类型,例如 `(|T| T -> T) -> Int`)或将它们包含在返回类型中的类型称为“rank 2 ”。 +重复上述以定义“Rank N”类型。 此外,秩-N 类型包括秩为N 或更少的所有类型。 因此,混合等级的类型与其中最高的等级相同。 + +```python +R1 = (|...| R0) or (R0 -> R1) or K(R1) or R0 +R2 = (|...| R1) or (R1 -> R2) or K(R2) or R1 +... +Rn = (|...| Rn-1) or (Rn-1 -> Rn) or K(Rn) or Rn-1 +``` + +让我们看看例子: + +```python + (|T: Type| T -> T) -> (|U: Type| U -> U) +=> R1 -> R1 +=> R1 -> R2 +=> R2 + +Option(|T: Type| T -> T) +=> Option(R1) +=> K(R1) +=> R1 +``` + +根据定义,`tuple_map` 是 rank-2 类型。 + +```python +tuple_map: + ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) +=> (R1, R0) -> R0 +=> R1 -> R2 +=> R2 +``` + +Erg 最多可以处理 rank 2 的类型(因为 rank N 类型包括所有 rank N 或更少的类型,确切地说,所有 Erg 类型都是 rank 2 类型)。 试图构造更多类型的函数是错误的。 +例如,所有处理多相关的函数都需要指定其他参数类型。 而且,这样的功能是不可配置的。 + +```python +# 这是一个 rank-3 类型的函数 +# |X, Y: Type|((|T: Type| T -> T), (X, Y)) -> (X, Y) +generic_tuple_map|X, Y: Type| f: (|T: Type| T -> T), tup: (X, Y) = (f(tup.0), f(tup.1)) +``` + +众所周知,具有 3 级或更高等级的类型在理论上无法通过类型推断来确定。 然而,大多数实际需求可以被等级 2 类型覆盖。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/default_param.md b/doc/zh_TW/syntax/type/advanced/default_param.md new file mode 100644 index 00000000..34b2a88d --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/default_param.md @@ -0,0 +1,28 @@ +# 带默认参数的函数类型 + +首先,让我们看一个使用默认参数的示例。 + +```python +f: (Int, Int, z := Int) -> Int +f(x, y, z := 0) = x + y + z + +g: (Int, Int, z := Int, w := Int) -> Int +g(x, y, z := 0, w := 1) = x + y + z + w + +fold: ((Int, Int) -> Int, [Int], acc := Int) -> Int +fold(f, [], acc) = acc +fold(f, arr, acc := 0) = fold(f, arr[1..], f(acc, arr[0])) +assert fold(f, [1, 2, 3]) == 6 +assert fold(g, [1, 2, 3]) == 8 +``` + +`:=` 之后的参数是默认参数。 +子类型规则如下: + +```python +((X, y := Y) -> Z) <: (X -> Z) +((X, y := Y, ...) -> Z) <: ((X, ...) -> Z) +``` + +第一个意味着可以用没有默认参数的函数来识别具有默认参数的函数。 +第二个意味着可以省略任何默认参数。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/erasure.md b/doc/zh_TW/syntax/type/advanced/erasure.md new file mode 100644 index 00000000..99532ba9 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/erasure.md @@ -0,0 +1,43 @@ +# 类型擦除 + +类型擦除是将类型参数设置为 `_` 并故意丢弃其信息的过程。类型擦除是许多多态语言的特性,但在 Erg 的语法上下文中,将其称为类型参数擦除更为准确。 + +类型擦除的最常见示例是 `[T, _]`。数组在编译时并不总是知道它们的长度。例如,引用命令行参数的 `sys.argv` 的类型为 `[Str, _]`。由于 Erg 的编译器无法知道命令行参数的长度,因此必须放弃有关其长度的信息。 +然而,一个已经被类型擦除的类型变成了一个未被擦除的类型的超类型(例如`[T; N] <: [T; _]`),所以它可以接受更多的对象。 +类型的对象`[T; N]` 当然可以使用 `[T; _]`,但使用后会删除`N`信息。如果长度没有改变,那么可以使用`[T; N]` 在签名中。如果长度保持不变,则必须由签名指示。 + +```python +# 保证不改变数组长度的函数(例如,排序) +f: [T; N] -> [T; N] # 没有的函数 (f: [T; N]) +# 没有的功能(例如过滤器) +g: [T; n] -> [T; _] +``` + +如果您在类型规范本身中使用 `_`,则类型将向上转换为 `Object`。 +对于非类型类型参数(Int、Bool 等),带有 `_` 的参数将是未定义的。 + +```python +i: _ # i: Object +[_; _] == [Object; _] == Array +``` + +类型擦除与省略类型说明不同。 一旦类型参数信息被删除,除非您再次声明它,否则它不会被返回。 + +```python +implicit = (1..5).iter().map(i -> i * 2).to_arr() +explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat)) +``` + +在 Rust 中,这对应于以下代码: + +```rust +let partial = (1..6).iter().map(|i| i * 2).collect::>(); +``` + +Erg 不允许部分省略类型,而是使用高阶种类多态性。 + +```python +# collect 是采用 Kind 的高阶 Kind 方法 +hk = (1..5).iter().map(i -> i * 2).collect(Array) +hk: Array(Int) +``` diff --git a/doc/zh_TW/syntax/type/advanced/existential.md b/doc/zh_TW/syntax/type/advanced/existential.md new file mode 100644 index 00000000..f28b67ed --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/existential.md @@ -0,0 +1,41 @@ +# 存在类型 + +如果存在对应于∀的for-all类型,那么很自然地假设存在对应于∃的存在类型。 +存在类型并不难。 你已经知道存在类型,只是没有意识到它本身。 + +```python +T: Trait +f x: T = ... +``` + +上面的 trait `T` 被用作存在类型。 +相比之下,小写的`T`只是一个特征,`X`是一个for-all类型。 + +```python +f|X <: T| x: X = ... +``` + +事实上,existential 类型被 for-all 类型所取代。 那么为什么会有存在类型这样的东西呢? +首先,正如我们在上面看到的,存在类型不涉及类型变量,这简化了类型规范。 +此外,由于可以删除类型变量,因此如果它是一个全推定类型,则可以构造一个等级为 2 或更高的类型。 + +```python +show_map f: (|T| T -> T), arr: [Show; _] = + arr.map x -> + y = f x + log y + y +``` + +但是,如您所见,existential 类型忘记或扩展了原始类型,因此如果您不想扩展返回类型,则必须使用 for-all 类型。 +相反,仅作为参数且与返回值无关的类型可以写为存在类型。 + +```python +# id(1): 我希望它是 Int +id|T|(x: T): T = x +# |S <: Show|(s: S) -> () 是多余的 +show(s: Show): () = log s +``` + +顺便说一句,类不称为存在类型。 一个类不被称为存在类型,因为它的元素对象是预定义的。 +存在类型是指满足某种特征的任何类型,它不是知道实际分配了什么类型的地方。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/keyword_param.md b/doc/zh_TW/syntax/type/advanced/keyword_param.md new file mode 100644 index 00000000..0989b952 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/keyword_param.md @@ -0,0 +1,26 @@ +# 带有关键字参数的函数类型 + +```python +h(f) = f(y: 1, x: 2) +h: |T: type|((y: Int, x: Int) -> T) -> T +``` + +带有关键字参数的函数的子类型化规则如下。 + +```python +((x: T, y: U) -> V) <: ((T, U) -> V) # x, y 为任意关键字参数 +((y: U, x: T) -> V) <: ((x: T, y: U) -> V) +((x: T, y: U) -> V) <: ((y: U, x: T) -> V) +``` + +这意味着可以删除或替换关键字参数。 +但是你不能同时做这两件事。 +也就是说,您不能将 `(x: T, y: U) -> V` 转换为 `(U, T) -> V`。 +请注意,关键字参数仅附加到顶级元组,而不附加到数组或嵌套元组。 + +```python +Valid: [T, U] -> V +Invalid: [x: T, y: U] -> V +Valid: (x: T, ys: (U,)) -> V +Invalid: (x: T, ys: (y: U,)) -> V +``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/kind.md b/doc/zh_TW/syntax/type/advanced/kind.md new file mode 100644 index 00000000..f0da4035 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/kind.md @@ -0,0 +1,147 @@ +# Kind + +一切都在 Erg 中输入。类型本身也不例外。 __kind__ 表示“类型的类型”。例如,`Int` 属于 `Type`,就像 `1` 属于 `Int`。 `Type` 是最简单的一种,__atomic kind__。在类型论符号中,`Type` 对应于 `*`。 + +在Kind的概念中,实际上重要的是一种或多种Kind(多项式Kind)。单项类型,例如`Option`,属于它。一元Kind表示为 `Type -> Type` [1](#1)。诸如 `Array` 或 `Option` 之类的 __container__ 特别是一种以类型作为参数的多项式类型。 +正如符号 `Type -> Type` 所表明的,`Option` 实际上是一个接收类型 `T` 并返回类型 `Option T` 的函数。但是,由于这个函数不是通常意义上的函数,所以通常称为一元类。 + +注意`->`本身,它是一个匿名函数操作符,当它接收一个类型并返回一个类型时,也可以看作是一Kind型。 + +另请注意,不是原子Kind的Kind不是类型。正如 `-1` 是一个数字但 `-` 不是,`Option Int` 是一个类型但 `Option` 不是。 `Option` 等有时被称为类型构造函数。 + +```python +assert not Option in Type +assert Option in Type -> Type +``` + +所以像下面这样的代码会报错: +在 Erg 中,方法只能在原子类型中定义,并且名称 `self` 不能在方法的第一个参数以外的任何地方使用。 + +```python +#K 是一元类型 +K: Type -> Type +K T = Class... +K. +foo x = ... # OK,这就像是所谓的静态方法 + bar self, x = ... # 类型错误: 无法为非类型对象定义方法 +K(T). + baz self, x = ... # OK +``` + +二进制或更高类型的示例是 `{T: U}`(: `(Type, Type) -> Type`), `(T, U, V)`(: `(Type, Type, Type) - > Type `), ... 等等。 + +还有一个零项类型`() -> Type`。 这有时等同于类型论中的原子类型,但在 Erg 中有所区别。 一个例子是`类`。 + +```python +Nil = Class() +``` + +## 收容类 + +多项类型之间也存在部分类型关系,或者更确切地说是部分类型关系。 + +```python +K T = ... +L = Inherit K +L<: K +``` + +也就是说,对于任何 `T`,如果 `L T <: K T`,则 `L <: K`,反之亦然。 + +```python +∀T. L T <: K T <=> L <: K +``` + +## 高阶Kind + +还有一种高阶Kind。 这是一种与高阶函数相同的概念,一种自身接收一种类型。 `(Type -> Type) -> Type` 是一种更高的Kind。 让我们定义一个属于更高Kind的对象。 + +```python +IntContainerOf K: Type -> Type = K Int +assert IntContainerOf Option == Option Int +assert IntContainerOf Result == Result Int +assert IntContainerOf in (Type -> Type) -> Type +``` + +多项式类型的有界变量通常表示为 K, L, ...,其中 K 是 Kind 的 K + +## 设置Kind + +在类型论中,有记录的概念。 这与 Erg 记录 [2](#2) 几乎相同。 + +```python +# 这是一条记录,对应于类型论中所谓的记录 +{x = 1; y = 2} +``` + +当所有的记录值都是类型时,它是一种类型,称为记录类型。 + +```python +assert {x = 1; y = 2} in {x = Int; y = Int} +``` + +记录类型键入记录。 一个好的猜测者可能认为应该有一个“记录类型”来键入记录类型。 实际上它是存在的。 + +```python +log Typeof {x = Int; y = Int} # {{x = Int; y = Int}} +``` + +像 `{{x = Int; 这样的类型 y = Int}}` 是一种记录类型。 这不是一个特殊的符号。 它只是一个枚举类型,只有 `{x = Int; y = Int}` 作为一个元素。 + +```python +Point = {x = Int; y = Int} +Pointy = {Point} +``` + +记录类型的一个重要属性是,如果 `T: |T|` 和 `U <: T` 则 `U: |T|`。 +从枚举实际上是筛子类型的语法糖这一事实也可以看出这一点。 + +```python +# {c} == {X: T | X == c} 对于普通对象,但是不能为类型定义相等性,所以 |T| == {X | X <: T} +{Point} == {P | P <: Point} +``` + +类型约束中的 `U <: T` 实际上是 `U: |T|` 的语法糖。 +作为此类类型的集合的种类通常称为集合种类。 Setkind 也出现在迭代器模式中。 + +```python +Iterable T = Trait { + .Iterator = {Iterator} + .iter = Self(T).() -> Self.Iterator T +} +``` + +## 多项式类型的类型推断 + +```python +Container K: Type -> Type, T: Type = Patch K(T, T) +Container (K). + f self = ... +Option T: Type = Patch T or NoneType +Option(T). + f self = ... +Fn T: Type = Patch T -> T +Fn(T). + f self = ... +Fn2 T, U: Type = Patch T -> U +Fn2(T, U). + f self = ... + +(Int -> Int).f() # 选择了哪一个? +``` +在上面的示例中,方法 `f` 会选择哪个补丁? +天真,似乎选择了`Fn T`,但是`Fn2 T,U`也是可以的,`Option T`原样包含`T`,所以任何类型都适用,`Container K,T`也匹配`->(Int, Int)`,即 `Container(`->`, Int)` 为 `Int -> Int`。因此,上述所有四个修复程序都是可能的选择。 + +在这种情况下,根据以下优先标准选择修复程序。 + +* 任何 `K(T)`(例如 `T or NoneType`)优先匹配 `Type -> Type` 而不是 `Type`。 +* 任何 `K(T, U)`(例如 `T -> U`)优先匹配 `(Type, Type) -> Type` 而不是 `Type`。 +* 类似的标准适用于种类 3 或更多。 +* 选择需要较少类型变量来替换的那个。例如,`Int -> Int` 是 `T -> T` 而不是 `K(T, T)`(替换类型变量:K, T)或 `T -> U`(替换类型变量:T, U )。(替换类型变量:T)优先匹配。 +* 如果更换的次数也相同,则报错为不可选择。 + +--- + +1 在类型理论符号中,`*=>*` [↩](#f1) + +2 可见性等细微差别。[↩](#f2) \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/marker_trait.md b/doc/zh_TW/syntax/type/advanced/marker_trait.md new file mode 100644 index 00000000..67227598 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/marker_trait.md @@ -0,0 +1,31 @@ +# 标记特征 + +标记特征是没有必需属性的特征。 也就是说,您可以在不实现任何方法的情况下实现 Impl。 +没有 required 属性似乎没有意义,但由于注册了它属于 trait 的信息,因此可以使用 patch 方法或由编译器进行特殊处理。 + +所有标记特征都包含在“标记”特征中。 +作为标准提供的“光”是一种标记特征。 + +```python +Light = Subsume Marker +``` + +```python +Person = Class {.name = Str; .age = Nat} and Light +``` + +```python +M = Subsume Marker + +MarkedInt = Inherit Int, Impl := M + +i = MarkedInt.new(2) +assert i + 1 == 2 +assert i in M +``` + +标记类也可以使用 `Excluding` 参数排除。 + +```python +NInt = Inherit MarkedInt, Impl := N, Excluding: M +``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/mut_struct.md b/doc/zh_TW/syntax/type/advanced/mut_struct.md new file mode 100644 index 00000000..e17faa08 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/mut_struct.md @@ -0,0 +1,40 @@ +# 可变结构类型 + +`T!` 类型被描述为可以被任何 `T` 类型对象替换的盒子类型。 + +```python +Particle!State: {"base", "excited"}! = Class(... Impl := Phantom State) +Particle! + # 此方法将状态从“base”移动到“excited” + apply_electric_field!(ref! self("base" ~> "excited"), field: Vector) = ... +``` + +`T!` 类型可以替换数据,但不能改变其结构。 +更像是一个真实程序的行为,它不能改变它的大小(在堆上)。 这样的类型称为不可变结构(mutable)类型。 + +事实上,有些数据结构不能用不变的结构类型来表示。 +例如,可变长度数组。 `[T; N]!`类型可以包含任何`[T; N]`,但不能被`[T; N+1]` 等等。 + +换句话说,长度不能改变。 要改变长度,必须改变类型本身的结构。 + +这是通过可变结构(可变)类型实现的。 + +```python +v = [Str; !0].new() +v.push! "Hello" +v: [Str; !1]. +``` + +对于可变结构类型,可变类型参数用 `!` 标记。 在上述情况下,类型 `[Str; !0]` 可以更改为 `[Str; !1]` 等等。 即,可以改变长度。 +顺便说一句,`[T; !N]` 类型是 `ArrayWithLength!(T, !N)` 类型的糖衣语法。 + +可变结构类型当然可以是用户定义的。 但是请注意,在构造方法方面与不变结构类型存在一些差异。 + +```python +Nil T = Class(Impl := Phantom T) +List T, !0 = Inherit Nil T +List T, N: Nat! = Class {head = T; rest = List(T, !N-1)} +List(T, !N). + push! ref! self(N ~> N+1, ...), head: T = + self.update! old -> Self.new {head; old} +``` diff --git a/doc/zh_TW/syntax/type/advanced/newtype.md b/doc/zh_TW/syntax/type/advanced/newtype.md new file mode 100644 index 00000000..7100c029 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/newtype.md @@ -0,0 +1,31 @@ +# 新类型模式 + +这是 Rust 中常用的 newtype 模式的 Erg 版本。 + +Erg 允许定义类型别名如下,但它们只引用相同的类型。 + +```python +UserID = Int +``` + +因此,例如,如果你有一个规范,类型为 `UserId` 的数字必须是一个正的 8 位数字,你可以输入 `10` 或 `-1`,因为它与类型 `Int` 相同 . 如果设置为 `Nat`,则可以拒绝 `-1`,但 8 位数字的性质不能仅用 Erg 的类型系统来表达。 + +此外,例如,在设计数据库系统时,假设有几种类型的 ID:用户 ID、产品 ID、产品 ID 和用户 ID。 如果 ID 类型的数量增加,例如用户 ID、产品 ID、订单 ID 等,可能会出现将不同类型的 ID 传递给不同函数的 bug。 即使用户 ID 和产品 ID 在结构上相同,但它们在语义上是不同的。 + +对于这种情况,newtype 模式是一个很好的设计模式。 + +```python +UserId = Class {id = Nat} +UserId. + new id: Nat = + assert id.dights().len() == 8, else: "UserId 必须是长度为 8 的正数" + UserId::__new__ {id;} + +i = UserId.new(10000000) +print! i # <__main__.UserId object> +i + UserId.new(10000001) # TypeError: + is not implemented between `UserId` and `UserId +``` + +构造函数保证 8 位数字的前置条件。 +`UserId` 失去了 `Nat` 拥有的所有方法,所以每次都必须重新定义必要的操作。 +如果重新定义的成本不值得,最好使用继承。 另一方面,在某些情况下,方法丢失是可取的,因此请根据情况选择适当的方法。 diff --git a/doc/zh_TW/syntax/type/advanced/overloading.md b/doc/zh_TW/syntax/type/advanced/overloading.md new file mode 100644 index 00000000..373585b0 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/overloading.md @@ -0,0 +1,90 @@ +# 重载 + +Erg 不支持 __ad hoc 多态性__。 也就是说,函数和种类(重载)的多重定义是不可能的。 但是,您可以通过使用特征和补丁的组合来重现重载行为。 +您可以使用特征而不是特征类,但随后将涵盖所有实现 `.add1` 的类型。 + +```python +Add1 = Trait { + .add1: Self.() -> Self +} +IntAdd1 = Patch Int, Impl := Add1 +IntAdd1. + add1 self = self + 1 +RatioAdd1 = Patch Ratio, Impl := Add1 +RatioAdd1. + add1 self = self + 1.0 + +add1|X <: Add1| x: X = x.add1() +assert add1(1) == 2 +assert add1(1.0) == 2.0 +``` + +这种接受一个类型的所有子类型的多态称为__subtyping polymorphism__。 + +如果每种类型的过程完全相同,则可以编写如下。 当行为从类到类(但返回类型相同)时,使用上述内容。 +使用类型参数的多态称为 __parametric polymorphism__。 参数多态性通常与子类型结合使用,如下所示,在这种情况下,它是参数和子类型多态性的组合。 + +```python +add1|T <: Int or Str| x: T = x + 1 +assert add1(1) == 2 +assert add1(1.0) == 2.0 +``` + +此外,可以使用默认参数重现具有不同数量参数的类型的重载。 + +```python +C = Class {.x = Int; .y = Int} +C. + new(x, y := 0) = Self::__new__ {.x; .y} + +assert C.new(0, 0) == C.new(0) +``` + +Erg 的立场是,您不能定义行为完全不同的函数,例如根据参数的数量具有不同的类型,但如果行为不同,则应该以不同的方式命名。 + +综上所述,Erg 禁止重载,采用子类型加参数多态,原因如下。 + +首先,重载函数分布在它们的定义中。 这使得在发生错误时很难报告错误的原因。 +此外,导入子程序可能会改变已定义子程序的行为。 + + +```python +{id; ...} = import "foo" +... +id x: Int = x +... +id x: Ratio = x +... +id "str" # 类型错误:没有为 Str 实现 id +# 但是……但是……这个错误是从哪里来的? +``` + +其次,它与默认参数不兼容。 当具有默认参数的函数被重载时,会出现一个优先级的问题。 + +```python +f x: Int = ... +f(x: Int, y := 0) = ... + +f(1) # 选择哪个? +``` + +此外,它与声明不兼容。 +声明 `f: Num -> Num` 不能指定它引用的定义。 这是因为 `Int -> Ratio` 和 `Ratio -> Int` 不包含在内。 + +```python +f: Num -> Num +f(x: Int): Ratio = ... +f(x: Ratio): Int = ... +``` + +并且语法不一致:Erg禁止变量重新赋值,但是重载的语法看起来像重新赋值。 +也不能用匿名函数代替。 + +```python +# 同 `f = x -> body` +f x = body + +# 一样……什么? +f x: Int = x +f x: Ratio = x +``` diff --git a/doc/zh_TW/syntax/type/advanced/phantom.md b/doc/zh_TW/syntax/type/advanced/phantom.md new file mode 100644 index 00000000..14c95749 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/phantom.md @@ -0,0 +1,56 @@ +# 幻影(phantom)类 + +幻像类型是标记特征,其存在仅用于向编译器提供注释。 +作为幻像类型的一种用法,让我们看一下列表的结构。 + +```python +Nil = Class() +List T, 0 = Inherit Nil +List T, N: Nat = Class {head = T; rest = List(T, N-1)} +``` + +此代码导致错误。 + +```python +3 | List T, 0 = Inherit Nil + ^^^ +类型构造错误:由于Nil没有参数T,所以无法用Nil构造List(T, 0) +提示:使用 'Phantom' 特质消耗 T +``` + +此错误是在使用 `List(_, 0).new Nil.new()` 时无法推断 `T` 的抱怨。 +在这种情况下,无论 `T` 类型是什么,它都必须在右侧使用。 大小为零的类型(例如长度为零的元组)很方便,因为它没有运行时开销。 +```python +Nil T = Class((T; 0)) +List T, 0 = Inherit Nil T +List T, N: Nat = Class {head = T; rest = List(T, N-1)} +``` + +此代码通过编译。 但是理解意图有点棘手,除非类型参数是类型,否则不能使用它。 + +在这种情况下,幻影类型正是您所需要的。 幻像类型是大小为 0 的广义类型。 + +```python +Nil T = Class(Impl := Phantom T) +List T, 0 = Inherit Nil T +List T, N: Nat = Class {head = T; rest = List(T, N-1)} + +nil = Nil(Int).new() +assert nil.__size__ == 0 +``` + +`Phantom` 拥有`T` 类型。 但实际上 `Phantom T` 类型的大小是 0 并且不包含 `T` 类型的对象。 + +此外,`Phantom` 可以使用除其类型之外的任意类型参数。 在下面的示例中,`Phantom` 包含一个名为 `State` 的类型参数,它是 `Str` 的子类型对象。 +同样,`State` 是一个假的类型变量,不会出现在对象的实体中。 + +```python +VM! State: {"stopped", "running"}! = Class(... State) +VM!("stopped"). + start ref! self("stopped" ~> "running") = + self.do_something!() + self::set_phantom!("running")) +``` + +`state` 是通过 `update_phantom!` 或 `set_phantom!` 方法更新的。 +这是标准补丁为`Phantom!`(`Phantom`的变量版本)提供的方法,其用法与变量`update!`和`set!`相同。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/projection.md b/doc/zh_TW/syntax/type/advanced/projection.md new file mode 100644 index 00000000..9ecaf889 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/projection.md @@ -0,0 +1,24 @@ +# 投影类型 + +投影类型表示如下代码中的“Self.AddO”等类型。 + +```python +Add R = Trait { + . `_+_` = Self, R -> Self.AddO + .AddO = Type +} + +AddForInt = Patch(Int, Impl := Add Int) +AddForInt. + AddO = Int +``` + +类型“Add(R)”可以说是定义了与某个对象的加法的类型。 由于方法应该是一个类型属性,`+` 类型声明应该写在缩进下面。 +`Add` 类型的场景是声明 `.AddO = Type`,而 `.AddO` 类型的实体是一个投影类型,由一个作为 ` 子类型的类型持有 添加`。 例如,`Int.AddO = Int`、`Odd.AddO = Even`。 + +```python +assert Int < Add +assert Int.AddO == Int +assert Odd < Add +assert Odd.AddO == Even +``` diff --git a/doc/zh_TW/syntax/type/advanced/quantified_dependent.md b/doc/zh_TW/syntax/type/advanced/quantified_dependent.md new file mode 100644 index 00000000..c96caca5 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/quantified_dependent.md @@ -0,0 +1,27 @@ +# 量化依赖类型 + +Erg 有量化和依赖类型。 那么很自然地,就可以创建一个将两者结合起来的类型。 那是量化的依赖类型。 + +```python +NonNullStr = |N: Nat| StrWithLen N | N ! = 0 # 同 {S | N: Nat; S: StrWithLen N; N ! = 0} +NonEmptyArray = |N: Nat| [_; N | N > 0] # 同 {A | N: Nat; A: Array(_, N); N > 0} +``` + +量化依赖类型的标准形式是“K(A, ... | Pred)”。 `K` 是类型构造函数,`A, B` 是类型参数,`Pred` 是条件表达式。 + +作为左值的量化依赖类型只能在与原始类型相同的模块中定义方法。 + +```python +K A: Nat = Class ... +K(A). + ... +K(A | A >= 1). + method ref! self(A ~> A+1) = ... +``` + +作为右值的量化依赖类型需要在类型变量列表 (`||`) 中声明要使用的类型变量。 + +```python +# T 是具体类型 +a: |N: Nat| [T; N | N > 1] +``` diff --git a/doc/zh_TW/syntax/type/advanced/shared.md b/doc/zh_TW/syntax/type/advanced/shared.md new file mode 100644 index 00000000..ec294166 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/shared.md @@ -0,0 +1,72 @@ +# 共享参考 + +共享引用是必须小心处理的语言特性之一。 +例如,在 TypeScript 中,以下代码将通过类型检查。 + +```typescript +class NormalMember {} +class VIPMember extends NormalMember {} + +let vip_area: VIPMember[] = [] +let normal_area: NormalMember[] = vip_area + +normal_area.push(new NormalMember()) +console.log(vip_area) # [NormalMember] +``` + +一个 NormalMember 已进入 vip_area。 这是一个明显的错误,但是出了什么问题? +原因是共享引用 [denatured](./variance.md)。 `normal_area` 是通过复制 `vip_area` 来创建的,但是这样做的时候类型已经改变了。 +但是 `VIPMember` 继承自 `NormalMember`,所以 `VIPMember[] <: NormalMember[]`,这不是问题。 +关系 `VIPMember[] <: NormalMember[]` 适用于不可变对象。 但是,如果您执行上述破坏性操作,则会出现故障。 + +在 Erg 中,由于所有权系统,此类代码会被回放。 + +```python +NormalMember = Class() +VIPMember = Class() + +vip_area = [].into [VIPMember; !_] +normal_area: [NormalMember; !_] = vip_area + +normal_area.push!(NormalMember.new()) +log vip_area # 所有权错误:`vip_room` 已移至 `normal_room` +``` + +然而,一个对象只属于一个地方可能会很不方便。 +出于这个原因,Erg 有一个类型 `SharedCell!T!`,它代表一个共享状态。 + +```python +$p1 = SharedCell!.new(!1) +$p2 = $p1.mirror!() +$p3 = SharedCell!.new(!1) +# 如果$p1 == $p2,比较内容类型Int! +assert $p1 == $p2 +assert $p1 == $p3 +# 检查 $p1 和 $p2 是否用 `.addr!` 指向同一个东西。 +assert $p1.addr!() == $p2.addr!() +assert $p1.addr!() != $p3.addr!() +$p1.add! 1 +assert $p1 == 2 +assert $p2 == 2 +assert $p3 == 1 +``` + +`SharedCell!` 类型的对象必须以`$` 为前缀。 此外,就其性质而言,它们不可能是常数。 + +`SharedCell! T!` 类型也是 `T!` 的子类型,可以调用 `T!` 类型的方法。 `SharedCell!T!` 类型特有的唯一方法是 `.addr!`、`.mirror!` 和 `.try_take`。 + +一个重要的事实是`SharedCell! T!` 是非变体的,即没有为不同类型的参数定义包含。 + +```python +$vip_area = SharedCell!.new([].into [VIPMember; !_]) +$normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() #类型错误:预期 SharedCell!([NormalMember;!_]),但得到 SharedCell!([VIPMember;!_]) +# 提示:SharedCell!(T) 是非变体的,这意味着它不能有超类型或子类型。 +``` + +但是,下面的代码没有问题。 在最后一行,它是 `VIPMember` 参数已被类型转换 + +```python +$normal_area = SharedCell!.new([].into [NormalMember; !_]) +$normal_area.push!(NormalMember.new()) # OK +$normal_area.push!(VIPMember.new()) # OK +``` diff --git a/doc/zh_TW/syntax/type/advanced/special.md b/doc/zh_TW/syntax/type/advanced/special.md new file mode 100644 index 00000000..92cbeb0b --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/special.md @@ -0,0 +1,51 @@ +# 特殊类型(Self、Super) + +`Self` 代表它自己的类型。 您可以将其用作别名,但请注意派生类型的含义会发生变化(指的是自己的类型)。 + +```python +@Inheritable +C = Class() +C. + new_self() = Self. new() + new_c() = C.new() +D = Inherit C + +classof D. new_self() # D +classof D. new_c() # C +``` + +`Super` 表示基类的类型。方法本身引用基类,但实例使用自己的类型。 + +```python +@Inheritable +C = Class() + +D = Inherit(C) +D. + new_super() = Super.new() + new_c() = C.new() + +classof D. new_super() # D +classof D. new_c() # C +``` + +## 特殊类型变量 + +`Self` 和 `Super` 可以用作结构化类型和特征中的类型变量。 这指的是作为该类型子类型的类。 也就是说,`T` 类型中的`Self` 表示`Self <: T`。 + +```python +Add R = Trait { + .AddO = Type + .`_+_`: Self, R -> Self.AddO +} +ClosedAdd = Subsume Add(Self) + +ClosedAddForInt = Patch(Int, Impl := ClosedAdd) +ClosedAddForInt. + AddO = Int + +assert 1 in Add(Int, Int) +assert 1 in ClosedAdd +assert Int < Add(Int, Int) +assert Int < ClosedAdd +``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/typeof.md b/doc/zh_TW/syntax/type/advanced/typeof.md new file mode 100644 index 00000000..7fd520cd --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/typeof.md @@ -0,0 +1,65 @@ +# Typeof, classof + +`Typeof` 是一个可以窥探 Erg 类型推断系统的函数,它的行为很复杂 + +```python +assert Typeof(1) == {I: Int | I == 1} +i: 1..3 or 5..10 = ... +assert Typeof(i) == {I: Int | (I >= 1 and I <= 3) or (I >= 5 and I <= 10)} + +C = Class {i = Int} +I = C. new {i = 1} +assert Typeof(I) == {X: C | X == I} +J: C = ... +assert Typeof(J) == {i = Int} + +assert {X: C | X == I} < C and C <= {i = Int} +``` + +`Typeof` 函数返回派生类型,而不是对象的类。 +因此,例如 `C = Class T` 类的`I: C`,`Typeof(I) == T`。 +值类没有对应的记录类型。 为了解决这个问题,值类应该是具有 `__valueclass_tag__` 属性的记录类型。 +请注意,您不能访问此属性,也不能在用户定义的类型上定义 `__valueclass_tag__` 属性。 + +```python +i: Int = ... +assert Typeof(i) == {__valueclass_tag__ = Phantom Int} +s: Str = ... +assert Typeof(s) == {__valueclass_tag__ = Phantom Str} +``` + +`Typeof` 仅输出结构化类型。 我解释说结构化类型包括属性类型、筛类型和(真正的)代数类型。 +这些是独立的类型(存在推理优先级),不会发生推理冲突。 +属性类型和代数类型可以跨越多个类,而筛类型是单个类的子类型。 +Erg 尽可能将对象类型推断为筛类型,如果不可能,则将筛基类扩展为结构化类型(见下文)。 + +## 结构化的 + +所有类都可以转换为派生类型。 这称为 __结构化__。 类的结构化类型可以通过 `Structure` 函数获得。 +如果一个类是用`C = Class T`定义的(所有类都以这种形式定义),那么`Structure(C) == T`。 + +```python +C = Class {i = Int} +assert Structure(C) == {i = Int} +D = Inherit C +assert Structure(D) == {i = Int} +Nat = Class {I: Int | I >= 0} +assert Structure(Nat) == {I: Int | I >= 0} +Option T = Class (T or NoneType) +assert Structure(Option Int) == Or(Int, NoneType) +assert Structure(Option) # 类型错误:只能构造单态类型 +# 你实际上不能用 __valueclass_tag__ 定义一条记录,但在概念上 +assert Structure(Int) == {__valueclass_tag__ = Phantom Int} +assert Structure(Str) == {__valueclass_tag__ = Phantom Str} +assert Structure((Nat, Nat)) == {__valueclass_tag__ = Phantom(Tuple(Nat, Nat))} +assert Structure(Nat -> Nat) == {__valueclass_tag__ = Phantom(Func(Nat, Nat))} +# 标记类也是带有 __valueclass_tag__ 的记录类型 +M = Inherit Marker +assert Structure(M) == {__valueclass_tag__ = Phantom M} +D = Inherit(C and M) +assert Structure(D) == {i = Int; __valueclass_tag__ = Phantom M} +E = Inherit(Int and M) +assert Structure(E) == {__valueclass_tag__ = Phantom(And(Int, M))} +F = Inherit(E not M) +assert Structure(F) == {__valueclass_tag__ = Phantom Int} +``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/variance.md b/doc/zh_TW/syntax/type/advanced/variance.md new file mode 100644 index 00000000..26943813 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/variance.md @@ -0,0 +1,142 @@ +# 变化 + +Erg 可以对多态类型进行子类型化,但有一些注意事项。 + +首先,考虑普通多态类型的包含关系。一般来说,有一个容器`K`和它分配的类型`A,B`,当`A < B`时,`K A < K B`。 +例如,`Option Int < Option Object`。因此,在`Option Object`中定义的方法也可以在`Option Int`中使用。 + +考虑典型的多态类型 `Array!(T)`。 +请注意,这一次不是 `Array!(T, N)` 因为我们不关心元素的数量。 +现在,`Array!(T)` 类型具有称为 `.push!` 和 `.pop!` 的方法,分别表示添加和删除元素。这是类型: + +`Array.push!: Self(T).(T) => NoneType` +`Array.pop!: Self(T).() => T` + +可以直观地理解: + +* `Array!(Object).push!(s)` is OK when `s: Str` (just upcast `Str` to `Object`) +* When `o: Object`, `Array!(Str).push!(o)` is NG +* `Array!(Object).pop!().into(Str)` is NG +* `Array!(Str).pop!().into(Object)` is OK + +就类型系统而言,这是 + +* `(Self(Object).(Object) => NoneType) < (Self(Str).(Str) => NoneType)` +* `(Self(Str).() => Str) < (Self(Object).() => Object)` +方法 + +前者可能看起来很奇怪。即使是 `Str < Object`,包含关系在将其作为参数的函数中也是相反的。 +在类型论中,这种关系(`.push!` 的类型关系)称为逆变,反之,`.pop!` 的类型关系称为协变。 +换句话说,函数类型就其参数类型而言是逆变的,而就其返回类型而言是协变的。 +这听起来很复杂,但正如我们之前看到的,如果将其应用于实际示例,这是一个合理的规则。 +如果您仍然不明白,请考虑以下内容。 + +Erg 的设计原则之一是“大输入类型,小输出类型”。这正是函数可变性的情况。 +看上面的规则,输入类型越大,整体类型越小。 +这是因为通用函数明显比专用函数少。 +而且输出类型越小,整体越小。 + +这样一来,上面的策略就相当于说“尽量减少函数的类型”。 + +## 不变性 + +Erg 有另一个修改。它是不变的。 +这是对 `SharedCell! T!`等内置类型的修改。这意味着对于两种类型 `T!, U!` 其中 `T! != U!`,在 `SharedCell! T!` 和 `SharedCell!意思是 +这是因为`SharedCell! T!` 是共享参考。有关详细信息,请参阅 [共享参考](shared.md)。 + +## 变异的泛型类型 + +通用类型变量可以指定其上限和下限。 + +```python +|A <: T| K(A) +|B :> T| K(B) +``` + +在类型变量列表中,执行类型变量的__variant说明__。 在上述变体规范中,类型变量“A”被声明为“T”类型的任何子类,“B”类型被声明为“T”类型的任何超类。 +在这种情况下,`T` 也称为 `A` 的上部类型和 `B` 的下部类型。 + +突变规范也可以重叠。 + +```python +# U U} +``` + +这是使用变量规范的代码示例: + +```python +show|S <: Show| s: S = log s + +Nil T = Class(Impl = Phantom T) +Cons T = Class(Nil T or List T) +List T = Class {head = T; rest = Cons T} +List(T). + push|U <: T|(self, x: U): List T = Self. new {head = x; rest = self} + upcast(self, U :> T): List U = self +``` + +## 更改规范 + +`List T` 的例子很棘手,所以让我们更详细一点。 +要理解上面的代码,你需要了解多态类型退化。 [this section](./variance.md) 中详细讨论了方差,但现在我们需要三个事实: + +* 普通的多态类型,例如`List T`,与`T`是协变的(`List U > List T` when `U > T`) +* 函数 `T -> U` 对于参数类型 `T` 是逆变的(`(S -> U) < (T -> U)` when `S > T`) +* 函数 `T -> U` 与返回类型 `U` 是协变的(`(T -> U) > (T -> S)` 当 `U > S` 时) + +例如,`List Int` 可以向上转换为 `List Object`,而 `Obj -> Obj` 可以向上转换为 `Int -> Obj`。 + +现在让我们考虑如果我们省略方法的变量说明会发生什么。 + +```python +... +List T = Class {head = T; rest = Cons T} +List(T). + # 如果 T > U,列表 T 可以被推入 U + push|U|(self, x: U): List T = Self. new {head = x; rest = self} + # List T 可以是 List U 如果 T < U + upcast(self, U): List U = self +``` + +即使在这种情况下,Erg 编译器也能很好地推断 `U` 的上下类型。 +但是请注意,Erg 编译器不理解方法的语义。编译器只是根据变量和类型变量的使用方式机械地推断和派生类型关系。 + +正如评论中所写,放在`List T`的`head`中的`U`类型是`T`的子类(`T:Int`,例如`Nat`)。也就是说,它被推断为 `U <: T`。此约束将 `.push{U}` upcast `(List(T), U) -> List(T) 的参数类型更改为 (List(T), T) -> List(T)`(例如 disallow `列表(整数).push{对象}`)。但是请注意,`U <: T` 约束不会改变函数的类型包含。 `(List(Int), Object) -> List(Int) to (List(Int), Int) -> List(Int)` 的事实并没有改变,只是在 `.push` 方法中表示强制转换无法执行。 +类似地,从 `List T` 到​​ `List U` 的转换可能会受到约束 `U :> T` 的约束,因此可以推断出变体规范。此约束将 `.upcast(U)` 的返回类型更改为向上转换 `List(T) -> List(T) 到 List(T) -> List(T)`(例如 `List(Object) .upcast(Int )`) 被禁止。 + +现在让我们看看如果我们允许这种向上转换会发生什么。 +让我们反转变性名称。 + +```python +... +List T = Class {head = T; rest = Cons T} +List(T). + push|U :> T|(self, x: U): List T = Self. new {head = x; rest = self} + upcast(self, U :> T): List U = self +# 类型警告:`.push` 中的 `U` 不能接受除 `U == T` 之外的任何内容。 将“U”替换为“T”。 +# 类型警告:`.upcast` 中的 `U` 不能接受除 `U == T` 之外的任何内容。 将“U”替换为“T”。 +``` + +只有当 `U == T` 时,约束 `U <: T` 和修改规范`U :> T` 才满足。 所以这个称号没有多大意义。 +只有“向上转换使得 `U == T`” = “向上转换不会改变 `U` 的位置”实际上是允许的。 + +##附录:用户定义类型的修改 + +默认情况下,用户定义类型的突变是不可变的。 但是,您也可以使用 `Inputs/Outputs` 标记特征指定可变性。 +如果您指定 `Inputs(T)`,则类型相对于 `T` 是逆变的。 +如果您指定 `Outputs(T)`,则类型相对于 `T` 是协变的。 + +```python +K T = Class(...) +assert not K(Str) <= K(Object) +assert not K(Str) >= K(Object) + +InputStream T = Class ..., Impl := Inputs(T) +# 接受Objects的流也可以认为接受Strs +assert InputStream(Str) > InputStream(Object) + +OutputStream T = Class ..., Impl := Outputs(T) +# 输出Str的流也可以认为输出Object +assert OutputStream(Str) < OutputStream(Object) +``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/widening.md b/doc/zh_TW/syntax/type/advanced/widening.md new file mode 100644 index 00000000..91e13f34 --- /dev/null +++ b/doc/zh_TW/syntax/type/advanced/widening.md @@ -0,0 +1,92 @@ +# 类型加宽 + +例如,定义多相关系数如下。 + +```python +ids|T|(x: T, y: T) = x, y +``` + +分配同一类的一对实例并没有错。 +当您分配另一个具有包含关系的类的实例对时,它会向上转换为较大的类并成为相同的类型。 +另外,很容易理解,如果分配了另一个不在包含关系中的类,就会发生错误。 + +```python +assert ids(1, 2) == (1, 2) +assert ids(1, 2.0) == (1.0, 2.0) +ids(1, "a") #TypeError +``` + +现在,具有不同派生类型的类型呢? + +```python +i: Int or Str +j: Int or NoneType +ids(i, j) # ? +``` + +在解释这一点之前,我们必须关注 Erg 的类型系统实际上并不关注(运行时)类这一事实。 + +```python +1: {__valueclass_tag__ = Phantom Int} +2: {__valueclass_tag__ = Phantom Int} +2.0: {__valueclass_tag__ = Phantom Ratio} +"a": {__valueclass_tag__ = Phantom Str} +ids(1, 2): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Int} == {__valueclass_tag__ = Phantom Int} +ids(1, 2.0): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Ratio} == {__valueclass_tag__ = Phantom Ratio} # Int < Ratio +ids(1, "a"): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Str} == Never # 类型错误 +``` + +我看不到该类,因为它可能无法准确看到,因为在 Erg 中,对象的类属于运行时信息。 +例如,一个`Int`或Str`类型的对象的类是`Int`或`Str`,但你只有通过执行才能知道它是哪一个。 +当然,`Int` 类型的对象的类被定义为 `Int`,但是在这种情况下,从类型系统中可见的是 `Int` 的结构类型 `{__valueclass_tag__ = Int}`。 + +现在让我们回到另一个结构化类型示例。 总之,上述代码将导致类型错误,因为类型不匹配。 +但是,如果您使用类型注释进行类型扩展,编译将通过。 + +```python +i: Int or Str +j: Int or NoneType +ids(i, j) # 类型错误:i 和 j 的类型不匹配 +# 提示:尝试扩大类型(例如 ids) +ids(i, j) # OK +``` + +`A 和 B` 有以下可能性。 + +* `A and B == A`:当`A <: B`或`A == B`时。 +* `A and B == B`:当 `A :> B` 或 `A == B` 时。 +* `A and B == {}`:当 `!(A :> B)` 和 `!(A <: B)` 时。 + +`A 或 B` 具有以下可能性。 + +* `A 或 B == A`:当`A :> B` 或`A == B` 时。 +* `A or B == B`:当`A <: B`或`A == B`时。 +* `A 或 B` 是不可约的(独立类型):如果 `!(A :> B)` 和 `!(A <: B)`。 + +## 子程序定义中的类型扩展 + +如果返回类型不匹配,Erg 默认会出错。 + +```python +parse_to_int s: Str = + if not s.is_numeric(): + do parse_to_int::return error("not numeric") +... # 返回 Int 对象 +# 类型错误:返回值类型不匹配 +# 3 | 做 parse_to_int::return error("not numeric") +# └─ Error +# 4 | ... +# └ Int +``` + +为了解决这个问题,需要将返回类型显式指定为 Or 类型 + +```python +parse_to_int(s: Str): Int or Error = + if not s.is_numeric(): + do parse_to_int::return error("not numeric") + ... # 返回 Int 对象 +``` + +这是设计使然,这样您就不会无意中将子例程的返回类型与另一种类型混合。 +但是,如果返回值类型选项是具有包含关系的类型,例如 `Int` 或 `Nat`,它将与较大的对齐。 \ No newline at end of file diff --git a/doc/zh_TW/tips.md b/doc/zh_TW/tips.md new file mode 100644 index 00000000..0646a08a --- /dev/null +++ b/doc/zh_TW/tips.md @@ -0,0 +1,135 @@ +# 提示 + +## 想要更改显示错误的语言 + +请为您的语言下载 Erg。 +但是,外部库可能不支持多种语言。 + +## 只想更改记录的某些属性 + +```python +record: {.name = Str; .age = Nat; .height = CentiMeter} +{height; rest; ...} = record +mut_record = {.height = !height; ...rest} +``` + +## 想要隐藏变量 + +使用 Erg 无法在相同范围内进行遮蔽。 但是,如果范围发生变化,您可以重新定义它们(这是一种称为实例块的语法)。 + +````python +## 获取一个 T!-type 对象,最后将它作为 T 类型赋值给一个变量 +x: T = + x: T! = foo() + x.bar!() + x.freeze() +```` + +## 想以某种方式重用最终类(不可继承的类) + +您可以创建一个包装类。 这就是所谓的构图模式。 + +```python +FinalWrapper = Class {inner = FinalClass} +FinalWrapper. + method self = + self::inner.method() + ... +``` + +## 想使用不是字符串的枚举类型 + +可以定义其他语言中常见的传统枚举类型(代数数据类型)如下 +如果您实现“单例”,则类和实例是相同的。 +此外,如果您使用 `Enum`,则选择的类型会自动定义为重定向属性。 + +```python +Ok = Class Impl := Singleton +Err = Class Impl := Singleton +ErrWithInfo = Inherit {info = Str} +Status = Enum Ok, Err, ErrWithInfo +stat: Status = Status.cons(ErrWithInfo) {info = "error caused by ..."} +match! stat: + Status.Ok -> ... + Status.Err -> ... + Status.ErrWithInfo::{info} -> ... +``` + +```python +Status = Enum Ok, Err, ErrWithInfo +# 相当于 +Status = Class Ok or Err or ErrWithInfo +Status. + Ok = Ok + Err = Err + ErrWithInfo = ErrWithInfo +``` + +## 我想在1开头枚举 + +方法一: + +```python +arr = [...] +for! arr.iter().enumerate(start: 1), i => + ... +``` + +method 2: + +```python +arr = [...] +for! arr.iter().zip(1...) , i => + ... +``` + +## 想要测试一个(白盒)非公共 API + +`foo.er` 中的私有 API 可在 `foo.test.er` 模块中特别访问。 +`foo.test.er` 模块无法导入,因此它保持隐藏状态。 + +```python +# foo.er +private x = ... +``` + +```python +# foo.test.er +foo = import "foo" + +@Test +'testing private' x = + ... + y = foo::private x + ... +``` + +## 想定义一个从外部只读的(变量)属性 + +您可以将属性设为私有并定义一个 getter。 + +```python +C = Class {v = Int!} +C:: + inc_v!(ref! self) = self::v.inc!() + ... +C. + get_v(ref self): Int = self::v.freeze() + ... +``` + +## 希望在类型系统上识别参数名称 + +您可以按记录接收参数。 + +```python +Point = {x = Int; y = Int} + +norm: Point -> Int +norm({x: Int; y: Int}): Int = x**2 + y**2 +assert norm({x = 1; y = 2}) == norm({y = 2; x = 1}) +``` + +## 想要停止警告 + +Erg 中没有停止警告的选项(这是设计使然)。 请重写你的代码。 diff --git a/doc/zh_TW/tools/build.md b/doc/zh_TW/tools/build.md new file mode 100644 index 00000000..7d28452e --- /dev/null +++ b/doc/zh_TW/tools/build.md @@ -0,0 +1,14 @@ +# 构建子命令 + +build 子命令构建包。 +默认构建中执行的步骤如下: + +1. 检查注释/文档中的代码(doc 下的 md 文件) +2. 编译打包所需的代码。 +3. 对于应用程序包,生成批处理文件或相当于命令的shell脚本。 +4. 运行测试。 + +构建完成后的交付物输出到以下目录。 + +* 在调试构建期间:build/debug +* 对于发布构建:build/release \ No newline at end of file diff --git a/doc/zh_TW/tools/env.md b/doc/zh_TW/tools/env.md new file mode 100644 index 00000000..03d2bd48 --- /dev/null +++ b/doc/zh_TW/tools/env.md @@ -0,0 +1,7 @@ +# 环境子命令 + +env 子命令指定 erg 执行环境。 +使用 `erg env new [env name]` 创建一个新的执行环境。 将打开一个交互式工具,当您指定 erg 版本时,将安装该版本的 erg(如果已存在,将使用它),您将能够将其用作新环境。 +您可以使用 `erg env switch [env name]` 切换环境。 +可以使用 `erg env edit` 编辑创建的环境以预安装软件包并指定其他语言的依赖项。 +该命令最大的特点是`erg env export`可以将重现环境的信息输出为`[env name].env.er`文件。 这使您可以立即开始在与其他人相同的环境中进行开发。 此外,`erg env publish` 可以像包一样发布环境。 \ No newline at end of file diff --git a/doc/zh_TW/tools/fmt.md b/doc/zh_TW/tools/fmt.md new file mode 100644 index 00000000..b24ecae8 --- /dev/null +++ b/doc/zh_TW/tools/fmt.md @@ -0,0 +1,6 @@ +# fmt + +可以使用 fmt 子命令来完成代码格式化。 +常用的标志有: + +* 显式类型:在省略类型说明的情况下自动完成。 \ No newline at end of file diff --git a/doc/zh_TW/tools/index.md b/doc/zh_TW/tools/index.md new file mode 100644 index 00000000..e69de29b diff --git a/doc/zh_TW/tools/install.md b/doc/zh_TW/tools/install.md new file mode 100644 index 00000000..fa0a8b5d --- /dev/null +++ b/doc/zh_TW/tools/install.md @@ -0,0 +1,10 @@ +# 安装子命令 + +您可以使用 install 安装在注册表站点上注册的软件包。 +基本用法与cargo等包管理器相同。 + +## 便利功能 + +* 如果有同名的包名,且下载次数超过该包名的10倍以上,会提示可能输入错误。 这可以防止拼写错误。 +* 如果包很大(超过 50MB),请显示大小并建议您是否真的要安装它。 +* 如果包装重复,建议使用替代包装。 \ No newline at end of file diff --git a/doc/zh_TW/tools/pack.md b/doc/zh_TW/tools/pack.md new file mode 100644 index 00000000..9679e502 --- /dev/null +++ b/doc/zh_TW/tools/pack.md @@ -0,0 +1,100 @@ +# 包管理器 + +Erg 标配有一个包管理器,您可以使用 `pack` 子命令调用它。 +以下是典型的选项。 + +* `erg pack init`:将当前目录初始化为一个包。会生成一个 `package.er` 文件和一个 `src` 目录。指定 `app` 将产生一个可执行包,`lib` 将产生一个库包,而 `hybrid` 将产生两个包。如果指定了 `--license`,将自动放置许可文件。 +* `erg pack build`:构建一个包。使用 `--release` 可以运行和优化测试。工件放置在 `build/debug` 或 `build/release` 中。 +* `erg pack install`:安装一个包。在库的情况下,`src` 被放置在 `.erg/lib` 中,而应用程序作为 shell 脚本被放置在 `.erg/app` 中。使用 `--release` 进行优化。 +* `erg pack run`:构建包并运行应用程序(仅限应用程序包)。 +* `erg pack clean`:删除构建目录的内容。 +* `erg pack test`:运行包测试。有关详细信息,请参阅 [test.md](./test.md)。 +* `erg pack publish`:发布/发布包。您将需要一个 GitHub 帐户和公钥。 + +本文档解释了如何管理您自己的包。 +如果要安装或搜索外部包,请参阅 [install.md](./install.md)。 +另请参阅 [package_system.md](../syntax/33_package_system.md) 了解 Erg 包系统。 + +## 整个包的标准目录结构(对于应用程序包) + +```console +/package # package root directory + /build # Directory to store build results + /debug # Artifacts during debug build + /release # Artifacts of release build + /doc # Documents (in addition, by dividing into subdirectories such as `en`, `ja` etc., it is possible to correspond to each language) + /src # source code + /main.er # file that defines the main function + /tests # Directory to store (black box) test files + /package.er # file that defines package settings +``` + +## package.er + +`erg pack init` 将生成如下所示的 `package.er` 文件。 `package.er` 描述了包的配置。 +下面是一个`package.er`的例子。 + +```python +name = "example" # package 名称 +author = "John Smith" # package 作者名称 +version="0.1.0" +description = "An awesome package" +categories = ["cli"] # package 类别 +type = "app" # "app" 或者 "lib" +license = "" # 例如"MIT", "APACHE-2.0", "MIT OR Apache-2.0" +pre_build = "" # 构建前要执行的脚本文件名 +post_build = "" # 构建后要执行的脚本文件名 +dependencies = { + # 如果不指定版本,则选择最新的 + # 如果省略版本说明,包管理器会自动将上次成功构建的版本添加到注释中 + foo = pack("foo") # [INFO] 最后成功构建的版本:1.2.1 + # 包可以重命名 + bar1 = pack("bar", "1.*.*") # [INFO] 最后成功构建的版本:1.2.0 + bar2 = pack("bar", "2.*.*") # [INFO] 最后成功构建的版本:2.0.0 + baz = pack("baz", "1.1.0") +} +deprecated=False +successors = [] # 替代包(当一个包被弃用时) +``` + +## 语义版本控制 + +Erg 包是基于 [语义版本控制](https://semver.org/lang/en/) 进行版本控制的。 +语义版本控制大致以“x.y.z”格式指定(x、y、z 是大于或等于 0 的整数)。 +每个数字的含义如下。 + +* x:主要版本(更新破坏兼容性时增加 1) +* y:次要版本(执行兼容更新时增加1(API添加,弃用等),错误修复等由补丁版本升级处理) +* z:补丁版本(当进行小的更改以修复错误或保持兼容性时增加1,破坏兼容性的严重修复由主要版本升级处理) + +但是,默认情况下,版本 `0.*.*` 中的更改始终是不兼容的。如果要在保持兼容性的同时升级,请在其后指定 `-compatible`(Erg 自己的规则)。例如,如果要在保持与 0.2.1 兼容的同时添加功能,即要升级到 0.3.0,则指定 0.3.0-compatible。如果您已修复错误,还请指定“0.2.2-compatible”。 +该版本将被视为与以前的版本兼容。 +即使您想将 `0.*.*` 升级到 `1.0.0`,这仍然有效。也就是说,`1.0.0-compatible` 与之前的版本 `0.y.z` 兼容。 + +生成锁文件时,语义版本控制非常重要。锁定文件是为保持依赖项兼容而生成的文件,因此除非明确更新,否则较新版本的依赖项依赖于较旧的包。 +当多人开发具有依赖包的包时,锁定文件很有用。它还通过允许依赖于它们的包在兼容的情况下重用包来节省本地存储。 + +Erg 的包管理器严格执行这些规则,并将拒绝违反这些规则的包更新。 +Erg 包管理器与版本控制系统(例如 git)一起使用,以检测代码差异并在发布包时验证版本控制的正确性。 +具体来说,包管理器会查看 API 的类型。如果类型是旧版本的子类型,则认为更改是兼容的(请注意,这不是完整的验证;类型兼容但语义上不兼容的重大更改是可能的,这是开发人员的工作来确定这一点)。 + +此外,由于整个包存储库都在注册表中注册,即使是开发人员也无法在不通过包管理器的情况下更新包。 +此外,包可以被弃用但不能被删除。 + +### 附录:语义版本控制问题和对策 + +语义版本控制存在(至少)两个已知问题。 +首先,语义版本控制可能过于严格。 +使用语义版本控制,单个不兼容的 API 更改会增加整个包的主要版本。 +发生这种情况时,诸如“我想尝试一个新的 API,但我必须处理另一个不兼容的 API 更改,所以我不会升级”之类的事情。 +其次,语义版本控制可以承诺太多。 +如上一节所述,对 API 的“兼容更改”在理论上是不可证明的。如果您指定要使用版本为 `1.0.1` 的包,则可以在语义版本控制方面使用 `1.0.1` 和 `2.0.0` 之间的任何包(`1.0.0` 不能被使用,因为错误已被修复),但由于包开发人员无意使用 API,构建可能不会成功。 + +Erg 通过允许同时使用不同版本的包(通过重命名)解决了这个问题。这使得在部分引入 ver2 API 的同时继续使用 ver1 API 成为可能。 +此外,虽然这不是一个非常理想的状态,但如果只能使用 API 的某个次要版本而没有错误,则可以不理会它并继续前进到下一个版本。 + +## 发布 + +可以使用 `publish` 子命令发布包。发布需要 GitHub 帐户。 +默认情况下,包使用 `(owner_name)/(package_name)` 注册。如果满足一定条件(下载次数、维护频率等),可以申请注册一个省略所有者名称的别名。 +请注意,包名称不区分大小写,并且不区分诸如 `_` 和 `-` 之类的分隔符。 \ No newline at end of file diff --git a/doc/zh_TW/tools/repl.md b/doc/zh_TW/tools/repl.md new file mode 100644 index 00000000..94fab78f --- /dev/null +++ b/doc/zh_TW/tools/repl.md @@ -0,0 +1,15 @@ +# REPL + +运行不带参数的 `erg` 命令会调用 REPL。 它也可以用 `repl` 子命令调用。 +此外,您可以指定以下标志: + +* typed:显示对象及其类型。 + +```console +$ erg repl --typed +Erg interpreter ... (tags/?:, ...) on ... +>>> 1 +1: {1} +>>> id x = x +id = : |T: Type| T -> T +``` \ No newline at end of file diff --git a/doc/zh_TW/tools/test.md b/doc/zh_TW/tools/test.md new file mode 100644 index 00000000..886473f5 --- /dev/null +++ b/doc/zh_TW/tools/test.md @@ -0,0 +1,45 @@ +# 测试子命令 + +erg 命令有一个名为 test 的子命令,它支持测试的实现和执行。 + +## 测试装饰器 (@Test) + +Erg 使用 `erg test` 命令测试包中 `tests` 目录或 `*.test.er` 文件中的 `@Test` 子例程。 +`tests` 子例程负责黑盒测试(不测试私有函数),`*.test.er` 子例程负责白盒测试(也测试私有函数)。 + +```python +# tests/test1.er +{add; ...} = import "foo" + +@Test +test_1_plus_n(n: Nat) = + assert add(1, n) == n + 1 +``` + +执行结果以摘要形式显示,可以以各种文件格式(.md、.csv 等)输出。 + +## 文档测试 + +在 Erg 中,`#` 和 `#[` 是注释行,但 `##` 和 `#[[` 是 doc 注释,并且注释可以从 VSCode 等编辑器显示为 markdown。 +此外,如果指定了 erg,则使用 erg test 命令自动测试文档注释中的源代码。 +下面是一个示例测试。 + +```python +VMs =... + ... + #[[ + execute commands. + ```python + # 标准配置的虚拟机 + {vm1; ...} = import "tests/mock" + + assert vm1.exec!("i = 0") == None + assert vm1.exec!("i").try_into(Int)? == 0 + ``` + ]]# + .exec! ref self, src = + ... + ... +``` + +用于测试的模拟对象(mock objects)在 `tests/mock` 模块中定义。 \ No newline at end of file From 68054846e20b4cdb0e92e986b1b86fcc77de8bcd Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Mon, 5 Sep 2022 21:18:51 +0800 Subject: [PATCH 25/42] trifle --- doc/EN/syntax/indexes.md | 275 ---------------------------- doc/zh_CN/compiler/inference.md | 2 +- doc/zh_CN/compiler/parsing.md | 2 +- doc/zh_CN/dev_guide/unify_terms.md | 2 +- doc/zh_CN/faq_general.md | 14 +- doc/zh_CN/faq_technical.md | 6 +- doc/zh_CN/improved_points.md | 4 +- doc/zh_CN/index.md | 2 +- doc/zh_CN/syntax/17_mutability.md | 2 +- doc/zh_CN/syntax/indexes.md | 278 +---------------------------- doc/zh_CN/syntax/quick_tour.md | 12 +- doc/zh_CN/tips.md | 12 +- doc/zh_CN/tools/env.md | 2 +- doc/zh_CN/tools/install.md | 2 +- doc/zh_CN/tools/pack.md | 28 +-- doc/zh_CN/tools/test.md | 6 +- doc/zh_TW/compiler/inference.md | 2 +- doc/zh_TW/compiler/parsing.md | 2 +- doc/zh_TW/dev_guide/unify_terms.md | 2 +- doc/zh_TW/faq_general.md | 14 +- doc/zh_TW/faq_technical.md | 6 +- doc/zh_TW/improved_points.md | 4 +- doc/zh_TW/index.md | 2 +- doc/zh_TW/syntax/17_mutability.md | 2 +- doc/zh_TW/syntax/indexes.md | 278 +---------------------------- doc/zh_TW/syntax/quick_tour.md | 12 +- doc/zh_TW/tips.md | 12 +- doc/zh_TW/tools/env.md | 2 +- doc/zh_TW/tools/install.md | 2 +- doc/zh_TW/tools/pack.md | 28 +-- doc/zh_TW/tools/test.md | 6 +- 31 files changed, 98 insertions(+), 925 deletions(-) diff --git a/doc/EN/syntax/indexes.md b/doc/EN/syntax/indexes.md index 5d3d19df..9af73d64 100644 --- a/doc/EN/syntax/indexes.md +++ b/doc/EN/syntax/indexes.md @@ -175,278 +175,3 @@ See [here](../dev_guide/terms.md) for terminology. ### Z -## A line - -* 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 - -* [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 line - -* 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 - -* [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 - -* [Comprehension](./27_comprehension.md) -* ~~Infix operator~~ → [Infix operator] -* [namespace] - -## is a line - -* [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 - -* ~~ prefix operator ~~ → prefix operator -* [Marker type](./type/advanced/marker_trait.md) -* [anonymous function](./21_lambda.md) -* mutable → [mutable] -* [Move] -* 方法 -* Metacharacter -* [module](./24_module.md) -* [String] → [Str] - * [String interpolation](./01_literal.md/#str literal) -* Return value - -## or line - -* [Ghost type](./type/advanced/phantom.md) -* request attributes -* [element] -* [call] - -## Ra line - -* [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 - -* Wildcard \ No newline at end of file diff --git a/doc/zh_CN/compiler/inference.md b/doc/zh_CN/compiler/inference.md index 40aaf89b..d40a5298 100644 --- a/doc/zh_CN/compiler/inference.md +++ b/doc/zh_CN/compiler/inference.md @@ -96,7 +96,7 @@ pub enum Type { 让我们将未绑定类型变量 `?T` 泛化为 `gen` 的操作表示。令生成的广义类型变量为 `|T: Type| T`。 在类型论中,量化类型,例如多相关类型 `α->α`,通过在它们前面加上 `∀α.` 来区分(像 ∀ 这样的符号称为(通用)量词。)。 这样的表示(例如`∀α.α->α`)称为类型方案。 Erg 中的类型方案表示为 `|T: Type| T -> T`。 -类型方案通常不被认为是一流的类型。以这种方式配置类型系统可以防止类型推断起作用。但是,在尔格中,在一定条件下可以算是一流的类型。有关详细信息,请参阅 [rank2 类型](../syntax/type/advanced/rank2type.md)。 +类型方案通常不被认为是一流的类型。以这种方式配置类型系统可以防止类型推断起作用。但是,在Erg中,在一定条件下可以算是一流的类型。有关详细信息,请参阅 [rank2 类型](../syntax/type/advanced/rank2type.md)。 现在,当在使用它的类型推断(例如,`id 1`,`id True`)中使用获得的类型方案(例如`'T -> 'T(id's type scheme)`)时,必须释放generalize。这种逆变换称为 __instantiation__。我们将调用操作`inst`。 diff --git a/doc/zh_CN/compiler/parsing.md b/doc/zh_CN/compiler/parsing.md index c790e086..aa540a33 100644 --- a/doc/zh_CN/compiler/parsing.md +++ b/doc/zh_CN/compiler/parsing.md @@ -2,7 +2,7 @@ ## 空格的处理 -尔格语法的一个特点是它对空间敏感。 +Erg语法的一个特点是它对空间敏感。 这是为了弥补因省略`()`而造成的表达力损失。在 Nim 中可以找到类似的语法,它也允许省略 `()`。 ```python diff --git a/doc/zh_CN/dev_guide/unify_terms.md b/doc/zh_CN/dev_guide/unify_terms.md index 2c8e49f5..1a8a2dba 100644 --- a/doc/zh_CN/dev_guide/unify_terms.md +++ b/doc/zh_CN/dev_guide/unify_terms.md @@ -23,7 +23,7 @@ * 符号:在源代码中实心编写的字符(符号、控制字符等除外),不是字符串对象(未包含在“”中)。符号在 Ruby、Lisp 等中作为原始类型存在,但在 Erg 中它们不被视为对象。 * 标识符:(并且可以)引用某个对象的符号,而不是保留字。例如,在 Python 中 class 和 def 不能用作标识符。由于 Erg 没有保留字,所以除了某些符号外,所有符号都可以用作标识符。 * 名称:与标识符的含义几乎相同。它有时与 Erg 中的代数同义使用。 -* 代数名称:相当于尔格中的标识符。在 C 中,函数名称是标识符,而不是代数名称。 “代数”指的是语言特性本身,它允许您使用 `=`(变量赋值运算符)或 `=`(常量赋值运算符)来分配对象。 +* 代数名称:相当于Erg中的标识符。在 C 中,函数名称是标识符,而不是代数名称。 “代数”指的是语言特性本身,它允许您使用 `=`(变量赋值运算符)或 `=`(常量赋值运算符)来分配对象。 ```python 代数名称<:(名称==标识符)​​<:符号 diff --git a/doc/zh_CN/faq_general.md b/doc/zh_CN/faq_general.md index c5ab4ee3..8d1166e1 100644 --- a/doc/zh_CN/faq_general.md +++ b/doc/zh_CN/faq_general.md @@ -1,16 +1,16 @@ -# 尔格常见问题 +# Erg常见问题 此常见问题解答适用于一般 Erg 初学者。 -对于个别(常见)技术问题,请参阅 [此处](./faq_technical.md) 了解个别(常见)技术问题,以及 +对于个别(常见)技术问题,请参阅 [此处](./faq_technical.md) 了解个别(常见)技术问题,以及 [这里](./dev_guide/faq_syntax.md) 了解更多信息。 ## Erg 是 Python 兼容语言是什么意思? -~~A:Erg的可执行系统EVM(Erg VirtualMachine)执行Erg字节码,是Python字节码的扩展。它在 Python 字节码中引入了静态类型系统和其他特性(例如向不带参数的指令引入参数,以及在自由编号中实现唯一指令)。这让 Erg 可以无缝调用 Python 代码并快速执行。~~ +~~A:Erg的可执行系统EVM(Erg VirtualMachine)执行Erg字节码,是Python字节码的扩展。它在 Python 字节码中引入了静态类型系统和其他特性(例如向不带参数的指令引入参数,以及在自由编号中实现唯一指令)。这让 Erg 可以无缝调用 Python 代码并快速执行。~~ -A: Erg 代码被转译成 Python 字节码。也就是说,它运行在与 Python 相同的解释器上。最初,我们计划开发一个兼容 Cpython 的解释器,并将其与编译器结合起来形成“Erg”。但是,由于处理系统的发展远远落后于编译器,我们决定提前只发布编译器(但解释器仍在开发中)。 +A: Erg 代码被转译成 Python 字节码。也就是说,它运行在与 Python 相同的解释器上。最初,我们计划开发一个兼容 Cpython 的解释器,并将其与编译器结合起来形成“Erg”。但是,由于处理系统的发展远远落后于编译器,我们决定提前只发布编译器(但解释器仍在开发中)。 -## 哪些语言影响了尔格? +## 哪些语言影响了Erg? 我们受到的语言多于我们双手所能指望的数量,但 Python、Rust、Nim 和 Haskell 的影响最大。 我们从 Python 继承了许多语义,从 Rust 继承了面向表达式和 trait,从 Nim 继承了过程,从 Haskell 继承了函数式编程相关的特性。 @@ -22,7 +22,7 @@ Julia 是可以有类型的,但它确实是一种动态类型语言,不具 ## Erg 支持多种编程风格,包括函数式和面向对象的编程。这不是与 Python 的“应该有一种——最好只有一种——明显的方法”相反吗? -答:在 Erg 中,该术语是在更狭窄的上下文中使用的。例如,Erg API 中一般没有别名;在这种情况下,尔格是“唯一一种方式”。 +答:在 Erg 中,该术语是在更狭窄的上下文中使用的。例如,Erg API 中一般没有别名;在这种情况下,Erg是“唯一一种方式”。 在更大的上下文中,例如 FP 或 OOP,只有一种做事方式并不一定很方便。 例如,JavaScript 有几个库可以帮助创建不可变的程序,而 C 有几个用于垃圾收集的库。 然而,即使是这样的基本功能也有多个库不仅需要时间来选择,而且在集成使用不同库的代码时也会产生很大的困难。 @@ -34,4 +34,4 @@ Julia 是可以有类型的,但它确实是一种动态类型语言,不具 它以cgs单位系统中的能量单位erg命名。它具有双重含义:一种为程序员提供能量的符合人体工程学的语言。 -还有其他几个候选者,但之所以选择它是因为它最短(根据 Ruby 的开发者 Matz 的说法,语言名称越短越好)并且具有相当高的可搜索性。 \ No newline at end of file +还有其他几个候选者,但之所以选择它是因为它最短(根据 Ruby 的开发者 Matz 的说法,语言名称越短越好)并且具有相当高的可搜索性。 \ No newline at end of file diff --git a/doc/zh_CN/faq_technical.md b/doc/zh_CN/faq_technical.md index 5c73524e..813cce5f 100644 --- a/doc/zh_CN/faq_technical.md +++ b/doc/zh_CN/faq_technical.md @@ -17,11 +17,11 @@ ## Never、{}、None、()、NotImplemented 和 Ellipsis 有什么区别? -A:`Never` 是一种“不可能”的类型。产生运行时错误的子例程将“Never”(或“Never”的合并类型)作为其返回类型。该程序将在检测到这一点后立即停止。尽管 `Never` 类型在定义上也是所有类型的子类,但 `Never` 类型的对象永远不会出现在 Erg 代码中,也永远不会被创建。 `{}` 等价于 `Never`。 +A:`Never` 是一种“不可能”的类型。产生运行时错误的子例程将“Never”(或“Never”的合并类型)作为其返回类型。该程序将在检测到这一点后立即停止。尽管 `Never` 类型在定义上也是所有类型的子类,但 `Never` 类型的对象永远不会出现在 Erg 代码中,也永远不会被创建。 `{}` 等价于 `Never`。 `Ellipsis` 是一个表示省略号的对象,来自 Python。 `NotImplemented` 也来自 Python。它被用作未实现的标记,但 Erg 更喜欢产生错误的 `todo` 函数。 `None` 是 `NoneType` 的一个实例。它通常与 `Option` 类型一起使用。 -`()` 是一个单元类型和它自己的一个实例。当您想要返回“无意义的值”(例如过程的返回值)时使用它。 +`()` 是一个单元类型和它自己的一个实例。当您想要返回“无意义的值”(例如过程的返回值)时使用它。 ## 为什么 `x = p!()` 有效但 `f() = p!()` 会导致 EffectError? @@ -31,4 +31,4 @@ A:`Never` 是一种“不可能”的类型。产生运行时错误的子例 ## 当我尝试使用 Python API 时,对于在 Python 中有效的代码,我在 Erg 中收到类型错误。这是什么意思? A:Erg API 的类型尽可能接近 Python API 规范,但有些情况无法完全表达。 -此外,根据规范有效但被认为不合需要的输入(例如,在应该输入 int 时输入浮点数)可能会被 Erg 开发团队酌情视为类型错误。 \ No newline at end of file +此外,根据规范有效但被认为不合需要的输入(例如,在应该输入 int 时输入浮点数)可能会被 Erg 开发团队酌情视为类型错误。 \ No newline at end of file diff --git a/doc/zh_CN/improved_points.md b/doc/zh_CN/improved_points.md index b137aad2..dcea4a90 100644 --- a/doc/zh_CN/improved_points.md +++ b/doc/zh_CN/improved_points.md @@ -1,6 +1,6 @@ # Python 的改进 -## 执行静态分析(静态类型检查、变量和属性检查) +## 执行静态分析(静态类型检查、变量和属性检查) 静态类型检查的好处现在怎么强调都不为过,但是检查变量和属性的存在也是相当重要的一部分。 @@ -35,7 +35,7 @@ assert i is not 257 就像 Java 的接口一样,你可以进行基于契约的编程。 -Python 也有 ABC(抽象基类),但这种结构最适合静态类型。 +Python 也有 ABC(抽象基类),但这种结构最适合静态类型。 ## 静态解决依赖关系 diff --git a/doc/zh_CN/index.md b/doc/zh_CN/index.md index e35146b5..c7d9e9ae 100644 --- a/doc/zh_CN/index.md +++ b/doc/zh_CN/index.md @@ -6,7 +6,7 @@ ## [compiler/](./compiler/index.md) - 描述 Erg 编译器的设计(厘米) + 描述 Erg 编译器的设计(厘米) ## [dev_guide/](./dev_guide/index.md) diff --git a/doc/zh_CN/syntax/17_mutability.md b/doc/zh_CN/syntax/17_mutability.md index 25145f88..3d89fad4 100644 --- a/doc/zh_CN/syntax/17_mutability.md +++ b/doc/zh_CN/syntax/17_mutability.md @@ -96,7 +96,7 @@ match! x: 变量和标识符之间的区别在于,如果我们在 Erg 的语法理论意义上谈论变量,则两者实际上是相同的。 在 C 中,类型和函数不能分配给变量; int 和 main 是标识符,而不是变量(严格来说可以赋值,但有限制)。 -然而,在尔格语中,“一切都是对象”。不仅函数和类型,甚至运算符都可以分配给变量。 +然而,在Erg语中,“一切都是对象”。不仅函数和类型,甚至运算符都可以分配给变量。

上一页 | 下一页 diff --git a/doc/zh_CN/syntax/indexes.md b/doc/zh_CN/syntax/indexes.md index 54ba47a3..b60d9945 100644 --- a/doc/zh_CN/syntax/indexes.md +++ b/doc/zh_CN/syntax/indexes.md @@ -173,280 +173,4 @@ ### Y -### 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) - -## 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函数) -* 逗号 → [,] - -## 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) - * 封闭式通用 - * 打开通用 - * 通用函数 → 多相关函数 - * 通用量化 -* 前缀运算符 -* 相互递归 -* 下标 → [索引] -* [属性] - * [属性子类型] - -## 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) - -## 没有一行 - -* [理解](./27_comprehension.md) -* ~~中缀运算符~~ → [中缀运算符] -* [命名空间] - -## is a line - -* [数组](./10_array.md) -* [派生类型](./type/variances.md/#用户定义的类型变体) -* [模式(匹配)](./26_pattern_matching.md) -* [包](./33_package_ssystem.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) -* 底部 - * 底部类型 → [{}] - * 底层 → [从不] -* [多态性] - -## ma line - -* ~~ 前缀运算符 ~~ → 前缀运算符 -* [标记类型](./type/advanced/marker_trait.md) -* [匿名函数](./21_lambda.md) -* 可变 → [可变] -* [移动] -* 方法 -* 元字符 -* [模块](./24_module.md) -* [字符串] → [字符串] - * [字符串插值](./01_literal.md/#str字面量) -* 返回值 - -## or line - -* [幽灵类型](./type/advanced/phantom.md) -* 请求属性 -* [元素] -* [称呼] - -## 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) - -## line - -* 通配符 \ No newline at end of file +### Z \ No newline at end of file diff --git a/doc/zh_CN/syntax/quick_tour.md b/doc/zh_CN/syntax/quick_tour.md index 886c4f8c..e891c70f 100644 --- a/doc/zh_CN/syntax/quick_tour.md +++ b/doc/zh_CN/syntax/quick_tour.md @@ -76,7 +76,7 @@ assert i == 1 print! 1 # 1 ``` -## 泛型函数(多相关) +## 泛型函数(多相关) ```python id|T|(x: T): T = x @@ -86,7 +86,7 @@ id("a"): Str ## 记录 -您可以使用类似 ML 的语言中的记录等价物(或 JS 中的对象字面量)。 +您可以使用类似 ML 的语言中的记录等价物(或 JS 中的对象字面量)。 ```python p = {x = 1; y = 2} @@ -94,7 +94,7 @@ p = {x = 1; y = 2} ## 所有权 -Ergs 由可变对象(使用 `!` 运算符突变的对象)拥有,并且不能从多个位置重写。 +Ergs 由可变对象(使用 `!` 运算符突变的对象)拥有,并且不能从多个位置重写。 ```python i = !0 @@ -164,7 +164,7 @@ name = match num: _ -> "unnamed" ``` -### 丢弃(通配符)模式 +### 丢弃(通配符)模式 ```python _ = 1 @@ -188,7 +188,7 @@ assert first(1, 2, 3) == 1 ```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) -# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) +# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) m, n = 1, 2 ``` @@ -258,7 +258,7 @@ Point. Nat = {I: Int | I >= 0} ``` -## 带值的参数类型(依赖类型) +## 带值的参数类型(依赖类型) ```python a: [Int; 3] diff --git a/doc/zh_CN/tips.md b/doc/zh_CN/tips.md index 0646a08a..7d8264bc 100644 --- a/doc/zh_CN/tips.md +++ b/doc/zh_CN/tips.md @@ -15,7 +15,7 @@ mut_record = {.height = !height; ...rest} ## 想要隐藏变量 -使用 Erg 无法在相同范围内进行遮蔽。 但是,如果范围发生变化,您可以重新定义它们(这是一种称为实例块的语法)。 +使用 Erg 无法在相同范围内进行遮蔽。 但是,如果范围发生变化,您可以重新定义它们(这是一种称为实例块的语法)。 ````python ## 获取一个 T!-type 对象,最后将它作为 T 类型赋值给一个变量 @@ -25,7 +25,7 @@ x: T = x.freeze() ```` -## 想以某种方式重用最终类(不可继承的类) +## 想以某种方式重用最终类(不可继承的类) 您可以创建一个包装类。 这就是所谓的构图模式。 @@ -39,7 +39,7 @@ FinalWrapper. ## 想使用不是字符串的枚举类型 -可以定义其他语言中常见的传统枚举类型(代数数据类型)如下 +可以定义其他语言中常见的传统枚举类型(代数数据类型)如下 如果您实现“单例”,则类和实例是相同的。 此外,如果您使用 `Enum`,则选择的类型会自动定义为重定向属性。 @@ -83,7 +83,7 @@ for! arr.iter().zip(1...) , i => ... ``` -## 想要测试一个(白盒)非公共 API +## 想要测试一个(白盒)非公共 API `foo.er` 中的私有 API 可在 `foo.test.er` 模块中特别访问。 `foo.test.er` 模块无法导入,因此它保持隐藏状态。 @@ -104,7 +104,7 @@ foo = import "foo" ... ``` -## 想定义一个从外部只读的(变量)属性 +## 想定义一个从外部只读的(变量)属性 您可以将属性设为私有并定义一个 getter。 @@ -132,4 +132,4 @@ assert norm({x = 1; y = 2}) == norm({y = 2; x = 1}) ## 想要停止警告 -Erg 中没有停止警告的选项(这是设计使然)。 请重写你的代码。 +Erg 中没有停止警告的选项(这是设计使然)。 请重写你的代码。 diff --git a/doc/zh_CN/tools/env.md b/doc/zh_CN/tools/env.md index 03d2bd48..ada55481 100644 --- a/doc/zh_CN/tools/env.md +++ b/doc/zh_CN/tools/env.md @@ -1,7 +1,7 @@ # 环境子命令 env 子命令指定 erg 执行环境。 -使用 `erg env new [env name]` 创建一个新的执行环境。 将打开一个交互式工具,当您指定 erg 版本时,将安装该版本的 erg(如果已存在,将使用它),您将能够将其用作新环境。 +使用 `erg env new [env name]` 创建一个新的执行环境。 将打开一个交互式工具,当您指定 erg 版本时,将安装该版本的 erg(如果已存在,将使用它),您将能够将其用作新环境。 您可以使用 `erg env switch [env name]` 切换环境。 可以使用 `erg env edit` 编辑创建的环境以预安装软件包并指定其他语言的依赖项。 该命令最大的特点是`erg env export`可以将重现环境的信息输出为`[env name].env.er`文件。 这使您可以立即开始在与其他人相同的环境中进行开发。 此外,`erg env publish` 可以像包一样发布环境。 \ No newline at end of file diff --git a/doc/zh_CN/tools/install.md b/doc/zh_CN/tools/install.md index fa0a8b5d..f59145b5 100644 --- a/doc/zh_CN/tools/install.md +++ b/doc/zh_CN/tools/install.md @@ -6,5 +6,5 @@ ## 便利功能 * 如果有同名的包名,且下载次数超过该包名的10倍以上,会提示可能输入错误。 这可以防止拼写错误。 -* 如果包很大(超过 50MB),请显示大小并建议您是否真的要安装它。 +* 如果包很大(超过 50MB),请显示大小并建议您是否真的要安装它。 * 如果包装重复,建议使用替代包装。 \ No newline at end of file diff --git a/doc/zh_CN/tools/pack.md b/doc/zh_CN/tools/pack.md index 9679e502..59f35f19 100644 --- a/doc/zh_CN/tools/pack.md +++ b/doc/zh_CN/tools/pack.md @@ -6,7 +6,7 @@ Erg 标配有一个包管理器,您可以使用 `pack` 子命令调用它。 * `erg pack init`:将当前目录初始化为一个包。会生成一个 `package.er` 文件和一个 `src` 目录。指定 `app` 将产生一个可执行包,`lib` 将产生一个库包,而 `hybrid` 将产生两个包。如果指定了 `--license`,将自动放置许可文件。 * `erg pack build`:构建一个包。使用 `--release` 可以运行和优化测试。工件放置在 `build/debug` 或 `build/release` 中。 * `erg pack install`:安装一个包。在库的情况下,`src` 被放置在 `.erg/lib` 中,而应用程序作为 shell 脚本被放置在 `.erg/app` 中。使用 `--release` 进行优化。 -* `erg pack run`:构建包并运行应用程序(仅限应用程序包)。 +* `erg pack run`:构建包并运行应用程序(仅限应用程序包)。 * `erg pack clean`:删除构建目录的内容。 * `erg pack test`:运行包测试。有关详细信息,请参阅 [test.md](./test.md)。 * `erg pack publish`:发布/发布包。您将需要一个 GitHub 帐户和公钥。 @@ -15,7 +15,7 @@ Erg 标配有一个包管理器,您可以使用 `pack` 子命令调用它。 如果要安装或搜索外部包,请参阅 [install.md](./install.md)。 另请参阅 [package_system.md](../syntax/33_package_system.md) 了解 Erg 包系统。 -## 整个包的标准目录结构(对于应用程序包) +## 整个包的标准目录结构(对于应用程序包) ```console /package # package root directory @@ -54,20 +54,20 @@ dependencies = { baz = pack("baz", "1.1.0") } deprecated=False -successors = [] # 替代包(当一个包被弃用时) +successors = [] # 替代包(当一个包被弃用时) ``` ## 语义版本控制 Erg 包是基于 [语义版本控制](https://semver.org/lang/en/) 进行版本控制的。 -语义版本控制大致以“x.y.z”格式指定(x、y、z 是大于或等于 0 的整数)。 +语义版本控制大致以“x.y.z”格式指定(x、y、z 是大于或等于 0 的整数)。 每个数字的含义如下。 -* x:主要版本(更新破坏兼容性时增加 1) -* y:次要版本(执行兼容更新时增加1(API添加,弃用等),错误修复等由补丁版本升级处理) -* z:补丁版本(当进行小的更改以修复错误或保持兼容性时增加1,破坏兼容性的严重修复由主要版本升级处理) +* x:主要版本(更新破坏兼容性时增加 1) +* y:次要版本(执行兼容更新时增加1(API添加,弃用等),错误修复等由补丁版本升级处理) +* z:补丁版本(当进行小的更改以修复错误或保持兼容性时增加1,破坏兼容性的严重修复由主要版本升级处理) -但是,默认情况下,版本 `0.*.*` 中的更改始终是不兼容的。如果要在保持兼容性的同时升级,请在其后指定 `-compatible`(Erg 自己的规则)。例如,如果要在保持与 0.2.1 兼容的同时添加功能,即要升级到 0.3.0,则指定 0.3.0-compatible。如果您已修复错误,还请指定“0.2.2-compatible”。 +但是,默认情况下,版本 `0.*.*` 中的更改始终是不兼容的。如果要在保持兼容性的同时升级,请在其后指定 `-compatible`(Erg 自己的规则)。例如,如果要在保持与 0.2.1 兼容的同时添加功能,即要升级到 0.3.0,则指定 0.3.0-compatible。如果您已修复错误,还请指定“0.2.2-compatible”。 该版本将被视为与以前的版本兼容。 即使您想将 `0.*.*` 升级到 `1.0.0`,这仍然有效。也就是说,`1.0.0-compatible` 与之前的版本 `0.y.z` 兼容。 @@ -75,26 +75,26 @@ Erg 包是基于 [语义版本控制](https://semver.org/lang/en/) 进行版本 当多人开发具有依赖包的包时,锁定文件很有用。它还通过允许依赖于它们的包在兼容的情况下重用包来节省本地存储。 Erg 的包管理器严格执行这些规则,并将拒绝违反这些规则的包更新。 -Erg 包管理器与版本控制系统(例如 git)一起使用,以检测代码差异并在发布包时验证版本控制的正确性。 -具体来说,包管理器会查看 API 的类型。如果类型是旧版本的子类型,则认为更改是兼容的(请注意,这不是完整的验证;类型兼容但语义上不兼容的重大更改是可能的,这是开发人员的工作来确定这一点)。 +Erg 包管理器与版本控制系统(例如 git)一起使用,以检测代码差异并在发布包时验证版本控制的正确性。 +具体来说,包管理器会查看 API 的类型。如果类型是旧版本的子类型,则认为更改是兼容的(请注意,这不是完整的验证;类型兼容但语义上不兼容的重大更改是可能的,这是开发人员的工作来确定这一点)。 此外,由于整个包存储库都在注册表中注册,即使是开发人员也无法在不通过包管理器的情况下更新包。 此外,包可以被弃用但不能被删除。 ### 附录:语义版本控制问题和对策 -语义版本控制存在(至少)两个已知问题。 +语义版本控制存在(至少)两个已知问题。 首先,语义版本控制可能过于严格。 使用语义版本控制,单个不兼容的 API 更改会增加整个包的主要版本。 发生这种情况时,诸如“我想尝试一个新的 API,但我必须处理另一个不兼容的 API 更改,所以我不会升级”之类的事情。 其次,语义版本控制可以承诺太多。 -如上一节所述,对 API 的“兼容更改”在理论上是不可证明的。如果您指定要使用版本为 `1.0.1` 的包,则可以在语义版本控制方面使用 `1.0.1` 和 `2.0.0` 之间的任何包(`1.0.0` 不能被使用,因为错误已被修复),但由于包开发人员无意使用 API,构建可能不会成功。 +如上一节所述,对 API 的“兼容更改”在理论上是不可证明的。如果您指定要使用版本为 `1.0.1` 的包,则可以在语义版本控制方面使用 `1.0.1` 和 `2.0.0` 之间的任何包(`1.0.0` 不能被使用,因为错误已被修复),但由于包开发人员无意使用 API,构建可能不会成功。 -Erg 通过允许同时使用不同版本的包(通过重命名)解决了这个问题。这使得在部分引入 ver2 API 的同时继续使用 ver1 API 成为可能。 +Erg 通过允许同时使用不同版本的包(通过重命名)解决了这个问题。这使得在部分引入 ver2 API 的同时继续使用 ver1 API 成为可能。 此外,虽然这不是一个非常理想的状态,但如果只能使用 API 的某个次要版本而没有错误,则可以不理会它并继续前进到下一个版本。 ## 发布 可以使用 `publish` 子命令发布包。发布需要 GitHub 帐户。 -默认情况下,包使用 `(owner_name)/(package_name)` 注册。如果满足一定条件(下载次数、维护频率等),可以申请注册一个省略所有者名称的别名。 +默认情况下,包使用 `(owner_name)/(package_name)` 注册。如果满足一定条件(下载次数、维护频率等),可以申请注册一个省略所有者名称的别名。 请注意,包名称不区分大小写,并且不区分诸如 `_` 和 `-` 之类的分隔符。 \ No newline at end of file diff --git a/doc/zh_CN/tools/test.md b/doc/zh_CN/tools/test.md index 886473f5..278035c4 100644 --- a/doc/zh_CN/tools/test.md +++ b/doc/zh_CN/tools/test.md @@ -5,7 +5,7 @@ erg 命令有一个名为 test 的子命令,它支持测试的实现和执行 ## 测试装饰器 (@Test) Erg 使用 `erg test` 命令测试包中 `tests` 目录或 `*.test.er` 文件中的 `@Test` 子例程。 -`tests` 子例程负责黑盒测试(不测试私有函数),`*.test.er` 子例程负责白盒测试(也测试私有函数)。 +`tests` 子例程负责黑盒测试(不测试私有函数),`*.test.er` 子例程负责白盒测试(也测试私有函数)。 ```python # tests/test1.er @@ -16,7 +16,7 @@ test_1_plus_n(n: Nat) = assert add(1, n) == n + 1 ``` -执行结果以摘要形式显示,可以以各种文件格式(.md、.csv 等)输出。 +执行结果以摘要形式显示,可以以各种文件格式(.md、.csv 等)输出。 ## 文档测试 @@ -42,4 +42,4 @@ VMs =... ... ``` -用于测试的模拟对象(mock objects)在 `tests/mock` 模块中定义。 \ No newline at end of file +用于测试的模拟对象(mock objects)在 `tests/mock` 模块中定义。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/inference.md b/doc/zh_TW/compiler/inference.md index 40aaf89b..d40a5298 100644 --- a/doc/zh_TW/compiler/inference.md +++ b/doc/zh_TW/compiler/inference.md @@ -96,7 +96,7 @@ pub enum Type { 让我们将未绑定类型变量 `?T` 泛化为 `gen` 的操作表示。令生成的广义类型变量为 `|T: Type| T`。 在类型论中,量化类型,例如多相关类型 `α->α`,通过在它们前面加上 `∀α.` 来区分(像 ∀ 这样的符号称为(通用)量词。)。 这样的表示(例如`∀α.α->α`)称为类型方案。 Erg 中的类型方案表示为 `|T: Type| T -> T`。 -类型方案通常不被认为是一流的类型。以这种方式配置类型系统可以防止类型推断起作用。但是,在尔格中,在一定条件下可以算是一流的类型。有关详细信息,请参阅 [rank2 类型](../syntax/type/advanced/rank2type.md)。 +类型方案通常不被认为是一流的类型。以这种方式配置类型系统可以防止类型推断起作用。但是,在Erg中,在一定条件下可以算是一流的类型。有关详细信息,请参阅 [rank2 类型](../syntax/type/advanced/rank2type.md)。 现在,当在使用它的类型推断(例如,`id 1`,`id True`)中使用获得的类型方案(例如`'T -> 'T(id's type scheme)`)时,必须释放generalize。这种逆变换称为 __instantiation__。我们将调用操作`inst`。 diff --git a/doc/zh_TW/compiler/parsing.md b/doc/zh_TW/compiler/parsing.md index c790e086..aa540a33 100644 --- a/doc/zh_TW/compiler/parsing.md +++ b/doc/zh_TW/compiler/parsing.md @@ -2,7 +2,7 @@ ## 空格的处理 -尔格语法的一个特点是它对空间敏感。 +Erg语法的一个特点是它对空间敏感。 这是为了弥补因省略`()`而造成的表达力损失。在 Nim 中可以找到类似的语法,它也允许省略 `()`。 ```python diff --git a/doc/zh_TW/dev_guide/unify_terms.md b/doc/zh_TW/dev_guide/unify_terms.md index 2c8e49f5..1a8a2dba 100644 --- a/doc/zh_TW/dev_guide/unify_terms.md +++ b/doc/zh_TW/dev_guide/unify_terms.md @@ -23,7 +23,7 @@ * 符号:在源代码中实心编写的字符(符号、控制字符等除外),不是字符串对象(未包含在“”中)。符号在 Ruby、Lisp 等中作为原始类型存在,但在 Erg 中它们不被视为对象。 * 标识符:(并且可以)引用某个对象的符号,而不是保留字。例如,在 Python 中 class 和 def 不能用作标识符。由于 Erg 没有保留字,所以除了某些符号外,所有符号都可以用作标识符。 * 名称:与标识符的含义几乎相同。它有时与 Erg 中的代数同义使用。 -* 代数名称:相当于尔格中的标识符。在 C 中,函数名称是标识符,而不是代数名称。 “代数”指的是语言特性本身,它允许您使用 `=`(变量赋值运算符)或 `=`(常量赋值运算符)来分配对象。 +* 代数名称:相当于Erg中的标识符。在 C 中,函数名称是标识符,而不是代数名称。 “代数”指的是语言特性本身,它允许您使用 `=`(变量赋值运算符)或 `=`(常量赋值运算符)来分配对象。 ```python 代数名称<:(名称==标识符)​​<:符号 diff --git a/doc/zh_TW/faq_general.md b/doc/zh_TW/faq_general.md index c5ab4ee3..8d1166e1 100644 --- a/doc/zh_TW/faq_general.md +++ b/doc/zh_TW/faq_general.md @@ -1,16 +1,16 @@ -# 尔格常见问题 +# Erg常见问题 此常见问题解答适用于一般 Erg 初学者。 -对于个别(常见)技术问题,请参阅 [此处](./faq_technical.md) 了解个别(常见)技术问题,以及 +对于个别(常见)技术问题,请参阅 [此处](./faq_technical.md) 了解个别(常见)技术问题,以及 [这里](./dev_guide/faq_syntax.md) 了解更多信息。 ## Erg 是 Python 兼容语言是什么意思? -~~A:Erg的可执行系统EVM(Erg VirtualMachine)执行Erg字节码,是Python字节码的扩展。它在 Python 字节码中引入了静态类型系统和其他特性(例如向不带参数的指令引入参数,以及在自由编号中实现唯一指令)。这让 Erg 可以无缝调用 Python 代码并快速执行。~~ +~~A:Erg的可执行系统EVM(Erg VirtualMachine)执行Erg字节码,是Python字节码的扩展。它在 Python 字节码中引入了静态类型系统和其他特性(例如向不带参数的指令引入参数,以及在自由编号中实现唯一指令)。这让 Erg 可以无缝调用 Python 代码并快速执行。~~ -A: Erg 代码被转译成 Python 字节码。也就是说,它运行在与 Python 相同的解释器上。最初,我们计划开发一个兼容 Cpython 的解释器,并将其与编译器结合起来形成“Erg”。但是,由于处理系统的发展远远落后于编译器,我们决定提前只发布编译器(但解释器仍在开发中)。 +A: Erg 代码被转译成 Python 字节码。也就是说,它运行在与 Python 相同的解释器上。最初,我们计划开发一个兼容 Cpython 的解释器,并将其与编译器结合起来形成“Erg”。但是,由于处理系统的发展远远落后于编译器,我们决定提前只发布编译器(但解释器仍在开发中)。 -## 哪些语言影响了尔格? +## 哪些语言影响了Erg? 我们受到的语言多于我们双手所能指望的数量,但 Python、Rust、Nim 和 Haskell 的影响最大。 我们从 Python 继承了许多语义,从 Rust 继承了面向表达式和 trait,从 Nim 继承了过程,从 Haskell 继承了函数式编程相关的特性。 @@ -22,7 +22,7 @@ Julia 是可以有类型的,但它确实是一种动态类型语言,不具 ## Erg 支持多种编程风格,包括函数式和面向对象的编程。这不是与 Python 的“应该有一种——最好只有一种——明显的方法”相反吗? -答:在 Erg 中,该术语是在更狭窄的上下文中使用的。例如,Erg API 中一般没有别名;在这种情况下,尔格是“唯一一种方式”。 +答:在 Erg 中,该术语是在更狭窄的上下文中使用的。例如,Erg API 中一般没有别名;在这种情况下,Erg是“唯一一种方式”。 在更大的上下文中,例如 FP 或 OOP,只有一种做事方式并不一定很方便。 例如,JavaScript 有几个库可以帮助创建不可变的程序,而 C 有几个用于垃圾收集的库。 然而,即使是这样的基本功能也有多个库不仅需要时间来选择,而且在集成使用不同库的代码时也会产生很大的困难。 @@ -34,4 +34,4 @@ Julia 是可以有类型的,但它确实是一种动态类型语言,不具 它以cgs单位系统中的能量单位erg命名。它具有双重含义:一种为程序员提供能量的符合人体工程学的语言。 -还有其他几个候选者,但之所以选择它是因为它最短(根据 Ruby 的开发者 Matz 的说法,语言名称越短越好)并且具有相当高的可搜索性。 \ No newline at end of file +还有其他几个候选者,但之所以选择它是因为它最短(根据 Ruby 的开发者 Matz 的说法,语言名称越短越好)并且具有相当高的可搜索性。 \ No newline at end of file diff --git a/doc/zh_TW/faq_technical.md b/doc/zh_TW/faq_technical.md index 5c73524e..813cce5f 100644 --- a/doc/zh_TW/faq_technical.md +++ b/doc/zh_TW/faq_technical.md @@ -17,11 +17,11 @@ ## Never、{}、None、()、NotImplemented 和 Ellipsis 有什么区别? -A:`Never` 是一种“不可能”的类型。产生运行时错误的子例程将“Never”(或“Never”的合并类型)作为其返回类型。该程序将在检测到这一点后立即停止。尽管 `Never` 类型在定义上也是所有类型的子类,但 `Never` 类型的对象永远不会出现在 Erg 代码中,也永远不会被创建。 `{}` 等价于 `Never`。 +A:`Never` 是一种“不可能”的类型。产生运行时错误的子例程将“Never”(或“Never”的合并类型)作为其返回类型。该程序将在检测到这一点后立即停止。尽管 `Never` 类型在定义上也是所有类型的子类,但 `Never` 类型的对象永远不会出现在 Erg 代码中,也永远不会被创建。 `{}` 等价于 `Never`。 `Ellipsis` 是一个表示省略号的对象,来自 Python。 `NotImplemented` 也来自 Python。它被用作未实现的标记,但 Erg 更喜欢产生错误的 `todo` 函数。 `None` 是 `NoneType` 的一个实例。它通常与 `Option` 类型一起使用。 -`()` 是一个单元类型和它自己的一个实例。当您想要返回“无意义的值”(例如过程的返回值)时使用它。 +`()` 是一个单元类型和它自己的一个实例。当您想要返回“无意义的值”(例如过程的返回值)时使用它。 ## 为什么 `x = p!()` 有效但 `f() = p!()` 会导致 EffectError? @@ -31,4 +31,4 @@ A:`Never` 是一种“不可能”的类型。产生运行时错误的子例 ## 当我尝试使用 Python API 时,对于在 Python 中有效的代码,我在 Erg 中收到类型错误。这是什么意思? A:Erg API 的类型尽可能接近 Python API 规范,但有些情况无法完全表达。 -此外,根据规范有效但被认为不合需要的输入(例如,在应该输入 int 时输入浮点数)可能会被 Erg 开发团队酌情视为类型错误。 \ No newline at end of file +此外,根据规范有效但被认为不合需要的输入(例如,在应该输入 int 时输入浮点数)可能会被 Erg 开发团队酌情视为类型错误。 \ No newline at end of file diff --git a/doc/zh_TW/improved_points.md b/doc/zh_TW/improved_points.md index b137aad2..dcea4a90 100644 --- a/doc/zh_TW/improved_points.md +++ b/doc/zh_TW/improved_points.md @@ -1,6 +1,6 @@ # Python 的改进 -## 执行静态分析(静态类型检查、变量和属性检查) +## 执行静态分析(静态类型检查、变量和属性检查) 静态类型检查的好处现在怎么强调都不为过,但是检查变量和属性的存在也是相当重要的一部分。 @@ -35,7 +35,7 @@ assert i is not 257 就像 Java 的接口一样,你可以进行基于契约的编程。 -Python 也有 ABC(抽象基类),但这种结构最适合静态类型。 +Python 也有 ABC(抽象基类),但这种结构最适合静态类型。 ## 静态解决依赖关系 diff --git a/doc/zh_TW/index.md b/doc/zh_TW/index.md index e35146b5..c7d9e9ae 100644 --- a/doc/zh_TW/index.md +++ b/doc/zh_TW/index.md @@ -6,7 +6,7 @@ ## [compiler/](./compiler/index.md) - 描述 Erg 编译器的设计(厘米) + 描述 Erg 编译器的设计(厘米) ## [dev_guide/](./dev_guide/index.md) diff --git a/doc/zh_TW/syntax/17_mutability.md b/doc/zh_TW/syntax/17_mutability.md index 25145f88..3d89fad4 100644 --- a/doc/zh_TW/syntax/17_mutability.md +++ b/doc/zh_TW/syntax/17_mutability.md @@ -96,7 +96,7 @@ match! x: 变量和标识符之间的区别在于,如果我们在 Erg 的语法理论意义上谈论变量,则两者实际上是相同的。 在 C 中,类型和函数不能分配给变量; int 和 main 是标识符,而不是变量(严格来说可以赋值,但有限制)。 -然而,在尔格语中,“一切都是对象”。不仅函数和类型,甚至运算符都可以分配给变量。 +然而,在Erg语中,“一切都是对象”。不仅函数和类型,甚至运算符都可以分配给变量。

上一页 | 下一页 diff --git a/doc/zh_TW/syntax/indexes.md b/doc/zh_TW/syntax/indexes.md index 54ba47a3..b60d9945 100644 --- a/doc/zh_TW/syntax/indexes.md +++ b/doc/zh_TW/syntax/indexes.md @@ -173,280 +173,4 @@ ### Y -### 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) - -## 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函数) -* 逗号 → [,] - -## 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) - * 封闭式通用 - * 打开通用 - * 通用函数 → 多相关函数 - * 通用量化 -* 前缀运算符 -* 相互递归 -* 下标 → [索引] -* [属性] - * [属性子类型] - -## 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) - -## 没有一行 - -* [理解](./27_comprehension.md) -* ~~中缀运算符~~ → [中缀运算符] -* [命名空间] - -## is a line - -* [数组](./10_array.md) -* [派生类型](./type/variances.md/#用户定义的类型变体) -* [模式(匹配)](./26_pattern_matching.md) -* [包](./33_package_ssystem.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) -* 底部 - * 底部类型 → [{}] - * 底层 → [从不] -* [多态性] - -## ma line - -* ~~ 前缀运算符 ~~ → 前缀运算符 -* [标记类型](./type/advanced/marker_trait.md) -* [匿名函数](./21_lambda.md) -* 可变 → [可变] -* [移动] -* 方法 -* 元字符 -* [模块](./24_module.md) -* [字符串] → [字符串] - * [字符串插值](./01_literal.md/#str字面量) -* 返回值 - -## or line - -* [幽灵类型](./type/advanced/phantom.md) -* 请求属性 -* [元素] -* [称呼] - -## 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) - -## line - -* 通配符 \ No newline at end of file +### Z \ No newline at end of file diff --git a/doc/zh_TW/syntax/quick_tour.md b/doc/zh_TW/syntax/quick_tour.md index 886c4f8c..e891c70f 100644 --- a/doc/zh_TW/syntax/quick_tour.md +++ b/doc/zh_TW/syntax/quick_tour.md @@ -76,7 +76,7 @@ assert i == 1 print! 1 # 1 ``` -## 泛型函数(多相关) +## 泛型函数(多相关) ```python id|T|(x: T): T = x @@ -86,7 +86,7 @@ id("a"): Str ## 记录 -您可以使用类似 ML 的语言中的记录等价物(或 JS 中的对象字面量)。 +您可以使用类似 ML 的语言中的记录等价物(或 JS 中的对象字面量)。 ```python p = {x = 1; y = 2} @@ -94,7 +94,7 @@ p = {x = 1; y = 2} ## 所有权 -Ergs 由可变对象(使用 `!` 运算符突变的对象)拥有,并且不能从多个位置重写。 +Ergs 由可变对象(使用 `!` 运算符突变的对象)拥有,并且不能从多个位置重写。 ```python i = !0 @@ -164,7 +164,7 @@ name = match num: _ -> "unnamed" ``` -### 丢弃(通配符)模式 +### 丢弃(通配符)模式 ```python _ = 1 @@ -188,7 +188,7 @@ assert first(1, 2, 3) == 1 ```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) -# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) +# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) m, n = 1, 2 ``` @@ -258,7 +258,7 @@ Point. Nat = {I: Int | I >= 0} ``` -## 带值的参数类型(依赖类型) +## 带值的参数类型(依赖类型) ```python a: [Int; 3] diff --git a/doc/zh_TW/tips.md b/doc/zh_TW/tips.md index 0646a08a..7d8264bc 100644 --- a/doc/zh_TW/tips.md +++ b/doc/zh_TW/tips.md @@ -15,7 +15,7 @@ mut_record = {.height = !height; ...rest} ## 想要隐藏变量 -使用 Erg 无法在相同范围内进行遮蔽。 但是,如果范围发生变化,您可以重新定义它们(这是一种称为实例块的语法)。 +使用 Erg 无法在相同范围内进行遮蔽。 但是,如果范围发生变化,您可以重新定义它们(这是一种称为实例块的语法)。 ````python ## 获取一个 T!-type 对象,最后将它作为 T 类型赋值给一个变量 @@ -25,7 +25,7 @@ x: T = x.freeze() ```` -## 想以某种方式重用最终类(不可继承的类) +## 想以某种方式重用最终类(不可继承的类) 您可以创建一个包装类。 这就是所谓的构图模式。 @@ -39,7 +39,7 @@ FinalWrapper. ## 想使用不是字符串的枚举类型 -可以定义其他语言中常见的传统枚举类型(代数数据类型)如下 +可以定义其他语言中常见的传统枚举类型(代数数据类型)如下 如果您实现“单例”,则类和实例是相同的。 此外,如果您使用 `Enum`,则选择的类型会自动定义为重定向属性。 @@ -83,7 +83,7 @@ for! arr.iter().zip(1...) , i => ... ``` -## 想要测试一个(白盒)非公共 API +## 想要测试一个(白盒)非公共 API `foo.er` 中的私有 API 可在 `foo.test.er` 模块中特别访问。 `foo.test.er` 模块无法导入,因此它保持隐藏状态。 @@ -104,7 +104,7 @@ foo = import "foo" ... ``` -## 想定义一个从外部只读的(变量)属性 +## 想定义一个从外部只读的(变量)属性 您可以将属性设为私有并定义一个 getter。 @@ -132,4 +132,4 @@ assert norm({x = 1; y = 2}) == norm({y = 2; x = 1}) ## 想要停止警告 -Erg 中没有停止警告的选项(这是设计使然)。 请重写你的代码。 +Erg 中没有停止警告的选项(这是设计使然)。 请重写你的代码。 diff --git a/doc/zh_TW/tools/env.md b/doc/zh_TW/tools/env.md index 03d2bd48..ada55481 100644 --- a/doc/zh_TW/tools/env.md +++ b/doc/zh_TW/tools/env.md @@ -1,7 +1,7 @@ # 环境子命令 env 子命令指定 erg 执行环境。 -使用 `erg env new [env name]` 创建一个新的执行环境。 将打开一个交互式工具,当您指定 erg 版本时,将安装该版本的 erg(如果已存在,将使用它),您将能够将其用作新环境。 +使用 `erg env new [env name]` 创建一个新的执行环境。 将打开一个交互式工具,当您指定 erg 版本时,将安装该版本的 erg(如果已存在,将使用它),您将能够将其用作新环境。 您可以使用 `erg env switch [env name]` 切换环境。 可以使用 `erg env edit` 编辑创建的环境以预安装软件包并指定其他语言的依赖项。 该命令最大的特点是`erg env export`可以将重现环境的信息输出为`[env name].env.er`文件。 这使您可以立即开始在与其他人相同的环境中进行开发。 此外,`erg env publish` 可以像包一样发布环境。 \ No newline at end of file diff --git a/doc/zh_TW/tools/install.md b/doc/zh_TW/tools/install.md index fa0a8b5d..f59145b5 100644 --- a/doc/zh_TW/tools/install.md +++ b/doc/zh_TW/tools/install.md @@ -6,5 +6,5 @@ ## 便利功能 * 如果有同名的包名,且下载次数超过该包名的10倍以上,会提示可能输入错误。 这可以防止拼写错误。 -* 如果包很大(超过 50MB),请显示大小并建议您是否真的要安装它。 +* 如果包很大(超过 50MB),请显示大小并建议您是否真的要安装它。 * 如果包装重复,建议使用替代包装。 \ No newline at end of file diff --git a/doc/zh_TW/tools/pack.md b/doc/zh_TW/tools/pack.md index 9679e502..59f35f19 100644 --- a/doc/zh_TW/tools/pack.md +++ b/doc/zh_TW/tools/pack.md @@ -6,7 +6,7 @@ Erg 标配有一个包管理器,您可以使用 `pack` 子命令调用它。 * `erg pack init`:将当前目录初始化为一个包。会生成一个 `package.er` 文件和一个 `src` 目录。指定 `app` 将产生一个可执行包,`lib` 将产生一个库包,而 `hybrid` 将产生两个包。如果指定了 `--license`,将自动放置许可文件。 * `erg pack build`:构建一个包。使用 `--release` 可以运行和优化测试。工件放置在 `build/debug` 或 `build/release` 中。 * `erg pack install`:安装一个包。在库的情况下,`src` 被放置在 `.erg/lib` 中,而应用程序作为 shell 脚本被放置在 `.erg/app` 中。使用 `--release` 进行优化。 -* `erg pack run`:构建包并运行应用程序(仅限应用程序包)。 +* `erg pack run`:构建包并运行应用程序(仅限应用程序包)。 * `erg pack clean`:删除构建目录的内容。 * `erg pack test`:运行包测试。有关详细信息,请参阅 [test.md](./test.md)。 * `erg pack publish`:发布/发布包。您将需要一个 GitHub 帐户和公钥。 @@ -15,7 +15,7 @@ Erg 标配有一个包管理器,您可以使用 `pack` 子命令调用它。 如果要安装或搜索外部包,请参阅 [install.md](./install.md)。 另请参阅 [package_system.md](../syntax/33_package_system.md) 了解 Erg 包系统。 -## 整个包的标准目录结构(对于应用程序包) +## 整个包的标准目录结构(对于应用程序包) ```console /package # package root directory @@ -54,20 +54,20 @@ dependencies = { baz = pack("baz", "1.1.0") } deprecated=False -successors = [] # 替代包(当一个包被弃用时) +successors = [] # 替代包(当一个包被弃用时) ``` ## 语义版本控制 Erg 包是基于 [语义版本控制](https://semver.org/lang/en/) 进行版本控制的。 -语义版本控制大致以“x.y.z”格式指定(x、y、z 是大于或等于 0 的整数)。 +语义版本控制大致以“x.y.z”格式指定(x、y、z 是大于或等于 0 的整数)。 每个数字的含义如下。 -* x:主要版本(更新破坏兼容性时增加 1) -* y:次要版本(执行兼容更新时增加1(API添加,弃用等),错误修复等由补丁版本升级处理) -* z:补丁版本(当进行小的更改以修复错误或保持兼容性时增加1,破坏兼容性的严重修复由主要版本升级处理) +* x:主要版本(更新破坏兼容性时增加 1) +* y:次要版本(执行兼容更新时增加1(API添加,弃用等),错误修复等由补丁版本升级处理) +* z:补丁版本(当进行小的更改以修复错误或保持兼容性时增加1,破坏兼容性的严重修复由主要版本升级处理) -但是,默认情况下,版本 `0.*.*` 中的更改始终是不兼容的。如果要在保持兼容性的同时升级,请在其后指定 `-compatible`(Erg 自己的规则)。例如,如果要在保持与 0.2.1 兼容的同时添加功能,即要升级到 0.3.0,则指定 0.3.0-compatible。如果您已修复错误,还请指定“0.2.2-compatible”。 +但是,默认情况下,版本 `0.*.*` 中的更改始终是不兼容的。如果要在保持兼容性的同时升级,请在其后指定 `-compatible`(Erg 自己的规则)。例如,如果要在保持与 0.2.1 兼容的同时添加功能,即要升级到 0.3.0,则指定 0.3.0-compatible。如果您已修复错误,还请指定“0.2.2-compatible”。 该版本将被视为与以前的版本兼容。 即使您想将 `0.*.*` 升级到 `1.0.0`,这仍然有效。也就是说,`1.0.0-compatible` 与之前的版本 `0.y.z` 兼容。 @@ -75,26 +75,26 @@ Erg 包是基于 [语义版本控制](https://semver.org/lang/en/) 进行版本 当多人开发具有依赖包的包时,锁定文件很有用。它还通过允许依赖于它们的包在兼容的情况下重用包来节省本地存储。 Erg 的包管理器严格执行这些规则,并将拒绝违反这些规则的包更新。 -Erg 包管理器与版本控制系统(例如 git)一起使用,以检测代码差异并在发布包时验证版本控制的正确性。 -具体来说,包管理器会查看 API 的类型。如果类型是旧版本的子类型,则认为更改是兼容的(请注意,这不是完整的验证;类型兼容但语义上不兼容的重大更改是可能的,这是开发人员的工作来确定这一点)。 +Erg 包管理器与版本控制系统(例如 git)一起使用,以检测代码差异并在发布包时验证版本控制的正确性。 +具体来说,包管理器会查看 API 的类型。如果类型是旧版本的子类型,则认为更改是兼容的(请注意,这不是完整的验证;类型兼容但语义上不兼容的重大更改是可能的,这是开发人员的工作来确定这一点)。 此外,由于整个包存储库都在注册表中注册,即使是开发人员也无法在不通过包管理器的情况下更新包。 此外,包可以被弃用但不能被删除。 ### 附录:语义版本控制问题和对策 -语义版本控制存在(至少)两个已知问题。 +语义版本控制存在(至少)两个已知问题。 首先,语义版本控制可能过于严格。 使用语义版本控制,单个不兼容的 API 更改会增加整个包的主要版本。 发生这种情况时,诸如“我想尝试一个新的 API,但我必须处理另一个不兼容的 API 更改,所以我不会升级”之类的事情。 其次,语义版本控制可以承诺太多。 -如上一节所述,对 API 的“兼容更改”在理论上是不可证明的。如果您指定要使用版本为 `1.0.1` 的包,则可以在语义版本控制方面使用 `1.0.1` 和 `2.0.0` 之间的任何包(`1.0.0` 不能被使用,因为错误已被修复),但由于包开发人员无意使用 API,构建可能不会成功。 +如上一节所述,对 API 的“兼容更改”在理论上是不可证明的。如果您指定要使用版本为 `1.0.1` 的包,则可以在语义版本控制方面使用 `1.0.1` 和 `2.0.0` 之间的任何包(`1.0.0` 不能被使用,因为错误已被修复),但由于包开发人员无意使用 API,构建可能不会成功。 -Erg 通过允许同时使用不同版本的包(通过重命名)解决了这个问题。这使得在部分引入 ver2 API 的同时继续使用 ver1 API 成为可能。 +Erg 通过允许同时使用不同版本的包(通过重命名)解决了这个问题。这使得在部分引入 ver2 API 的同时继续使用 ver1 API 成为可能。 此外,虽然这不是一个非常理想的状态,但如果只能使用 API 的某个次要版本而没有错误,则可以不理会它并继续前进到下一个版本。 ## 发布 可以使用 `publish` 子命令发布包。发布需要 GitHub 帐户。 -默认情况下,包使用 `(owner_name)/(package_name)` 注册。如果满足一定条件(下载次数、维护频率等),可以申请注册一个省略所有者名称的别名。 +默认情况下,包使用 `(owner_name)/(package_name)` 注册。如果满足一定条件(下载次数、维护频率等),可以申请注册一个省略所有者名称的别名。 请注意,包名称不区分大小写,并且不区分诸如 `_` 和 `-` 之类的分隔符。 \ No newline at end of file diff --git a/doc/zh_TW/tools/test.md b/doc/zh_TW/tools/test.md index 886473f5..278035c4 100644 --- a/doc/zh_TW/tools/test.md +++ b/doc/zh_TW/tools/test.md @@ -5,7 +5,7 @@ erg 命令有一个名为 test 的子命令,它支持测试的实现和执行 ## 测试装饰器 (@Test) Erg 使用 `erg test` 命令测试包中 `tests` 目录或 `*.test.er` 文件中的 `@Test` 子例程。 -`tests` 子例程负责黑盒测试(不测试私有函数),`*.test.er` 子例程负责白盒测试(也测试私有函数)。 +`tests` 子例程负责黑盒测试(不测试私有函数),`*.test.er` 子例程负责白盒测试(也测试私有函数)。 ```python # tests/test1.er @@ -16,7 +16,7 @@ test_1_plus_n(n: Nat) = assert add(1, n) == n + 1 ``` -执行结果以摘要形式显示,可以以各种文件格式(.md、.csv 等)输出。 +执行结果以摘要形式显示,可以以各种文件格式(.md、.csv 等)输出。 ## 文档测试 @@ -42,4 +42,4 @@ VMs =... ... ``` -用于测试的模拟对象(mock objects)在 `tests/mock` 模块中定义。 \ No newline at end of file +用于测试的模拟对象(mock objects)在 `tests/mock` 模块中定义。 \ No newline at end of file From c120700585fdb1d655255c8e2817bb13cc8d369e Mon Sep 17 00:00:00 2001 From: GreasySlug <9619abgoni@gmail.com> Date: Mon, 5 Sep 2022 22:29:51 +0900 Subject: [PATCH 26/42] Remove unnecessary newlines --- doc/EN/faq_technical.md | 1 - doc/EN/syntax/type/13_algebraic.md | 1 - doc/JA/dev_guide/branches.md | 1 - doc/JA/dev_guide/build_features.md | 1 - doc/JA/dev_guide/directories.md | 1 - doc/JA/dev_guide/doc_guideline.md | 1 - doc/JA/dev_guide/env.md | 1 - doc/JA/dev_guide/faq_syntax.md | 1 - doc/JA/dev_guide/i18n_messages.md | 1 - doc/JA/dev_guide/rust_code_guideline.md | 1 - doc/JA/dev_guide/terms.md | 1 - doc/JA/dev_guide/unify_terms.md | 1 - doc/JA/faq_general.md | 1 - doc/JA/faq_technical.md | 1 - doc/JA/improved_points.md | 1 - doc/JA/index.md | 1 - doc/JA/migration_from_py.md | 1 - doc/JA/syntax/00_basic.md | 1 - doc/JA/syntax/01_literal.md | 1 - doc/JA/syntax/02_name.md | 1 - doc/JA/syntax/03_declaration.md | 1 - doc/JA/syntax/04_function.md | 1 - doc/JA/syntax/05_builtin_funcs.md | 1 - doc/JA/syntax/06_operator.md | 1 - doc/JA/syntax/07_side_effect.md | 1 - doc/JA/syntax/08_procedure.md | 1 - doc/JA/syntax/09_builtin_procs.md | 1 - doc/JA/syntax/10_array.md | 1 - doc/JA/syntax/11_tuple.md | 1 - doc/JA/syntax/12_dict.md | 1 - doc/JA/syntax/13_record.md | 1 - doc/JA/syntax/14_set.md | 1 - doc/JA/syntax/15_type.md | 1 - doc/JA/syntax/16_iterator.md | 1 - doc/JA/syntax/17_mutability.md | 1 - doc/JA/syntax/18_ownership.md | 1 - doc/JA/syntax/19_visibility.md | 1 - doc/JA/syntax/20_naming_rule.md | 1 - doc/JA/syntax/21_lambda.md | 1 - doc/JA/syntax/22_subroutine.md | 1 - doc/JA/syntax/23_closure.md | 1 - doc/JA/syntax/24_module.md | 1 - doc/JA/syntax/25_object_system.md | 1 - doc/JA/syntax/26_pattern_matching.md | 1 - doc/JA/syntax/27_comprehension.md | 1 - doc/JA/syntax/28_spread_syntax.md | 1 - doc/JA/syntax/29_decorator.md | 1 - doc/JA/syntax/30_error_handling.md | 1 - doc/JA/syntax/31_pipeline.md | 1 - doc/JA/syntax/32_integration_with_Python.md | 1 - doc/JA/syntax/33_package_system.md | 1 - doc/JA/syntax/34_generator.md | 1 - doc/JA/syntax/SUMMARY.md | 1 - doc/JA/syntax/container_ownership.md | 1 - doc/JA/syntax/indexes.md | 1 - doc/JA/syntax/quick_tour.md | 1 - doc/JA/syntax/type/01_type_system.md | 1 - doc/JA/syntax/type/02_basic.md | 1 - doc/JA/syntax/type/03_trait.md | 1 - doc/JA/syntax/type/04_class.md | 1 - doc/JA/syntax/type/05_inheritance.md | 1 - doc/JA/syntax/type/06_nst_vs_sst.md | 1 - doc/JA/syntax/type/07_patch.md | 1 - doc/JA/syntax/type/08_value.md | 1 - doc/JA/syntax/type/09_attributive.md | 1 - doc/JA/syntax/type/10_interval.md | 1 - doc/JA/syntax/type/11_enum.md | 1 - doc/JA/syntax/type/12_refinement.md | 1 - doc/JA/syntax/type/13_algebraic.md | 1 - doc/JA/syntax/type/14_dependent.md | 1 - doc/JA/syntax/type/15_quantified.md | 1 - doc/JA/syntax/type/16_subtyping.md | 1 - doc/JA/syntax/type/17_type_casting.md | 1 - doc/JA/syntax/type/18_mut.md | 1 - doc/JA/syntax/type/19_bound.md | 1 - doc/JA/syntax/type/advanced/GADTs.md | 1 - doc/JA/syntax/type/advanced/default_param.md | 1 - doc/JA/syntax/type/advanced/erasure.md | 1 - doc/JA/syntax/type/advanced/existential.md | 1 - doc/JA/syntax/type/advanced/keyword_param.md | 1 - doc/JA/syntax/type/advanced/kind.md | 1 - doc/JA/syntax/type/advanced/marker_trait.md | 1 - doc/JA/syntax/type/advanced/mut_struct.md | 1 - doc/JA/syntax/type/advanced/newtype.md | 1 - doc/JA/syntax/type/advanced/overloading.md | 1 - doc/JA/syntax/type/advanced/phantom.md | 1 - doc/JA/syntax/type/advanced/projection.md | 1 - doc/JA/syntax/type/advanced/quantified_dependent.md | 1 - doc/JA/syntax/type/advanced/shared.md | 1 - doc/JA/syntax/type/advanced/special.md | 1 - doc/JA/tips.md | 1 - doc/zh_CN/dev_guide/faq_syntax.md | 2 -- doc/zh_CN/faq_technical.md | 1 - doc/zh_CN/python/bytecode_specification.md | 1 - doc/zh_CN/syntax/01_literal.md | 1 - doc/zh_CN/syntax/21_lambda.md | 1 - doc/zh_CN/syntax/32_integration_with_Python.md | 1 - doc/zh_CN/syntax/type/13_algebraic.md | 1 - doc/zh_CN/syntax/type/advanced/overloading.md | 1 - 99 files changed, 100 deletions(-) diff --git a/doc/EN/faq_technical.md b/doc/EN/faq_technical.md index 896b120a..03fab7b5 100644 --- a/doc/EN/faq_technical.md +++ b/doc/EN/faq_technical.md @@ -1,6 +1,5 @@ # Technical FAQ - 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. 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). diff --git a/doc/EN/syntax/type/13_algebraic.md b/doc/EN/syntax/type/13_algebraic.md index e214c71d..042d6607 100644 --- a/doc/EN/syntax/type/13_algebraic.md +++ b/doc/EN/syntax/type/13_algebraic.md @@ -9,7 +9,6 @@ Normal classes can only perform Union, and other operations will result in a typ Union types can give multiple possibilities for types. As the name suggests, they are generated by the `or` operator. A typical Union is the `Option` type. The `Option` type is a `T or NoneType` patch type, primarily representing values that may fail. - ```python IntOrStr = Int or Str assert dict.get("some key") in (Int or NoneType) diff --git a/doc/JA/dev_guide/branches.md b/doc/JA/dev_guide/branches.md index 1fd16786..600efce5 100644 --- a/doc/JA/dev_guide/branches.md +++ b/doc/JA/dev_guide/branches.md @@ -1,6 +1,5 @@ # ブランチの命名と運用方針 - * 基本的に開発は`main`ブランチ一本で行う(モノレポ開発)。どうしてもブランチを切らないと作業しにくい場合のみ`feature-*`ブランチか`issue-*`ブランチを作成する。 ## main diff --git a/doc/JA/dev_guide/build_features.md b/doc/JA/dev_guide/build_features.md index e6dbbf9d..c78abb3e 100644 --- a/doc/JA/dev_guide/build_features.md +++ b/doc/JA/dev_guide/build_features.md @@ -1,6 +1,5 @@ # `erg` build features - ## debug デバッグモードにする。これにより、Erg内部での挙動が逐次ログ表示される。 diff --git a/doc/JA/dev_guide/directories.md b/doc/JA/dev_guide/directories.md index df6f6bb8..1eb0c60c 100644 --- a/doc/JA/dev_guide/directories.md +++ b/doc/JA/dev_guide/directories.md @@ -1,6 +1,5 @@ # Ergリポジトリのディレクトリ構造 - ```console └─┬ assets: 画像など ├─ CODE_OF_CONDUCT: 行動規範 diff --git a/doc/JA/dev_guide/doc_guideline.md b/doc/JA/dev_guide/doc_guideline.md index 8aa8ca89..abcc87a2 100644 --- a/doc/JA/dev_guide/doc_guideline.md +++ b/doc/JA/dev_guide/doc_guideline.md @@ -1,6 +1,5 @@ # 書式 - 以下のルールに従っていないドキュメントはすべて修正の対象となる。 * コードコメント、または内部用のドキュメントは、である調で書く。 diff --git a/doc/JA/dev_guide/env.md b/doc/JA/dev_guide/env.md index 49a64042..c85aa280 100644 --- a/doc/JA/dev_guide/env.md +++ b/doc/JA/dev_guide/env.md @@ -1,6 +1,5 @@ # 開発環境 - ## インストールが必要なもの * Rust (installed with rustup) diff --git a/doc/JA/dev_guide/faq_syntax.md b/doc/JA/dev_guide/faq_syntax.md index 8f2c615c..8dea551e 100644 --- a/doc/JA/dev_guide/faq_syntax.md +++ b/doc/JA/dev_guide/faq_syntax.md @@ -1,6 +1,5 @@ # Erg design's "Why" and Answers - ## なぜ所有権システムがあるのにGCも共存させているのですか? Ergが所有権システムを導入した動機は、Rustのような「GCに頼らないメモリ管理」のためではないからです。 diff --git a/doc/JA/dev_guide/i18n_messages.md b/doc/JA/dev_guide/i18n_messages.md index ddafc18a..51fd8fb5 100644 --- a/doc/JA/dev_guide/i18n_messages.md +++ b/doc/JA/dev_guide/i18n_messages.md @@ -1,6 +1,5 @@ # メッセージの多言語化 - Ergはメッセージ(スタート、オプション、ドキュメント、ヒント、警告、エラーメッセージなど)の多言語化を進めています。 このプロジェクトは、RustやErgの詳しい知識がなくても参加することができます。ぜひ協力をお願いします。 diff --git a/doc/JA/dev_guide/rust_code_guideline.md b/doc/JA/dev_guide/rust_code_guideline.md index e679e8e4..cf090732 100644 --- a/doc/JA/dev_guide/rust_code_guideline.md +++ b/doc/JA/dev_guide/rust_code_guideline.md @@ -1,6 +1,5 @@ # Rustコードに関するガイドライン - ## ローカルルール * デバッグ用の出力には`log!`を使用する(release時にも必要な出力処理は`println!`等を使用する)。 diff --git a/doc/JA/dev_guide/terms.md b/doc/JA/dev_guide/terms.md index 7c2a8be1..7d5677f6 100644 --- a/doc/JA/dev_guide/terms.md +++ b/doc/JA/dev_guide/terms.md @@ -1,6 +1,5 @@ # 用語辞典 - ## 記号 ### ! diff --git a/doc/JA/dev_guide/unify_terms.md b/doc/JA/dev_guide/unify_terms.md index 76984a3b..e6e71220 100644 --- a/doc/JA/dev_guide/unify_terms.md +++ b/doc/JA/dev_guide/unify_terms.md @@ -1,6 +1,5 @@ # 用語の統一 - ## Accessibility, Visibility (参照性、可視性) Visibility(可視性)を使用する。 diff --git a/doc/JA/faq_general.md b/doc/JA/faq_general.md index 18c0c6ae..9d2b4fac 100644 --- a/doc/JA/faq_general.md +++ b/doc/JA/faq_general.md @@ -1,6 +1,5 @@ # Erg FAQ - このFAQは一般のErg入門者向けです。 個別の(よくある)技術的な問題については[こちら](./faq_technical.md)を、文法の決定経緯(なぜこのような文法になったのか)などについては [こちら](./dev_guide/why.md)を参照してください。 diff --git a/doc/JA/faq_technical.md b/doc/JA/faq_technical.md index 8faeee50..affbc713 100644 --- a/doc/JA/faq_technical.md +++ b/doc/JA/faq_technical.md @@ -1,6 +1,5 @@ # 技術的なFAQ - 本項はErg言語を使用する上での技術的な質問に答えるものです。すなわち、WhatやWhichで始まる質問、Yes/Noで答えられる質問を載せています。 根本的な文法の決定経緯については[こちら](./dev_guide/faq_syntax.md)を、なぜこの言語を作ったのか、この機能はどのように実装されているのかなど、より大きな話題は[こちら](./dev_guide/../faq_general.md)を参照してください。 diff --git a/doc/JA/improved_points.md b/doc/JA/improved_points.md index 1e0f6dbb..eb3d7f51 100644 --- a/doc/JA/improved_points.md +++ b/doc/JA/improved_points.md @@ -1,6 +1,5 @@ # Pythonから改良された点 - ## 静的解析を行う(静的型チェック、変数・プロパティチェック) 静的型チェックの恩恵は今更強調するまでもないほどですが、変数・プロパティの存在チェックもかなり効いてくる部分です。 diff --git a/doc/JA/index.md b/doc/JA/index.md index 0b95fd68..db3516f8 100644 --- a/doc/JA/index.md +++ b/doc/JA/index.md @@ -1,6 +1,5 @@ # Index - ## [API/](./API/index.md) Ergの組み込みまたは標準ライブラリで提供されるサブルーチン、型、定数等の仕様が記述されている。 diff --git a/doc/JA/migration_from_py.md b/doc/JA/migration_from_py.md index 3ffaf52a..4f1daf8c 100644 --- a/doc/JA/migration_from_py.md +++ b/doc/JA/migration_from_py.md @@ -1,6 +1,5 @@ # PythonからErgへの移行に関してのTips - ## 文字列をint等に変換したい `Str`クラスの`parse`メソッドを使用してください。これは`Result`型を返します。 diff --git a/doc/JA/syntax/00_basic.md b/doc/JA/syntax/00_basic.md index 95ba5f6d..d2cb5332 100644 --- a/doc/JA/syntax/00_basic.md +++ b/doc/JA/syntax/00_basic.md @@ -1,6 +1,5 @@ # 基本事項 - > __Warning__: 本ドキュメントは未完成です。校正(文体、正しいリンクが張られているか、など)がなされていません。また、Ergの文法はバージョン0.*の間に破壊的変更が加えられる可能性があり、それに伴うドキュメントの更新が追いついていない可能性があります。予めご了承ください。 > また、本ドキュメントの誤りを見つけた場合は、[こちらのフォーム](https://forms.gle/HtLYRfYzWCAaeTGb6)または[GitHubリポジトリ](https://github.com/mtshiba/TheErgBook/issues/new)から修正の提案をしていただけると幸いです。 diff --git a/doc/JA/syntax/01_literal.md b/doc/JA/syntax/01_literal.md index a7310dd5..6db8d8a5 100644 --- a/doc/JA/syntax/01_literal.md +++ b/doc/JA/syntax/01_literal.md @@ -1,6 +1,5 @@ # Literal - ## 基本的なリテラル ### 整数リテラル(Int Literal) diff --git a/doc/JA/syntax/02_name.md b/doc/JA/syntax/02_name.md index 1e9ee3ba..7bb732d9 100644 --- a/doc/JA/syntax/02_name.md +++ b/doc/JA/syntax/02_name.md @@ -1,6 +1,5 @@ # 変数 - 変数は代数の一種です。Ergにおける代数―紛れがなければ単に変数と呼ばれることもあります―とは、オブジェクトを名前付けしてコード中の別の場所から利用できるようにする機能を指します。 変数は以下のように定義します。 diff --git a/doc/JA/syntax/03_declaration.md b/doc/JA/syntax/03_declaration.md index 9d8638c9..2278a3dc 100644 --- a/doc/JA/syntax/03_declaration.md +++ b/doc/JA/syntax/03_declaration.md @@ -1,6 +1,5 @@ # Declaration(宣言) - 宣言は、使用する変数の型を指定する構文です。 宣言はコード中のどこでも可能ですが、宣言しただけでその変数を参照することはできません。必ず初期化する必要があります。 代入後の宣言では、代入されたオブジェクトと型が適合するかをチェック可能です。 diff --git a/doc/JA/syntax/04_function.md b/doc/JA/syntax/04_function.md index 3b88a348..e0262688 100644 --- a/doc/JA/syntax/04_function.md +++ b/doc/JA/syntax/04_function.md @@ -1,6 +1,5 @@ # 関数 - 関数は「引数」を受け取ってそれを加工し、「戻り値」として返すブロックです。以下のように定義します。 ```python diff --git a/doc/JA/syntax/05_builtin_funcs.md b/doc/JA/syntax/05_builtin_funcs.md index edcc2179..e0f973e0 100644 --- a/doc/JA/syntax/05_builtin_funcs.md +++ b/doc/JA/syntax/05_builtin_funcs.md @@ -1,6 +1,5 @@ # 組み込み関数 - ## if `if`は条件に応じて処理を変える関数です。 diff --git a/doc/JA/syntax/06_operator.md b/doc/JA/syntax/06_operator.md index b3d6857a..6747385d 100644 --- a/doc/JA/syntax/06_operator.md +++ b/doc/JA/syntax/06_operator.md @@ -1,6 +1,5 @@ # 演算子 - 演算子(オペレーター)は、演算を表す記号です。被演算子(オペランド)は演算子の(左)右にあるもので、Ergでは専らオブジェクトです。 演算子は関数の一種であり、したがってそれ自体も第一級オブジェクトで変数に束縛できます。束縛の際は``で囲む必要があります。 diff --git a/doc/JA/syntax/07_side_effect.md b/doc/JA/syntax/07_side_effect.md index df1381f2..7c1e5b76 100644 --- a/doc/JA/syntax/07_side_effect.md +++ b/doc/JA/syntax/07_side_effect.md @@ -1,6 +1,5 @@ # 副作用とプロシージャ - これまで`print!`の`!`の意味を説明せずにいましたが、いよいよその意味が明かされます。この!は、ズバリこのオブジェクトが「副作用」のある「プロシージャ」であることを示しています。プロシージャは関数に「副作用」という効果を与えたものです。 ```python diff --git a/doc/JA/syntax/08_procedure.md b/doc/JA/syntax/08_procedure.md index 34729273..1cddedc9 100644 --- a/doc/JA/syntax/08_procedure.md +++ b/doc/JA/syntax/08_procedure.md @@ -1,6 +1,5 @@ # プロシージャ - プロシージャは可変オブジェクトを取り扱う際に必要となりますが、可変オブジェクトを引数に持てばプロシージャであるとは限りません。 ```python diff --git a/doc/JA/syntax/09_builtin_procs.md b/doc/JA/syntax/09_builtin_procs.md index ccdd0a9f..d360673d 100644 --- a/doc/JA/syntax/09_builtin_procs.md +++ b/doc/JA/syntax/09_builtin_procs.md @@ -1,6 +1,5 @@ # 組み込みプロシージャ - ## id! オブジェクトのユニークな識別番号を返します。 diff --git a/doc/JA/syntax/10_array.md b/doc/JA/syntax/10_array.md index 7d9c413b..73706278 100644 --- a/doc/JA/syntax/10_array.md +++ b/doc/JA/syntax/10_array.md @@ -1,6 +1,5 @@ # 配列 - 配列はもっとも基本的な __コレクション(集約)__ です。 コレクションとは、内部にオブジェクトを複数保持できるオブジェクトのことです。 diff --git a/doc/JA/syntax/11_tuple.md b/doc/JA/syntax/11_tuple.md index d734d6f7..b395a601 100644 --- a/doc/JA/syntax/11_tuple.md +++ b/doc/JA/syntax/11_tuple.md @@ -1,6 +1,5 @@ # タプル - タプルは配列と似ていますが、違う型のオブジェクトを保持できます。 このようなコレクションを非等質なコレクションと呼びます。対して等質なコレクションには配列、セットなどがあります。 diff --git a/doc/JA/syntax/12_dict.md b/doc/JA/syntax/12_dict.md index 56859e74..8918200b 100644 --- a/doc/JA/syntax/12_dict.md +++ b/doc/JA/syntax/12_dict.md @@ -1,6 +1,5 @@ # Dict - Dictはキーと値のペアを持つコレクションです。 ```python diff --git a/doc/JA/syntax/13_record.md b/doc/JA/syntax/13_record.md index c5711133..ff2ba75f 100644 --- a/doc/JA/syntax/13_record.md +++ b/doc/JA/syntax/13_record.md @@ -1,6 +1,5 @@ # レコード - レコードは、キーでアクセスするDictとコンパイル時にアクセスが検査されるタプルの性質を併せ持つコレクションです。 JavaScriptをやったことがある方ならば、オブジェクトリテラル記法の(より強化された)ようなものと考えてください。 diff --git a/doc/JA/syntax/14_set.md b/doc/JA/syntax/14_set.md index d63ace6c..4a69f085 100644 --- a/doc/JA/syntax/14_set.md +++ b/doc/JA/syntax/14_set.md @@ -1,6 +1,5 @@ # セット(Set) - セットは集合を表し、データ構造的には重複、順序のない配列です。 ```python diff --git a/doc/JA/syntax/15_type.md b/doc/JA/syntax/15_type.md index f8dd29da..840b24fc 100644 --- a/doc/JA/syntax/15_type.md +++ b/doc/JA/syntax/15_type.md @@ -1,6 +1,5 @@ # 型 - 型はErgにおいて非常に重要な機能ですので、[専用のセクション](./type/01_type_system.md)を用意しています。そちらをご覧ください。

diff --git a/doc/JA/syntax/16_iterator.md b/doc/JA/syntax/16_iterator.md index b9a3bf83..affcb68e 100644 --- a/doc/JA/syntax/16_iterator.md +++ b/doc/JA/syntax/16_iterator.md @@ -1,6 +1,5 @@ # イテレータ - イテレータは、コンテナの要素を取り出すためのオブジェクトです。 ```python diff --git a/doc/JA/syntax/17_mutability.md b/doc/JA/syntax/17_mutability.md index 5f9a3ad9..2271632e 100644 --- a/doc/JA/syntax/17_mutability.md +++ b/doc/JA/syntax/17_mutability.md @@ -1,6 +1,5 @@ # Mutability - すでに見たように、Ergの変数は全て不変です。しかし、Ergのオブジェクトには可変性という概念があります。 以下のコードを例にします。 diff --git a/doc/JA/syntax/18_ownership.md b/doc/JA/syntax/18_ownership.md index 302d17b6..4970db77 100644 --- a/doc/JA/syntax/18_ownership.md +++ b/doc/JA/syntax/18_ownership.md @@ -1,6 +1,5 @@ # 所有権システム - ErgはPythonをホスト言語にした言語であるため、メモリ管理の方法はPythonの処理系に依存しています。 しかし、意味論的にはErgのメモリ管理はPythonのそれとは別物です。顕著な違いは、所有権システムと循環参照の禁止に現れています。 diff --git a/doc/JA/syntax/19_visibility.md b/doc/JA/syntax/19_visibility.md index 72309793..489cce62 100644 --- a/doc/JA/syntax/19_visibility.md +++ b/doc/JA/syntax/19_visibility.md @@ -1,6 +1,5 @@ # 可視性(Visibility) - Ergの変数には __可視性__ という概念が存在します。 今まで見てきた変数は全て __プライベート変数(非公開変数)__ と呼ばれます。これは、外部から不可視の変数です。 例えば`foo`モジュールで定義したプライベート変数は、別のモジュールから参照できないのです。 diff --git a/doc/JA/syntax/20_naming_rule.md b/doc/JA/syntax/20_naming_rule.md index 78f39931..5b8617de 100644 --- a/doc/JA/syntax/20_naming_rule.md +++ b/doc/JA/syntax/20_naming_rule.md @@ -1,6 +1,5 @@ # 命名規則 - 変数を定数式として使いたい場合は、必ず大文字で始めます。二文字以降は小文字でもよいです。 ```python diff --git a/doc/JA/syntax/21_lambda.md b/doc/JA/syntax/21_lambda.md index fa1ae96b..7a29084f 100644 --- a/doc/JA/syntax/21_lambda.md +++ b/doc/JA/syntax/21_lambda.md @@ -1,6 +1,5 @@ # 無名関数(anonymous function) - 無名関数は、関数オブジェクトを名付けずその場で生成するための文法です。 ```python diff --git a/doc/JA/syntax/22_subroutine.md b/doc/JA/syntax/22_subroutine.md index 7ea16d94..6bc287b2 100644 --- a/doc/JA/syntax/22_subroutine.md +++ b/doc/JA/syntax/22_subroutine.md @@ -1,6 +1,5 @@ # Subroutine signatures - ## Func ```python diff --git a/doc/JA/syntax/23_closure.md b/doc/JA/syntax/23_closure.md index bf4f8bd0..f8ff31d8 100644 --- a/doc/JA/syntax/23_closure.md +++ b/doc/JA/syntax/23_closure.md @@ -1,6 +1,5 @@ # クロージャ - Ergのサブルーチンには、外部変数を捕捉する「クロージャ」という機能があります。 ```python diff --git a/doc/JA/syntax/24_module.md b/doc/JA/syntax/24_module.md index abc00723..613f6ee9 100644 --- a/doc/JA/syntax/24_module.md +++ b/doc/JA/syntax/24_module.md @@ -1,6 +1,5 @@ # モジュール - Ergでは、ファイル自体を1つのレコードとみなすことができます。これをモジュールと呼びます。 ```python: foo.er diff --git a/doc/JA/syntax/25_object_system.md b/doc/JA/syntax/25_object_system.md index 75a967e8..4a387b0a 100644 --- a/doc/JA/syntax/25_object_system.md +++ b/doc/JA/syntax/25_object_system.md @@ -1,6 +1,5 @@ # Object(対象体) - 変数に代入できる全てのデータです。`Object`クラスの持つ属性は以下の通りです。 * `.__repr__`: オブジェクトの(リッチでない)文字列表現を返します diff --git a/doc/JA/syntax/26_pattern_matching.md b/doc/JA/syntax/26_pattern_matching.md index d6d9bd23..1c2399a8 100644 --- a/doc/JA/syntax/26_pattern_matching.md +++ b/doc/JA/syntax/26_pattern_matching.md @@ -1,6 +1,5 @@ # パターンマッチ、論駁可能性 - ## Ergで使用可能なパターン ### 変数パターン diff --git a/doc/JA/syntax/27_comprehension.md b/doc/JA/syntax/27_comprehension.md index 99312cb0..70edab21 100644 --- a/doc/JA/syntax/27_comprehension.md +++ b/doc/JA/syntax/27_comprehension.md @@ -1,6 +1,5 @@ # Comprehension(内包表記) - `[expr | (name <- iterable)+ (predicate)*]`で配列、 `{expr | (name <- iterable)+ (predicate)*}`でセット、 `{key: value | (name <- iterable)+ (predicate)*}`でDictが作れます。 diff --git a/doc/JA/syntax/28_spread_syntax.md b/doc/JA/syntax/28_spread_syntax.md index e5bcdfa8..1c16844d 100644 --- a/doc/JA/syntax/28_spread_syntax.md +++ b/doc/JA/syntax/28_spread_syntax.md @@ -1,6 +1,5 @@ # Spread assignment (展開代入) - 分解代入において、変数の前に`...`を置くと残りの要素を全てその変数に展開できます。これを展開代入と呼びます。 ```python diff --git a/doc/JA/syntax/29_decorator.md b/doc/JA/syntax/29_decorator.md index ed9f1705..34f02216 100644 --- a/doc/JA/syntax/29_decorator.md +++ b/doc/JA/syntax/29_decorator.md @@ -1,6 +1,5 @@ # デコレータ(修飾子) - デコレータは型や関数に特定の状態や振る舞いを追加したり明示するために使われます。 デコレータの文法は以下の通りです。 diff --git a/doc/JA/syntax/30_error_handling.md b/doc/JA/syntax/30_error_handling.md index e8713e96..f870b0d2 100644 --- a/doc/JA/syntax/30_error_handling.md +++ b/doc/JA/syntax/30_error_handling.md @@ -1,6 +1,5 @@ # エラーハンドリングシステム - 主にResult型を使用します。 ErgではError型オブジェクトを捨てる(トップレベルで対応しない)とエラーが発生します。 diff --git a/doc/JA/syntax/31_pipeline.md b/doc/JA/syntax/31_pipeline.md index 7faf14a2..ab861a70 100644 --- a/doc/JA/syntax/31_pipeline.md +++ b/doc/JA/syntax/31_pipeline.md @@ -1,6 +1,5 @@ # パイプライン演算子 - パイプライン演算子は、次のように使います。 ```python diff --git a/doc/JA/syntax/32_integration_with_Python.md b/doc/JA/syntax/32_integration_with_Python.md index 438ecd45..473d4334 100644 --- a/doc/JA/syntax/32_integration_with_Python.md +++ b/doc/JA/syntax/32_integration_with_Python.md @@ -1,6 +1,5 @@ # Pythonとの連携 - ## Pythonへのexport Ergスクリプトをコンパイルすると.pycファイルが生成されますが、これは単純にPythonのモジュールとして読み込むことができます。 diff --git a/doc/JA/syntax/33_package_system.md b/doc/JA/syntax/33_package_system.md index b9e46e10..79a1229e 100644 --- a/doc/JA/syntax/33_package_system.md +++ b/doc/JA/syntax/33_package_system.md @@ -1,6 +1,5 @@ # パッケージシステム - Ergのパッケージはアプリケーションであるappパッケージとライブラリであるlibパッケージに大別できます。 appパッケージのエントリポイントは`src/app.er`です。`app.er`内に定義された`main`関数が実行されます。 libパッケージのエントリポイントは`src/lib.er`です。パッケージをインポートすることは`lib.er`をインポートすることと等価になります。 diff --git a/doc/JA/syntax/34_generator.md b/doc/JA/syntax/34_generator.md index 868412a2..8d883748 100644 --- a/doc/JA/syntax/34_generator.md +++ b/doc/JA/syntax/34_generator.md @@ -1,6 +1,5 @@ # ジェネレータ - ジェネレータは、ブロック中で`yield!`プロシージャを使う特殊なプロシージャです。 ```python diff --git a/doc/JA/syntax/SUMMARY.md b/doc/JA/syntax/SUMMARY.md index 3c2772e9..774c354b 100644 --- a/doc/JA/syntax/SUMMARY.md +++ b/doc/JA/syntax/SUMMARY.md @@ -1,6 +1,5 @@ # Summary - - [Basics](./00_basic.md) - [Literal](./01_literal.md) - [Name](02_name.md) diff --git a/doc/JA/syntax/container_ownership.md b/doc/JA/syntax/container_ownership.md index 28ce256d..c464e579 100644 --- a/doc/JA/syntax/container_ownership.md +++ b/doc/JA/syntax/container_ownership.md @@ -1,6 +1,5 @@ # Subscript(添字アクセス) - `[]`は通常のメソッドとは異なっています。 ```python diff --git a/doc/JA/syntax/indexes.md b/doc/JA/syntax/indexes.md index 7c56e81c..0db44b64 100644 --- a/doc/JA/syntax/indexes.md +++ b/doc/JA/syntax/indexes.md @@ -1,6 +1,5 @@ # 索引 - この索引にないAPIについては[こちら](../API/index.md)を参照してください。 用語の意味については[こちら](../dev_guide/terms.md)を参照。 diff --git a/doc/JA/syntax/quick_tour.md b/doc/JA/syntax/quick_tour.md index 18944eae..414803d2 100644 --- a/doc/JA/syntax/quick_tour.md +++ b/doc/JA/syntax/quick_tour.md @@ -1,6 +1,5 @@ # Quick Tour - `syntax`以下のドキュメントは、概ねプログラミング初心者でも理解できることを目指して書かれています。 すでにPythonやRust, Haskellなどの言語を習得されている方にとっては、少し冗長であるかもしれません。 diff --git a/doc/JA/syntax/type/01_type_system.md b/doc/JA/syntax/type/01_type_system.md index 9803c681..238af1bc 100644 --- a/doc/JA/syntax/type/01_type_system.md +++ b/doc/JA/syntax/type/01_type_system.md @@ -1,6 +1,5 @@ # Ergの型システム - 以下では、Ergの型システムを概略的に説明します。詳細については他の項で解説します。 ## 定義方法 diff --git a/doc/JA/syntax/type/02_basic.md b/doc/JA/syntax/type/02_basic.md index 49ec720d..9eeefc1a 100644 --- a/doc/JA/syntax/type/02_basic.md +++ b/doc/JA/syntax/type/02_basic.md @@ -1,6 +1,5 @@ # 型に関する基本的な文法 - ## 型指定 Ergでは以下のように`:`の後に変数の型を指定します。代入と同時に行うこともできます。 diff --git a/doc/JA/syntax/type/03_trait.md b/doc/JA/syntax/type/03_trait.md index d5ac7550..8f794755 100644 --- a/doc/JA/syntax/type/03_trait.md +++ b/doc/JA/syntax/type/03_trait.md @@ -1,6 +1,5 @@ # トレイト - トレイトは、レコード型に型属性の要求を追加した記名型です。 Pythonでいう抽象基底クラス(Abstract Base Class, ABC)に類似しますが、代数的演算を行えるという特徴があります。 diff --git a/doc/JA/syntax/type/04_class.md b/doc/JA/syntax/type/04_class.md index ea41ff0d..7eff7f0d 100644 --- a/doc/JA/syntax/type/04_class.md +++ b/doc/JA/syntax/type/04_class.md @@ -1,6 +1,5 @@ # Class - Ergにおけるクラスは、大まかには自身の要素(インスタンス)を生成できる型と言えます。 以下は単純なクラスの例です。 diff --git a/doc/JA/syntax/type/05_inheritance.md b/doc/JA/syntax/type/05_inheritance.md index 4722b60a..eab04bd0 100644 --- a/doc/JA/syntax/type/05_inheritance.md +++ b/doc/JA/syntax/type/05_inheritance.md @@ -1,6 +1,5 @@ # 継承(Inheritance) - 継承を使うと、既存のクラスに機能を加えたり特化したりした新しいクラスを定義できます。 継承はトレイトにおける包摂に似ています。継承してできたクラスは、もとのクラスのサブタイプになります。 diff --git a/doc/JA/syntax/type/06_nst_vs_sst.md b/doc/JA/syntax/type/06_nst_vs_sst.md index 7643a49d..20e23b39 100644 --- a/doc/JA/syntax/type/06_nst_vs_sst.md +++ b/doc/JA/syntax/type/06_nst_vs_sst.md @@ -1,6 +1,5 @@ # 記名的部分型 vs. 構造的部分型 - ```python Months = 0..12 diff --git a/doc/JA/syntax/type/07_patch.md b/doc/JA/syntax/type/07_patch.md index 5bf1b40e..a535d769 100644 --- a/doc/JA/syntax/type/07_patch.md +++ b/doc/JA/syntax/type/07_patch.md @@ -1,6 +1,5 @@ # Patch - Ergでは、既存の型・クラスに手を加えることはできません。 クラスにメソッドを追加で定義することはできず、特殊化(specialization, 多相に宣言された型を単相化し専用のメソッドを定義する機能。C++などが持つ)も行えません。 しかし、既存の型・クラスに機能を追加したいという状況は多々あり、これを実現するためにパッチという機能があります。 diff --git a/doc/JA/syntax/type/08_value.md b/doc/JA/syntax/type/08_value.md index ad50a386..ae81cd95 100644 --- a/doc/JA/syntax/type/08_value.md +++ b/doc/JA/syntax/type/08_value.md @@ -1,6 +1,5 @@ # 値型(Value types) - 値型はErg組み込み型のうちコンパイル時評価が可能な型で、具体的には以下のものです。 ```python diff --git a/doc/JA/syntax/type/09_attributive.md b/doc/JA/syntax/type/09_attributive.md index c9d470b6..96dce87e 100644 --- a/doc/JA/syntax/type/09_attributive.md +++ b/doc/JA/syntax/type/09_attributive.md @@ -1,6 +1,5 @@ # 属性型(Attributive Type) - 属性型は、レコードおよびデータクラス、パッチ、モジュールなどが含まれる型です。 属性型に属する型は値型ではありません。 diff --git a/doc/JA/syntax/type/10_interval.md b/doc/JA/syntax/type/10_interval.md index 4786c8f4..75c489c5 100644 --- a/doc/JA/syntax/type/10_interval.md +++ b/doc/JA/syntax/type/10_interval.md @@ -1,6 +1,5 @@ # Interval Type - `Range`オブジェクトの最も基本的な使い方は、イテレータとしての使用です。 ```python diff --git a/doc/JA/syntax/type/11_enum.md b/doc/JA/syntax/type/11_enum.md index 3decde83..b82dcdc9 100644 --- a/doc/JA/syntax/type/11_enum.md +++ b/doc/JA/syntax/type/11_enum.md @@ -1,6 +1,5 @@ # Enumerative Type(列挙型) - 列挙型(Enum type)はSetによって生成されます。 列挙型はそのままでも型指定で使えますが、クラス化したりパッチを定義することで更にメソッドを定義できます。 列挙型による部分型システムを列挙的部分型付けといいます。 diff --git a/doc/JA/syntax/type/12_refinement.md b/doc/JA/syntax/type/12_refinement.md index 24a1a7ca..b49d5774 100644 --- a/doc/JA/syntax/type/12_refinement.md +++ b/doc/JA/syntax/type/12_refinement.md @@ -1,6 +1,5 @@ # 篩型(Refinement Type) - Refinement type(篩型、ふるいがた)は、述語式によって制約付けられた型です。列挙型や区間型は篩型の一種です。 篩型の標準形は`{Elem: Type | (Pred)*}`です。これは、`Pred`を満たす`Elem`を要素とする型である、という意味です。 diff --git a/doc/JA/syntax/type/13_algebraic.md b/doc/JA/syntax/type/13_algebraic.md index bf7e2c04..51238f0d 100644 --- a/doc/JA/syntax/type/13_algebraic.md +++ b/doc/JA/syntax/type/13_algebraic.md @@ -1,6 +1,5 @@ # Algebraic type (代数演算型) - 代数演算型は、型を代数のようにみなして演算することで生成される型のことです。 代数演算型が扱う演算は、Union, Intersection, Diff, Complementなどがあります。 通常のクラスはUnionのみが行えて、他の演算は型エラーになります。 diff --git a/doc/JA/syntax/type/14_dependent.md b/doc/JA/syntax/type/14_dependent.md index ba923522..f8e4f6ae 100644 --- a/doc/JA/syntax/type/14_dependent.md +++ b/doc/JA/syntax/type/14_dependent.md @@ -1,6 +1,5 @@ # 依存型 - 依存型はErgの最大の特徴とも言っても良い機能です。 依存型とは、値を引数に取る型です。通常の多相型は型のみを引数に取れますが、その制限を緩めたのが依存型といえます。 diff --git a/doc/JA/syntax/type/15_quantified.md b/doc/JA/syntax/type/15_quantified.md index c5dd0f2a..9a134bf3 100644 --- a/doc/JA/syntax/type/15_quantified.md +++ b/doc/JA/syntax/type/15_quantified.md @@ -1,6 +1,5 @@ # 型変数(Type Variable)、量化型 - 型変数はサブルーチン引数の型指定などに使用する変数で、その型が任意である(単相化しない)ことを示します。 まず、型変数を導入するモチベーションとして、入力をそのまま返す`id`関数について考えましょう。 diff --git a/doc/JA/syntax/type/16_subtyping.md b/doc/JA/syntax/type/16_subtyping.md index d425f6fd..96d0e1ba 100644 --- a/doc/JA/syntax/type/16_subtyping.md +++ b/doc/JA/syntax/type/16_subtyping.md @@ -1,6 +1,5 @@ # 部分型付け - Ergでは、クラス同士の包含関係は比較演算子`<`, `>`で判定可能です。 ```python diff --git a/doc/JA/syntax/type/17_type_casting.md b/doc/JA/syntax/type/17_type_casting.md index 24046b67..d30a919b 100644 --- a/doc/JA/syntax/type/17_type_casting.md +++ b/doc/JA/syntax/type/17_type_casting.md @@ -1,6 +1,5 @@ # キャスト - ## アップキャスト Pythonはダックタイピングを採用する言語のため、キャストという概念はありません。アップキャストはする必要がなく、ダウンキャストも基本的にはありません。 diff --git a/doc/JA/syntax/type/18_mut.md b/doc/JA/syntax/type/18_mut.md index fbc3fd6c..24c97a81 100644 --- a/doc/JA/syntax/type/18_mut.md +++ b/doc/JA/syntax/type/18_mut.md @@ -1,6 +1,5 @@ # 可変型(Mutable Type) - > __Warning__: この項の情報は古く、一部に間違いを含みます。 Ergではデフォルトですべての型が不変型、すなわち内部状態を更新できないようになっています。 diff --git a/doc/JA/syntax/type/19_bound.md b/doc/JA/syntax/type/19_bound.md index 2bc125a5..ea121878 100644 --- a/doc/JA/syntax/type/19_bound.md +++ b/doc/JA/syntax/type/19_bound.md @@ -1,6 +1,5 @@ # 型境界 (Type Bound) - 型境界は型指定に条件を加えるものである。これを実現する機能がガード(ガード節)である。 関数シグニチャ、無名関数シグニチャのほか、篩型でもこの機能を利用できる。 ガードは戻り値型の後に記述する。 diff --git a/doc/JA/syntax/type/advanced/GADTs.md b/doc/JA/syntax/type/advanced/GADTs.md index 40790c18..6a7d7958 100644 --- a/doc/JA/syntax/type/advanced/GADTs.md +++ b/doc/JA/syntax/type/advanced/GADTs.md @@ -1,6 +1,5 @@ # 一般化代数的データ型(Generalized Algebraic Data Types, GADTs) - ErgはOr型をクラス化することで一般化代数的データ型(GADTs)を作成出来ます。 ```python diff --git a/doc/JA/syntax/type/advanced/default_param.md b/doc/JA/syntax/type/advanced/default_param.md index 4e2568f1..48714c73 100644 --- a/doc/JA/syntax/type/advanced/default_param.md +++ b/doc/JA/syntax/type/advanced/default_param.md @@ -1,6 +1,5 @@ # デフォルト引数付きの関数型 - まず、デフォルト引数の使用例を見る。 ```python diff --git a/doc/JA/syntax/type/advanced/erasure.md b/doc/JA/syntax/type/advanced/erasure.md index fd41b4c5..df15e071 100644 --- a/doc/JA/syntax/type/advanced/erasure.md +++ b/doc/JA/syntax/type/advanced/erasure.md @@ -1,6 +1,5 @@ # 型消去(Type erasure) - 型消去とは、型引数に`_`を指定し、その情報をあえて捨てることです。型消去は多相型を持つ言語の多くが併せて持つ機能ですが、Ergの文法に即して言えば型引数消去といった方が正確でしょう。 もっともよく見られる型消去された型の例は`[T, _]`でしょう。配列はコンパイル時にその長さが分からない場合もあります。例えば、コマンドライン引数を指す`sys.argv`は`[Str, _]`型です。コマンドライン引数の長さをErgのコンパイラは知りようがないため、長さに関する情報は諦めなくてはならないのです。 diff --git a/doc/JA/syntax/type/advanced/existential.md b/doc/JA/syntax/type/advanced/existential.md index b81cd7ea..fe346e93 100644 --- a/doc/JA/syntax/type/advanced/existential.md +++ b/doc/JA/syntax/type/advanced/existential.md @@ -1,6 +1,5 @@ # 存在型 - ∀に対応する全称型があるならば、∃に対応する存在型があると考えるのが自然です。 存在型は難しいものではありません。そうと意識していないだけで、既にあなたは存在型を知っています。 diff --git a/doc/JA/syntax/type/advanced/keyword_param.md b/doc/JA/syntax/type/advanced/keyword_param.md index 2fa54313..af031750 100644 --- a/doc/JA/syntax/type/advanced/keyword_param.md +++ b/doc/JA/syntax/type/advanced/keyword_param.md @@ -1,6 +1,5 @@ # キーワード引数付き関数型 - ```python h(f) = f(y: 1, x: 2) h: |T: Type|((y: Int, x: Int) -> T) -> T diff --git a/doc/JA/syntax/type/advanced/kind.md b/doc/JA/syntax/type/advanced/kind.md index bfbce7e2..2140a96c 100644 --- a/doc/JA/syntax/type/advanced/kind.md +++ b/doc/JA/syntax/type/advanced/kind.md @@ -1,6 +1,5 @@ # カインド(Kind) - Ergでは全てが型付けられている。型自体も例外ではない。「型の型」を表すのが __カインド(種)__ である。例えば`1`が`Int`に属しているように、`Int`は`Type`に属している。`Type`は最もシンプルなカインドである __原子カインド(Atomic kind)__ である。型理論的の記法では、`Type`は`*`に対応する。 カインドという概念で実用上重要なのは1項以上のカインド(多項カインド)である。1項のカインドは、例えば`Option`などがそれに属する。1項カインドは`Type -> Type`と表される[1](#1)。`Array`や`Option`などの __コンテナ__ は特に型を引数に取る多項カインドのことなのである。 diff --git a/doc/JA/syntax/type/advanced/marker_trait.md b/doc/JA/syntax/type/advanced/marker_trait.md index d06105ac..529b8007 100644 --- a/doc/JA/syntax/type/advanced/marker_trait.md +++ b/doc/JA/syntax/type/advanced/marker_trait.md @@ -1,6 +1,5 @@ # Marker Trait - マーカートレイトは、要求属性のないトレイトである。すなわち、メソッドを実装せずにImplすることができる。 要求属性がないと意味がないように思えるが、そのトレイトに属しているという情報が登録されるので、パッチメソッドを使ったり、コンパイラが特別扱いしたりできる。 diff --git a/doc/JA/syntax/type/advanced/mut_struct.md b/doc/JA/syntax/type/advanced/mut_struct.md index 3389c229..b3a5cffb 100644 --- a/doc/JA/syntax/type/advanced/mut_struct.md +++ b/doc/JA/syntax/type/advanced/mut_struct.md @@ -1,6 +1,5 @@ # 可変構造型 - `T!`型は任意の`T`型オブジェクトを入れられて差し替え可能なボックス型であると説明した。 ```python diff --git a/doc/JA/syntax/type/advanced/newtype.md b/doc/JA/syntax/type/advanced/newtype.md index f7703a5e..121cc5ab 100644 --- a/doc/JA/syntax/type/advanced/newtype.md +++ b/doc/JA/syntax/type/advanced/newtype.md @@ -1,6 +1,5 @@ # Newtype pattern - ここでは、Rustでよく使われるnewtypeパターンのErg版を紹介します。 Ergはでは以下のように型のエイリアスを定義できますが、これはあくまで同じ型を指します。 diff --git a/doc/JA/syntax/type/advanced/overloading.md b/doc/JA/syntax/type/advanced/overloading.md index 80cead4e..0fe43edf 100644 --- a/doc/JA/syntax/type/advanced/overloading.md +++ b/doc/JA/syntax/type/advanced/overloading.md @@ -1,6 +1,5 @@ # オーバーロード - Ergでは __アドホック多相__ をサポートしない。すなわち、関数・カインドの多重定義(オーバーロード)ができない。が、トレイトクラスとパッチを組み合わせることでオーバーロードの挙動を再現できる。 トレイトクラスのかわりにトレイトを使用しても良いが、その場合`.add1`を実装している型全てが対象になってしまう。 diff --git a/doc/JA/syntax/type/advanced/phantom.md b/doc/JA/syntax/type/advanced/phantom.md index 15280cd7..f2df3fed 100644 --- a/doc/JA/syntax/type/advanced/phantom.md +++ b/doc/JA/syntax/type/advanced/phantom.md @@ -1,6 +1,5 @@ # 幽霊型(Phantom class) - 幽霊型は、コンパイラに注釈を与えるためだけに存在するマーカートレイトである。 幽霊型の使い方として、リストの構成をみる。 diff --git a/doc/JA/syntax/type/advanced/projection.md b/doc/JA/syntax/type/advanced/projection.md index e12ef9ae..119ffe3d 100644 --- a/doc/JA/syntax/type/advanced/projection.md +++ b/doc/JA/syntax/type/advanced/projection.md @@ -1,6 +1,5 @@ # Projection Type(射影型) - 射影型は、次のコードにおける`Self.AddO`のような型を表します。 ```python diff --git a/doc/JA/syntax/type/advanced/quantified_dependent.md b/doc/JA/syntax/type/advanced/quantified_dependent.md index 00a62c2d..80abf07e 100644 --- a/doc/JA/syntax/type/advanced/quantified_dependent.md +++ b/doc/JA/syntax/type/advanced/quantified_dependent.md @@ -1,6 +1,5 @@ # 量化依存型 - Ergには量化型、依存型が存在します。すると当然、その二つを組み合わせた型を作ることができます。それが量化依存型です。 ```python diff --git a/doc/JA/syntax/type/advanced/shared.md b/doc/JA/syntax/type/advanced/shared.md index cb2dbaa1..f3c6d4bb 100644 --- a/doc/JA/syntax/type/advanced/shared.md +++ b/doc/JA/syntax/type/advanced/shared.md @@ -1,6 +1,5 @@ # 共有参照(Shared Reference) - 共有参照は気をつけて扱わねばならない言語機能の一つです。 例えばTypeScriptでは以下のようなコードが型検査を通ってしまいます。 diff --git a/doc/JA/syntax/type/advanced/special.md b/doc/JA/syntax/type/advanced/special.md index b6cd401c..22de410a 100644 --- a/doc/JA/syntax/type/advanced/special.md +++ b/doc/JA/syntax/type/advanced/special.md @@ -1,6 +1,5 @@ # 特殊型(Self, Super) - `Self`は自身の型を表します。単にエイリアスとして使うことも出来ますが、派生型中では意味が変わる(自身の型を指す)ので注意してください。 ```python diff --git a/doc/JA/tips.md b/doc/JA/tips.md index b21ca905..700964dc 100644 --- a/doc/JA/tips.md +++ b/doc/JA/tips.md @@ -1,6 +1,5 @@ # Tips - ## エラーの表示言語を変えたい 各国語版のergをダウンロードしてください。 diff --git a/doc/zh_CN/dev_guide/faq_syntax.md b/doc/zh_CN/dev_guide/faq_syntax.md index 9ff0b713..23bcb495 100644 --- a/doc/zh_CN/dev_guide/faq_syntax.md +++ b/doc/zh_CN/dev_guide/faq_syntax.md @@ -48,7 +48,6 @@ assert S.i == Int 在 Erg 中,运算符使你可以在不太注意错误的情况下编写。 - ```python read_file!() = f = open!("foo.txt")? # 如果失败则立即返回错误,所以 f 是文件类型 @@ -77,7 +76,6 @@ Python 的库中有一些类设计为继承,如果完全取消继承,这些 默认情况下,指向结构托盘会使类型指定变得复杂,并且可能会混合程序员的非预期行为。 - ```python # 如果 T 是结构特征的子类型... # f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T diff --git a/doc/zh_CN/faq_technical.md b/doc/zh_CN/faq_technical.md index 896b120a..03fab7b5 100644 --- a/doc/zh_CN/faq_technical.md +++ b/doc/zh_CN/faq_technical.md @@ -1,6 +1,5 @@ # Technical FAQ - 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. 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). diff --git a/doc/zh_CN/python/bytecode_specification.md b/doc/zh_CN/python/bytecode_specification.md index 86fd9c27..036912c0 100644 --- a/doc/zh_CN/python/bytecode_specification.md +++ b/doc/zh_CN/python/bytecode_specification.md @@ -70,7 +70,6 @@ * 1~4 byte: length of string * 5~ byte: payload - # Python 字节码规范 ## 格式 diff --git a/doc/zh_CN/syntax/01_literal.md b/doc/zh_CN/syntax/01_literal.md index a285d8d3..9292471e 100644 --- a/doc/zh_CN/syntax/01_literal.md +++ b/doc/zh_CN/syntax/01_literal.md @@ -135,7 +135,6 @@ assert 0.0f32 == 0.0f64 一个“复杂”对象只是一个虚数单位对象`im`的算术组合 - ## *-less 乘法 在 Erg 中,您可以省略 `*` 来表示乘法,只要解释上没有混淆即可。 但是,运算符的组合强度设置为强于 `*`。 diff --git a/doc/zh_CN/syntax/21_lambda.md b/doc/zh_CN/syntax/21_lambda.md index 8cac3bea..820378f3 100644 --- a/doc/zh_CN/syntax/21_lambda.md +++ b/doc/zh_CN/syntax/21_lambda.md @@ -59,7 +59,6 @@ now = if! True: 您还可以键入和模式匹配。 正因为如此,`match` 函数大多是借助匿名函数的力量来实现的。 作为 `match` 函数的参数给出的匿名函数从顶部开始按顺序尝试。 因此,您应该在顶部描述特殊情况,在底部描述更一般的情况。 如果你弄错了顺序,编译器会发出警告(如果可能的话) - ```python n = (Complex or Ratio or Int).sample!() i = matchn: diff --git a/doc/zh_CN/syntax/32_integration_with_Python.md b/doc/zh_CN/syntax/32_integration_with_Python.md index d18ac194..25261dd0 100644 --- a/doc/zh_CN/syntax/32_integration_with_Python.md +++ b/doc/zh_CN/syntax/32_integration_with_Python.md @@ -65,7 +65,6 @@ assert foo.bar(1) in Int 这通过在运行时执行类型检查来确保类型安全。 ``declare`` 函数大致如下工作 - ```python declare|S: Subroutine| sub!: S, T = # 实际上,=> 可以强制转换为没有块副作用的函数 diff --git a/doc/zh_CN/syntax/type/13_algebraic.md b/doc/zh_CN/syntax/type/13_algebraic.md index 5567aafc..ae777027 100644 --- a/doc/zh_CN/syntax/type/13_algebraic.md +++ b/doc/zh_CN/syntax/type/13_algebraic.md @@ -9,7 +9,6 @@ 联合类型可以为类型提供多种可能性。 顾名思义,它们是由“或”运算符生成的。 一个典型的 Union 是 `Option` 类型。 `Option` 类型是 `T 或 NoneType` 补丁类型,主要表示可能失败的值。 - ```python IntOrStr = Int or Str assert dict.get("some key") in (Int or NoneType) diff --git a/doc/zh_CN/syntax/type/advanced/overloading.md b/doc/zh_CN/syntax/type/advanced/overloading.md index 3d75b07e..2689eb34 100644 --- a/doc/zh_CN/syntax/type/advanced/overloading.md +++ b/doc/zh_CN/syntax/type/advanced/overloading.md @@ -47,7 +47,6 @@ Erg 的立场是,您不能定义行为完全不同的函数,例如根据参 首先,重载函数分布在它们的定义中。 这使得在发生错误时很难报告错误的原因。 此外,导入子程序可能会改变已定义子程序的行为。 - ```python {id; ...} = import "foo" ... From 07160d2a8f1f1e2dc46d7e911e90fa0959f0cad4 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Mon, 5 Sep 2022 21:39:50 +0800 Subject: [PATCH 27/42] Complete traditional Chinese Translation --- doc/zh_TW/API/consts.md | 2 +- doc/zh_TW/API/funcs.md | 54 +- doc/zh_TW/API/modules/external/alstruct.md | 14 +- doc/zh_TW/API/modules/repl.md | 12 +- doc/zh_TW/API/modules/status.md | 4 +- doc/zh_TW/API/modules/unit.md | 62 +- doc/zh_TW/API/modules/unsound.md | 16 +- doc/zh_TW/API/operators.md | 40 +- doc/zh_TW/API/procs.md | 26 +- doc/zh_TW/API/special.md | 76 +-- doc/zh_TW/API/types.md | 166 +++--- doc/zh_TW/API/types/classes/Array!(T).md | 2 +- doc/zh_TW/API/types/classes/Array(T).md | 2 +- .../API/types/classes/ArrayWithLen(T,N).md | 10 +- .../types/classes/ArrayWithMutLength!(T,N).md | 10 +- doc/zh_TW/API/types/classes/Complex.md | 4 +- doc/zh_TW/API/types/classes/Dict!.md | 2 +- doc/zh_TW/API/types/classes/Either.md | 2 +- doc/zh_TW/API/types/classes/Float.md | 14 +- doc/zh_TW/API/types/classes/Inf.md | 10 +- doc/zh_TW/API/types/classes/Int.md | 10 +- doc/zh_TW/API/types/classes/IntRange.md | 2 +- doc/zh_TW/API/types/classes/Interval.md | 8 +- doc/zh_TW/API/types/classes/Matrix.md | 4 +- doc/zh_TW/API/types/classes/Nat.md | 4 +- doc/zh_TW/API/types/classes/Neg.md | 6 +- doc/zh_TW/API/types/classes/Never.md | 8 +- doc/zh_TW/API/types/classes/NonZero.md | 2 +- doc/zh_TW/API/types/classes/Object.md | 2 +- doc/zh_TW/API/types/classes/Operator.md | 4 +- doc/zh_TW/API/types/classes/Option.md | 4 +- doc/zh_TW/API/types/classes/Pos.md | 6 +- doc/zh_TW/API/types/classes/Ratio.md | 6 +- doc/zh_TW/API/types/classes/Record.md | 4 +- doc/zh_TW/API/types/classes/Result.md | 2 +- doc/zh_TW/API/types/classes/Str!.md | 2 +- doc/zh_TW/API/types/classes/Str.md | 4 +- doc/zh_TW/API/types/classes/Subroutine.md | 4 +- doc/zh_TW/API/types/classes/Tensor.md | 4 +- doc/zh_TW/API/types/classes/TransCell(T).md | 4 +- doc/zh_TW/API/types/classes/Tuple.md | 8 +- doc/zh_TW/API/types/classes/Vector.md | 2 +- doc/zh_TW/API/types/patches/BinOp.md | 4 +- doc/zh_TW/API/types/patches/UnaryOp.md | 4 +- doc/zh_TW/API/types/traits/Add(R,O).md | 8 +- doc/zh_TW/API/types/traits/Div(R,O).md | 2 +- doc/zh_TW/API/types/traits/Into.md | 6 +- doc/zh_TW/API/types/traits/Num.md | 4 +- doc/zh_TW/API/types/traits/Sample.md | 10 +- doc/zh_TW/API/types/traits/Unpack.md | 2 +- doc/zh_TW/compiler/TODO_hint.md | 6 +- doc/zh_TW/compiler/TODO_recov_suggest.md | 8 +- doc/zh_TW/compiler/TODO_warn.md | 6 +- doc/zh_TW/compiler/abandoned.md | 12 +- doc/zh_TW/compiler/architecture.md | 56 +- doc/zh_TW/compiler/errors.md | 52 +- doc/zh_TW/compiler/hir.md | 18 +- doc/zh_TW/compiler/inference.md | 228 ++++---- doc/zh_TW/compiler/overview.md | 30 +- doc/zh_TW/compiler/parsing.md | 22 +- doc/zh_TW/compiler/refinement_subtyping.md | 52 +- doc/zh_TW/compiler/trait_method_resolving.md | 66 +-- doc/zh_TW/compiler/transpile.md | 36 +- doc/zh_TW/compiler/type_var_normalization.md | 26 +- doc/zh_TW/dev_guide/branches.md | 30 +- doc/zh_TW/dev_guide/build_features.md | 20 +- doc/zh_TW/dev_guide/directories.md | 26 +- doc/zh_TW/dev_guide/doc_guideline.md | 14 +- doc/zh_TW/dev_guide/env.md | 18 +- doc/zh_TW/dev_guide/faq_syntax.md | 68 +-- doc/zh_TW/dev_guide/i18n_messages.md | 36 +- doc/zh_TW/dev_guide/rust_code_guideline.md | 30 +- doc/zh_TW/dev_guide/terms.md | 532 +++++++++--------- doc/zh_TW/dev_guide/unify_terms.md | 60 +- doc/zh_TW/faq_general.md | 48 +- doc/zh_TW/faq_technical.md | 42 +- doc/zh_TW/improved_points.md | 38 +- doc/zh_TW/index.md | 12 +- doc/zh_TW/migration_from_py.md | 8 +- doc/zh_TW/python/bytecode_instructions.md | 78 +-- doc/zh_TW/python/bytecode_specification.md | 80 +-- doc/zh_TW/python/class_system.md | 38 +- doc/zh_TW/syntax/00_basic.md | 66 +-- doc/zh_TW/syntax/01_literal.md | 52 +- doc/zh_TW/syntax/02_name.md | 92 +-- doc/zh_TW/syntax/03_declaration.md | 26 +- doc/zh_TW/syntax/04_function.md | 126 ++--- doc/zh_TW/syntax/05_builtin_funcs.md | 14 +- doc/zh_TW/syntax/06_operator.md | 20 +- doc/zh_TW/syntax/07_side_effect.md | 72 +-- doc/zh_TW/syntax/08_procedure.md | 6 +- doc/zh_TW/syntax/09_builtin_procs.md | 10 +- doc/zh_TW/syntax/10_array.md | 26 +- doc/zh_TW/syntax/11_tuple.md | 54 +- doc/zh_TW/syntax/12_dict.md | 30 +- doc/zh_TW/syntax/13_record.md | 94 ++-- doc/zh_TW/syntax/14_set.md | 18 +- doc/zh_TW/syntax/15_type.md | 6 +- doc/zh_TW/syntax/16_iterator.md | 30 +- doc/zh_TW/syntax/17_mutability.md | 64 +-- doc/zh_TW/syntax/18_ownership.md | 80 +-- doc/zh_TW/syntax/19_visibility.md | 66 +-- doc/zh_TW/syntax/20_naming_rule.md | 30 +- doc/zh_TW/syntax/21_lambda.md | 52 +- doc/zh_TW/syntax/22_subroutine.md | 32 +- doc/zh_TW/syntax/23_closure.md | 40 +- doc/zh_TW/syntax/24_module.md | 8 +- doc/zh_TW/syntax/25_object_system.md | 68 +-- doc/zh_TW/syntax/26_pattern_matching.md | 62 +- doc/zh_TW/syntax/27_comprehension.md | 30 +- doc/zh_TW/syntax/28_spread_syntax.md | 12 +- doc/zh_TW/syntax/29_decorator.md | 52 +- doc/zh_TW/syntax/30_error_handling.md | 54 +- doc/zh_TW/syntax/31_pipeline.md | 14 +- .../syntax/32_integration_with_Python.md | 32 +- doc/zh_TW/syntax/33_package_system.md | 32 +- doc/zh_TW/syntax/34_generator.md | 10 +- doc/zh_TW/syntax/SUMMARY.md | 106 ++-- doc/zh_TW/syntax/container_ownership.md | 18 +- doc/zh_TW/syntax/grammar.md | 2 +- doc/zh_TW/syntax/indexes.md | 14 +- doc/zh_TW/syntax/quick_tour.md | 114 ++-- doc/zh_TW/syntax/type/01_type_system.md | 132 ++--- doc/zh_TW/syntax/type/02_basic.md | 84 +-- doc/zh_TW/syntax/type/03_trait.md | 66 +-- doc/zh_TW/syntax/type/04_class.md | 148 ++--- doc/zh_TW/syntax/type/05_inheritance.md | 146 ++--- doc/zh_TW/syntax/type/06_nst_vs_sst.md | 14 +- doc/zh_TW/syntax/type/07_patch.md | 90 +-- doc/zh_TW/syntax/type/08_value.md | 14 +- doc/zh_TW/syntax/type/09_attributive.md | 12 +- doc/zh_TW/syntax/type/10_interval.md | 20 +- doc/zh_TW/syntax/type/11_enum.md | 30 +- doc/zh_TW/syntax/type/12_refinement.md | 42 +- doc/zh_TW/syntax/type/13_algebraic.md | 54 +- doc/zh_TW/syntax/type/14_dependent.md | 34 +- doc/zh_TW/syntax/type/15_quantified.md | 144 ++--- doc/zh_TW/syntax/type/16_subtyping.md | 32 +- doc/zh_TW/syntax/type/17_type_casting.md | 30 +- doc/zh_TW/syntax/type/18_mut.md | 142 ++--- doc/zh_TW/syntax/type/19_bound.md | 14 +- doc/zh_TW/syntax/type/advanced.md | 2 +- doc/zh_TW/syntax/type/advanced/GADTs.md | 22 +- doc/zh_TW/syntax/type/advanced/_rank2type.md | 70 +-- .../syntax/type/advanced/default_param.md | 12 +- doc/zh_TW/syntax/type/advanced/erasure.md | 28 +- doc/zh_TW/syntax/type/advanced/existential.md | 24 +- .../syntax/type/advanced/keyword_param.md | 14 +- doc/zh_TW/syntax/type/advanced/kind.md | 84 +-- .../syntax/type/advanced/marker_trait.md | 12 +- doc/zh_TW/syntax/type/advanced/mut_struct.md | 24 +- doc/zh_TW/syntax/type/advanced/newtype.md | 20 +- doc/zh_TW/syntax/type/advanced/overloading.md | 40 +- doc/zh_TW/syntax/type/advanced/phantom.md | 30 +- doc/zh_TW/syntax/type/advanced/projection.md | 8 +- .../type/advanced/quantified_dependent.md | 12 +- doc/zh_TW/syntax/type/advanced/shared.md | 38 +- doc/zh_TW/syntax/type/advanced/special.md | 10 +- doc/zh_TW/syntax/type/advanced/typeof.md | 30 +- doc/zh_TW/syntax/type/advanced/variance.md | 106 ++-- doc/zh_TW/syntax/type/advanced/widening.md | 58 +- doc/zh_TW/tips.md | 46 +- doc/zh_TW/tools/build.md | 20 +- doc/zh_TW/tools/env.md | 12 +- doc/zh_TW/tools/fmt.md | 6 +- doc/zh_TW/tools/install.md | 12 +- doc/zh_TW/tools/pack.md | 112 ++-- doc/zh_TW/tools/repl.md | 6 +- doc/zh_TW/tools/test.md | 24 +- 169 files changed, 3164 insertions(+), 3164 deletions(-) diff --git a/doc/zh_TW/API/consts.md b/doc/zh_TW/API/consts.md index b42e2f5b..735fca38 100644 --- a/doc/zh_TW/API/consts.md +++ b/doc/zh_TW/API/consts.md @@ -1,4 +1,4 @@ -# 内置常量 +# 內置常量 ## True diff --git a/doc/zh_TW/API/funcs.md b/doc/zh_TW/API/funcs.md index 0a97634e..691715f6 100644 --- a/doc/zh_TW/API/funcs.md +++ b/doc/zh_TW/API/funcs.md @@ -6,31 +6,31 @@ ### map|T; U|(i: Iterable T, f: T -> U) -> Map U -请注意,参数的顺序与 Python 相反 +請注意,參數的順序與 Python 相反 ### log(x: Object, type: LogType = Info) -> None -在调试显示中记录“x”。 执行完成后汇总并显示日志 -支持表情符号的终端根据“类型”添加前缀 +在調試顯示中記錄“x”。 執行完成后匯總并顯示日志 +支持表情符號的終端根據“類型”添加前綴 -* type == Info: 💬 -* type == Ok: ✅ -* type == Warn: ⚠️ -* type == Hint: 💡 +* type == Info: ?? +* type == Ok: ? +* type == Warn: ?? +* type == Hint: ?? ### panic(msg: Str) -> Panic -显示msg并停止。 -支持表情符号的终端有一个🚨前缀。 +顯示msg并停止。 +支持表情符號的終端有一個??前綴。 ### discard|T|(x: ...T) -> NoneType -扔掉`x`。不使用返回值时使用。与 `del` 不同,它不会使变量 `x` 不可访问 +扔掉`x`。不使用返回值時使用。與 `del` 不同,它不會使變量 `x` 不可訪問 ```python p! x = - # q!应该返回一些不是None或()的值 - # 如果不需要,请使用`discard` + # q!應該返回一些不是None或()的值 + # 如果不需要,請使用`discard` discard q!(x) f x @@ -40,19 +40,19 @@ assert True # OK ### import(path: Path) -> Module or CompilerPanic -导入一个模块。如果找不到模块,则引发编译错误 +導入一個模塊。如果找不到模塊,則引發編譯錯誤 ### eval(code: Str) -> Object -将`code`作为代码进行评估并返回。 +將`code`作為代碼進行評估并返回。 ### classof(object: Object) -> Class -返回`object`的类。 -但是,由于无法比较类,如果要判断实例,请使用`object in Class`而不是`classof(object) == Class` -编译时确定的结构类型是通过`Typeof`获得的 +返回`object`的類。 +但是,由于無法比較類,如果要判斷實例,請使用`object in Class`而不是`classof(object) == Class` +編譯時確定的結構類型是通過`Typeof`獲得的 -## Iterator, Array生成系统 +## Iterator, Array生成系統 ### repeat|T|(x: T) -> RepeatIterator T @@ -78,12 +78,12 @@ cycle([0, 1]).take 4 # [0, 1, 0, 1] cycle("hello").take 3 # "hellohellohello" ``` -## 定数式関数 +## 定數式関數 ### Class -创建一个新类。 与`Inherit`不同,通过`Class`传递与基类型无关,并且方法会丢失 -您将无法进行比较,但您可以进行模式匹配等操作 +創建一個新類。 與`Inherit`不同,通過`Class`傳遞與基類型無關,并且方法會丟失 +您將無法進行比較,但您可以進行模式匹配等操作 ```python C = Class {i = Int} @@ -96,20 +96,20 @@ match jan: _ -> log "Other" ``` -第二个参数 Impl 是要实现的特征 +第二個參數 Impl 是要實現的特征 ### Inherit -继承一个类。您可以按原样使用基类方法 +繼承一個類。您可以按原樣使用基類方法 ### Trait -创造一个新的特质。目前,只能指定记录类型 +創造一個新的特質。目前,只能指定記錄類型 ### Typeof -返回参数类型。如果要获取运行时类,请使用`classof`。 -如果您将其用于类型规范,则会出现警告。 +返回參數類型。如果要獲取運行時類,請使用`classof`。 +如果您將其用于類型規范,則會出現警告。 ```python x: Typeof i = ... @@ -118,4 +118,4 @@ x: Typeof i = ... ### Deprecated -作为解码器使用。警告不推荐使用的类型或函数 \ No newline at end of file +作為解碼器使用。警告不推薦使用的類型或函數 \ No newline at end of file diff --git a/doc/zh_TW/API/modules/external/alstruct.md b/doc/zh_TW/API/modules/external/alstruct.md index bfbf7a1b..94e932f2 100644 --- a/doc/zh_TW/API/modules/external/alstruct.md +++ b/doc/zh_TW/API/modules/external/alstruct.md @@ -1,10 +1,10 @@ -# 结构 +# 結構 -模块为它们提供代表代数结构和补丁的特征 +模塊為它們提供代表代數結構和補丁的特征 -* 成员 +* 成員 -## 二进制运算 +## 二進制運算 ```python BinOp Op: Kind 2 = Subsume Op(Self, Self.ReturnTypeOf Op), Additional: { @@ -18,7 +18,7 @@ assert Nat. ReturnTypeof(Mul) == Nat assert Nat.ReturnTypeof(Div) == Positive Ratio ``` -## 半群(一个二元运算的代数系统) +## 半群(一個二元運算的代數系統) ```python SemiGroup Op: Kind 2 = Op(Self, Self) @@ -38,7 +38,7 @@ Functor = Trait { } ``` -## 应用 +## 應用 ```python # * Identity law: x.app(X.pure(id)) == x @@ -48,7 +48,7 @@ Applicative = Subsume Functor, Additional: { } ``` -## 单子(交互式命令行工具以及面向对象的脚本技术) +## 單子(交互式命令行工具以及面向對象的腳本技術) ```python Monad = Subsume Applicative, Additional: { diff --git a/doc/zh_TW/API/modules/repl.md b/doc/zh_TW/API/modules/repl.md index 0395afcb..8a1018b3 100644 --- a/doc/zh_TW/API/modules/repl.md +++ b/doc/zh_TW/API/modules/repl.md @@ -1,22 +1,22 @@ -# 模块`repl` +# 模塊`repl` -提供REPL(Read-Eval-Print-Loop)相关的API。 +提供REPL(Read-Eval-Print-Loop)相關的API。 ## 功能 * `gui_help` -在浏览器中查看有关对象的信息。 可以离线使用。 +在瀏覽器中查看有關對象的信息。 可以離線使用。 -## 类型 +## 類型 -### 猜测 = 对象 +### 猜測 = 對象 #### 方法 * `.guess` -在给定参数和返回值的情况下推断函数。 +在給定參數和返回值的情況下推斷函數。 ```python 1.guess((1,), 2) # diff --git a/doc/zh_TW/API/modules/status.md b/doc/zh_TW/API/modules/status.md index 1e65ebd8..ca082199 100644 --- a/doc/zh_TW/API/modules/status.md +++ b/doc/zh_TW/API/modules/status.md @@ -1,6 +1,6 @@ - # 模块`status` + # 模塊`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 index 179b55f0..a4bccd20 100644 --- a/doc/zh_TW/API/modules/unit.md +++ b/doc/zh_TW/API/modules/unit.md @@ -1,58 +1,58 @@ -# 模块`unit` +# 模塊`unit` -`unit` 模块是将数值计算中经常使用的单位定义为类型的模块。 -Erg 数值类型包括 `Nat`、`Int`、`Ratio` 等。但是,这些类型没有关于“数字的含义”的信息,因此可以执行诸如添加米和码之类的无意义计算。 -通过使用 `unit` 模块,您可以避免错误,例如将不同单位的数字传递给函数。 -这样的错误确实会发生,并且会导致诸如[由于错误的单位系统导致火星探测器丢失](http://www.sydrose.com/case100/287/)之类的严重错误。 -如果您希望代码在进行数值计算时更加健壮,您应该使用此模块。 +`unit` 模塊是將數值計算中經常使用的單位定義為類型的模塊。 +Erg 數值類型包括 `Nat`、`Int`、`Ratio` 等。但是,這些類型沒有關于“數字的含義”的信息,因此可以執行諸如添加米和碼之類的無意義計算。 +通過使用 `unit` 模塊,您可以避免錯誤,例如將不同單位的數字傳遞給函數。 +這樣的錯誤確實會發生,并且會導致諸如[由于錯誤的單位系統導致火星探測器丟失](http://www.sydrose.com/case100/287/)之類的嚴重錯誤。 +如果您希望代碼在進行數值計算時更加健壯,您應該使用此模塊。 ```python {*} = import "unit" -x = 6m # 相当于 `x = Meter.new(6)` -t = 3s # 相当于 `t = Sec.new(3)` -#m/s是速度单位对象,类型为velocity +x = 6m # 相當于 `x = Meter.new(6)` +t = 3s # 相當于 `t = Sec.new(3)` +#m/s是速度單位對象,類型為velocity print! x/t # 2m/s print! x + 4m # 10m -print! x + 2s # 类型错误: `+`(Meter, Sec) 未实现 +print! x + 2s # 類型錯誤: `+`(Meter, Sec) 未實現 ``` -对象`m`、`s`和`m/s`被称为单元对象。它本身具有1m、1s、1m/s的含义。 `m/s`可以说是结合m和s创建的单位对象。 +對象`m`、`s`和`m/s`被稱為單元對象。它本身具有1m、1s、1m/s的含義。 `m/s`可以說是結合m和s創建的單位對象。 -在单元中,以下单元被定义为类型。它被称为SI(国际单位制)。 +在單元中,以下單元被定義為類型。它被稱為SI(國際單位制)。 -* 长度:Meter(单位常数:m) -* 质量:KiloGram(单位常数:kg,g = 0.001kg) -* 时间:Sec(分、时、日、年等有分、时、日、年等常量由秒生成) -* 电流:Amper(单位常数:a) -* 温度:Kelvin(单位常数:k。华氏、摄氏度类型也可用,可相互转换) -* 物质量:Mol(单位常数:mol) -* 发光强度:Candela(单位常数:cd) +* 長度:Meter(單位常數:m) +* 質量:KiloGram(單位常數:kg,g = 0.001kg) +* 時間:Sec(分、時、日、年等有分、時、日、年等常量由秒生成) +* 電流:Amper(單位常數:a) +* 溫度:Kelvin(單位常數:k。華氏、攝氏度類型也可用,可相互轉換) +* 物質量:Mol(單位常數:mol) +* 發光強度:Candela(單位常數:cd) -此外,还定义了`Unit1`、`UnitMul`和`UnitDiv`类型,可以通过组合基本类型来创建新的单元。 -例如`UnitDiv(Unit1, Sec)`,因为频率单位赫兹(hertz)被定义为振动周期(秒)的倒数。 -如果要将此类型视为有意义的类型(例如添加专用方法),则应创建 [patch](./../../syntax/type/07_patch.md)。 +此外,還定義了`Unit1`、`UnitMul`和`UnitDiv`類型,可以通過組合基本類型來創建新的單元。 +例如`UnitDiv(Unit1, Sec)`,因為頻率單位赫茲(hertz)被定義為振動周期(秒)的倒數。 +如果要將此類型視為有意義的類型(例如添加專用方法),則應創建 [patch](./../../syntax/type/07_patch.md)。 ```python Hertz = Patch UnitDiv(Unit1, Sec) SquareMeter = Patch UnitMul(Meter, Meter) ``` -一些辅助单元也是预定义的: +一些輔助單元也是預定義的: -* 频率: Hertz(hz) +* 頻率: Hertz(hz) * 力: Newton(newton) * 能量: Joule(j) * 功率: Watt(w) -* 电压: Volt(v) -* 电阻: Ohm(ohm) +* 電壓: Volt(v) +* 電阻: Ohm(ohm) * 速度: Velocity(m/s) -* 面积: SquareMeter(m^2) -* 体积: CubicMeter(m^3) (liter = 10e-3 m^3) +* 面積: SquareMeter(m^2) +* 體積: CubicMeter(m^3) (liter = 10e-3 m^3) * 角度: Degree(deg) (rad = 180/pi deg) -* 长度: Feet, Yard, Inch, Mile, Ly, Au, Angstrom +* 長度: Feet, Yard, Inch, Mile, Ly, Au, Angstrom * 重量: Pound -它还定义了一个前缀: +它還定義了一個前綴: * Femto = 1e-15 * Pico = 1e-12 @@ -69,4 +69,4 @@ SquareMeter = Patch UnitMul(Meter, Meter) * Peta = 1e+15 * Exa = 1e+18 -* 与名字的由来相反,Erg基本采用MKS单位制。如果需要 CGS 单位制的单位模块,请使用外部库[cgs](https://github.com/mtshiba/cgs)等)。 \ No newline at end of file +* 與名字的由來相反,Erg基本采用MKS單位制。如果需要 CGS 單位制的單位模塊,請使用外部庫[cgs](https://github.com/mtshiba/cgs)等)。 \ No newline at end of file diff --git a/doc/zh_TW/API/modules/unsound.md b/doc/zh_TW/API/modules/unsound.md index adfe6ccf..a5febad2 100644 --- a/doc/zh_TW/API/modules/unsound.md +++ b/doc/zh_TW/API/modules/unsound.md @@ -1,24 +1,24 @@ -# 模块 `unsound` +# 模塊 `unsound` -让 API 执行在 Erg 的类型系统中无法保证的不健全和不安全的操作。 +讓 API 執行在 Erg 的類型系統中無法保證的不健全和不安全的操作。 ## `unsafe!` -执行“不安全”过程。 就像 Rust 一样,`Unsafe` API 不能直接调用,而是作为高阶函数传递给这个过程。 +執行“不安全”過程。 就像 Rust 一樣,`Unsafe` API 不能直接調用,而是作為高階函數傳遞給這個過程。 ```python unsound = import "unsound" i = unsound. unsafe! do!: - # 将 `Result Int` 转换为 `Int` + # 將 `Result Int` 轉換為 `Int` unsound.transmute input!().try_into(Int), Int ``` ## transmit -将第一个参数的对象转换为第二个参数的类型。没有进行类型检查。 -这个函数破坏了类型系统的类型安全。请在使用前进行验证。 +將第一個參數的對象轉換為第二個參數的類型。沒有進行類型檢查。 +這個函數破壞了類型系統的類型安全。請在使用前進行驗證。 -## 隐式转换 +## 隱式轉換 -与 `transmute` 不同,它会自动转换为预期的类型。与 Ocaml 的 `Obj.magic` 工作方式相同。 \ No newline at end of file +與 `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 index 82c43c93..ce91831c 100644 --- a/doc/zh_TW/API/operators.md +++ b/doc/zh_TW/API/operators.md @@ -1,38 +1,38 @@ -# 操作员 +# 操作員 -## 中缀运算符 +## 中綴運算符 ### `_+_`|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 操作。 +執行 and 操作。 ### `or`(x: Bool, y: Bool) -> Bool -执行 and 操作。 +執行 and 操作。 -## 前缀运算符 +## 前綴運算符 ### `+_`|T <: Num|(x: T) -> T -默认与 id 相同。 +默認與 id 相同。 ### `-_`|T <: Num|(x: T) -> T.Neg @@ -40,25 +40,25 @@ ### `!`|T <: Immut|(x: T) -> `T!` -从不可变对象创建可变对象。 -该运算符本身不是程序性的,可以在函数内部使用。 +從不可變對象創建可變對象。 +該運算符本身不是程序性的,可以在函數內部使用。 ### `..`|T <: Ord|(x: T) -> Range T -在 x 的末尾创建一个没有下限的 Range 对象。 -x..x 仅返回 x 作为迭代器。 +在 x 的末尾創建一個沒有下限的 Range 對象。 +x..x 僅返回 x 作為迭代器。 ### `..<`|T <: Ord|(x: T) -> Range T -x.. Range T -创建一个从 x 开始没有上限的 Range 对象。 +創建一個從 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 index e527f5fb..38e3e3a0 100644 --- a/doc/zh_TW/API/procs.md +++ b/doc/zh_TW/API/procs.md @@ -1,34 +1,34 @@ -# 过程 +# 過程 ## print! ```python -打印!(x)->无类型 +打印!(x)->無類型 ``` - 使用换行符返回 x。 + 使用換行符返回 x。 -## 调试&排除; +## 調試&排除; ```python -调试!(x,类型=信息)-> NoneType +調試!(x,類型=信息)-> NoneType ``` -用换行符调试 x(文件名、行号、变量名一起显示)。 在发布模式中删除。 -支持表情符号的终端根据类型加前缀。 +用換行符調試 x(文件名、行號、變量名一起顯示)。 在發布模式中刪除。 +支持表情符號的終端根據類型加前綴。 -* type == Info: 💬 -* type == Ok: ✅ -* type == Warn: ⚠️ -* type == Hint: 💡 +* type == Info: ?? +* type == Ok: ? +* type == Warn: ?? +* type == Hint: ?? ## for!i: Iterable T, block: T => NoneType -以块的动作遍历迭代器。 +以塊的動作遍歷迭代器。 ## while!cond: Bool!, block: () => NoneType -当cond为True时的执行块。 +當cond為True時的執行塊。 ## Lineno!() -> Nat diff --git a/doc/zh_TW/API/special.md b/doc/zh_TW/API/special.md index 6de5fc48..ff4c4157 100644 --- a/doc/zh_TW/API/special.md +++ b/doc/zh_TW/API/special.md @@ -1,20 +1,20 @@ # 特殊形式 -特殊形式是不能在 Erg 类型系统中表达的运算符、子程序(等等)。它被`包围,但实际上无法捕获。 -此外,为方便起见,还出现了“Pattern”、“Body”和“Conv”等类型,但不存在此类类型。它的含义也取决于上下文。 +特殊形式是不能在 Erg 類型系統中表達的運算符、子程序(等等)。它被`包圍,但實際上無法捕獲。 +此外,為方便起見,還出現了“Pattern”、“Body”和“Conv”等類型,但不存在此類類型。它的含義也取決于上下文。 ## `=`(pat: Pattern, body: Body) -> NoneType -将 body 分配给 pat 作为变量。如果变量已存在于同一范围内或与 pat 不匹配,则引发错误。 -它还用于记录属性定义和默认参数。 +將 body 分配給 pat 作為變量。如果變量已存在于同一范圍內或與 pat 不匹配,則引發錯誤。 +它還用于記錄屬性定義和默認參數。 ```python record = {i = 1; j = 2} f(x: Int, y = 2) = ... ``` -当主体是类型或函数时,`=` 具有特殊行为。 -左侧的变量名嵌入到右侧的对象中。 +當主體是類型或函數時,`=` 具有特殊行為。 +左側的變量名嵌入到右側的對象中。 ```python print! Class() # > @@ -31,35 +31,35 @@ L = X: Int -> Class(...) print! L # ``` -`=` 运算符的返回值为“未定义”。 -函数中的多个赋值和 `=` 会导致语法错误。 +`=` 運算符的返回值為“未定義”。 +函數中的多個賦值和 `=` 會導致語法錯誤。 ```python -i = j = 1 # SyntaxError: 不允许多次赋值 +i = j = 1 # SyntaxError: 不允許多次賦值 print!(x=1) # SyntaxError: cannot use `=` in function arguments -# 提示:您的意思是关键字参数(`x: 1`)吗? +# 提示:您的意思是關鍵字參數(`x: 1`)嗎? if True, do: - i = 0 # SyntaxError: 块不能被赋值表达式终止 + i = 0 # SyntaxError: 塊不能被賦值表達式終止 ``` ## `->`(pat: Pattern, body: Body) -> Func -生成匿名函数,函数类型。 +生成匿名函數,函數類型。 ## `=>`(pat: Pattern, body: Body) -> Proc -生成匿名过程,过程类型。 +生成匿名過程,過程類型。 ## `:`(subject, T) -确定主题是否与 T 匹配。如果它们不匹配,则抛出编译错误。 +確定主題是否與 T 匹配。如果它們不匹配,則拋出編譯錯誤。 ```python a: Int f x: Int, y: Int = x / y ``` -也用于 `:` 应用样式。 +也用于 `:` 應用樣式。 ```python f x: @@ -67,29 +67,29 @@ f x: z ``` -像`:`和`=`一样,运算的结果是不确定的。 +像`:`和`=`一樣,運算的結果是不確定的。 ```python -_ = x: Int # 语法错误: -print!(x: Int) # 语法错误: +_ = x: Int # 語法錯誤: +print!(x: Int) # 語法錯誤: ``` ## `.`(obj, attr) -读取obj的属性。 -`x.[y, z]` 将 x 的 y 和 z 属性作为数组返回。 +讀取obj的屬性。 +`x.[y, z]` 將 x 的 y 和 z 屬性作為數組返回。 ## `|>`(obj, c: Callable) -执行`c(obj)`。 `x + y |>.foo()` 与 `(x + y).foo()` 相同。 +執行`c(obj)`。 `x + y |>.foo()` 與 `(x + y).foo()` 相同。 ### (x: Option T)`?` -> T | T -后缀运算符。如果出现错误,请立即调用 `x.unwrap()` 和 `return`。 +后綴運算符。如果出現錯誤,請立即調用 `x.unwrap()` 和 `return`。 ## match(obj, ...lambdas: Lambda) -对于 obj,执行与模式匹配的 lambda。 +對于 obj,執行與模式匹配的 lambda。 ```python match [1, 2, 3]: @@ -101,7 +101,7 @@ match [1, 2, 3]: ## del(x: ...T) -> NoneType | T -删除变量“x”。但是,无法删除内置对象。 +刪除變量“x”。但是,無法刪除內置對象。 ```python a = 1 @@ -112,16 +112,16 @@ 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 时才会计算表达式。 +創建一個由兩對組成的類元組結構,稱為 Choice 對象。 +`l, r` 被懶惰地評估。也就是說,只有在調用 .get_then 或 .get_else 時才會計算表達式。 ```python choice = 1 else 2 @@ -130,27 +130,27 @@ assert choice.get_else() == 2 assert True.then(choice) == 1 ``` -## 集合运算符 +## 集合運算符 ### `[]`(...objs) -从参数创建一个数组或从可选参数创建一个字典。 +從參數創建一個數組或從可選參數創建一個字典。 ### `{}`(...objs) -从参数创建一个集合。 +從參數創建一個集合。 ### `{}`(...fields: ((Field, Value); N)) -生成记录。 +生成記錄。 ### `{}`(layout, ...names, ...preds) -生成筛型,等级2型。 +生成篩型,等級2型。 ### `...` -展开嵌套集合。它也可以用于模式匹配。 +展開嵌套集合。它也可以用于模式匹配。 ```python [x, ...y] = [1, 2, 3] @@ -162,14 +162,14 @@ 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 +返回對可變對象的可變引用。 \ No newline at end of file diff --git a/doc/zh_TW/API/types.md b/doc/zh_TW/API/types.md index 68f525a0..c8750872 100644 --- a/doc/zh_TW/API/types.md +++ b/doc/zh_TW/API/types.md @@ -1,88 +1,88 @@ -# 内置 Erg 类型列表 +# 內置 Erg 類型列表 -类型本身的属性不存储在 `.__dict__` 中,不能从实例中引用 +類型本身的屬性不存儲在 `.__dict__` 中,不能從實例中引用 -## 基本类型 +## 基本類型 -### 对象 +### 對象 -* `__dir__`:将对象的属性作为数组返回(dir函数) -* `__getattribute__`: 获取并返回一个属性 -* `__hash__`:返回对象的哈希值 -* `__repr__`:对象的字符串表示(不存在丰富/默认实现) -* `__sizeof__`:返回对象的大小(包括在堆中分配的大小) +* `__dir__`:將對象的屬性作為數組返回(dir函數) +* `__getattribute__`: 獲取并返回一個屬性 +* `__hash__`:返回對象的哈希值 +* `__repr__`:對象的字符串表示(不存在豐富/默認實現) +* `__sizeof__`:返回對象的大小(包括在堆中分配的大小) -### 显示 +### 顯示 -* `__str__`:返回对象的字符串表示(丰富) +* `__str__`:返回對象的字符串表示(豐富) ### Fmt -* `__format__`: 返回一个格式化的字符串 +* `__format__`: 返回一個格式化的字符串 -### 文档 +### 文檔 -* `__doc__`:对象描述 +* `__doc__`:對象描述 ### 命名 -* `__name__`: 对象的名称 +* `__name__`: 對象的名稱 ### 泡菜 -* `__reduce__`: 用 Pickle 序列化对象 -* `__reduce_ex__`: __reduce__ 允许你指定协议版本 +* `__reduce__`: 用 Pickle 序列化對象 +* `__reduce_ex__`: __reduce__ 允許你指定協議版本 -## 对象系统 +## 對象系統 -Trait 类相当于 Python 中的 ABC(抽象基类,接口) -实例属于1、True、“aaa”等。 -类是 Int、Bool、Str 等。 +Trait 類相當于 Python 中的 ABC(抽象基類,接口) +實例屬于1、True、“aaa”等。 +類是 Int、Bool、Str 等。 -### 类型 +### 類型 -* `__父类__`:超类型(`__mro__` 是一个数组,但这个是一个 Set) +* `__父類__`:超類型(`__mro__` 是一個數組,但這個是一個 Set) * `__basicsize__`: * `__dictoffset__`:Evm 不支持 * `__flags__`: -* `__itemsize__`:实例的大小(如果不是类,则为 0) +* `__itemsize__`:實例的大小(如果不是類,則為 0) * `__weakrefoffset__`:Evm 不支持 -* `__membercheck__`: 相当于`ismember(x, T)` -* `__subtypecheck__`:等价于`issubtype(U, T)`,别名`__subclasshook__`(兼容CPython) +* `__membercheck__`: 相當于`ismember(x, T)` +* `__subtypecheck__`:等價于`issubtype(U, T)`,別名`__subclasshook__`(兼容CPython) -### 实例 +### 實例 -* `__class__`:返回创建实例的类(自动附加到使用 `.new` 创建的对象) +* `__class__`:返回創建實例的類(自動附加到使用 `.new` 創建的對象) ### Class -* `__mro__`:用于方法解析的类型数组(包括自身,始终以 Object 结尾) -* `__base__`:基本类型(`__mro__[1]` 如果有多个) -* `__new__`: 实例化 -* `__init__`: 初始化实例 -* `__init_subclass__`: 初始化实例 -* `__intstancecheck__`:使用类似于 `MyClass.__instancecheck__(x)`,等价于 `isinstance(x, MyClass)` -* `__subclasscheck__`:等价于 `issubclass(C, MyClass)` +* `__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__`: 对象比较函数 (!=),默认实现 +* `__eq__(self, rhs: Self) -> Bool`: 對象比較函數 (==) +* `__ne__`: 對象比較函數 (!=),默認實現 ### 秩序 -* `__lt__(self, rhs: Self) -> Bool`: 对象比较函数 (<) -* `__le__`:对象比较函数(<=),默认实现 -* `__gt__`:对象比较函数(>),默认实现 -* `__ge__`:对象比较函数(>=),默认实现 +* `__lt__(self, rhs: Self) -> Bool`: 對象比較函數 (<) +* `__le__`:對象比較函數(<=),默認實現 +* `__gt__`:對象比較函數(>),默認實現 +* `__ge__`:對象比較函數(>=),默認實現 ### BinAdd -* 实现 `__add__(self, rhs: Self) -> Self`: `+` +* 實現 `__add__(self, rhs: Self) -> Self`: `+` ### 添加R @@ -98,27 +98,27 @@ Trait 类相当于 Python 中的 ABC(抽象基类,接口) ### BinMul <: Mul Self -* `__pow__`:实现 `**`(默认实现) +* `__pow__`:實現 `**`(默認實現) ### Div R, O -* 实现 `__div__(self, rhs: Self) -> Self`: `/`,可能会因为 0 而恐慌 +* 實現 `__div__(self, rhs: Self) -> Self`: `/`,可能會因為 0 而恐慌 ### BinDiv <: Div Self -* `__mod__`: 实现 `%` (默认实现) +* `__mod__`: 實現 `%` (默認實現) -## 数值型 +## 數值型 ### Num (= Add and Sub and Mul and Eq) -例如,除了Complex,Vector、Matrix和Tensor都是Num(Matrix和Tensor中的*分别与dot和product相同) +例如,除了Complex,Vector、Matrix和Tensor都是Num(Matrix和Tensor中的*分別與dot和product相同) ### Complex (= Inherit(Object, Impl := Num)) -* `imag: Ratio`:返回虚部 -* `real: Ratio`:返回实部 -* `conjugate self -> Complex`:返回复共轭 +* `imag: Ratio`:返回虛部 +* `real: Ratio`:返回實部 +* `conjugate self -> Complex`:返回復共軛 ### Float (= Inherit(FloatComplex, Impl := Num)) @@ -131,11 +131,11 @@ Trait 类相当于 Python 中的 ABC(抽象基类,接口) ### Nat (= Inherit Int) -* `times!`: 运行 proc self 时间 +* `times!`: 運行 proc self 時間 -## 其他基本类型 +## 其他基本類型 -### 布尔值 +### 布爾值 * `__and__`: * `__or__`: @@ -144,7 +144,7 @@ Trait 类相当于 Python 中的 ABC(抽象基类,接口) ## 字符串 (<: 序列) * `capitalize` -* `chomp`: 删除换行符 +* `chomp`: 刪除換行符 * `isalnum`: * `isascii`: * `isalpha`: @@ -166,22 +166,22 @@ Trait 类相当于 Python 中的 ABC(抽象基类,接口) ### 位 -* `from_bytes`:从字节转换 -* `to_bytes`:转换为字节(指定长度和字节序(字节序)) -* `bit_length`:返回位长度 +* `from_bytes`:從字節轉換 +* `to_bytes`:轉換為字節(指定長度和字節序(字節序)) +* `bit_length`:返回位長度 ### 可迭代 T -请注意,它不是 `Iterator` 本身的类型。 `Nat` 是 `Iterable` 但你不能 `Nat.next()`,你需要 `Nat.iter().next()`。 +請注意,它不是 `Iterator` 本身的類型。 `Nat` 是 `Iterable` 但你不能 `Nat.next()`,你需要 `Nat.iter().next()`。 -* `iter`:创建一个迭代器。 +* `iter`:創建一個迭代器。 ### 迭代器 T Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter().fold (sum, n) -> sum + n*2`等是可能的。 -由于所有和任何在使用后都会被破坏,因此没有副作用。这些应该使用没有副作用的 `next` 来实现,但内部使用 `Iterator!.next!` 来提高执行效率。 +由于所有和任何在使用后都會被破壞,因此沒有副作用。這些應該使用沒有副作用的 `next` 來實現,但內部使用 `Iterator!.next!` 來提高執行效率。 -* `next`:返回第一个元素和剩余的迭代器。 +* `next`:返回第一個元素和剩余的迭代器。 * `all` * `any` * `filter` @@ -202,11 +202,11 @@ Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter(). ### Iterator!T = IteratorT 和 ... -* `next!`:获取第一个元素。 +* `next!`:獲取第一個元素。 ## SizedIterator T = 迭代器 T 和 ... -有限数量元素的迭代器。 +有限數量元素的迭代器。 * `len`: * `chain`: @@ -223,22 +223,22 @@ Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter(). ## Seq T = SizedIterable T 和 ... -* `concat`: 合并两个 Seq -* `__getitem__`:等同于使用 `[]` 访问(否则会出现恐慌) -* 与 `get`: __getitem__ 不同,它返回 Option -* `maketrans`:创建替换表(静态方法) -* `replace`: 替换 -* `translate`:根据替换表替换 +* `concat`: 合并兩個 Seq +* `__getitem__`:等同于使用 `[]` 訪問(否則會出現恐慌) +* 與 `get`: __getitem__ 不同,它返回 Option +* `maketrans`:創建替換表(靜態方法) +* `replace`: 替換 +* `translate`:根據替換表替換 * `insert`: 添加到 idx -* `remove`: 删除 idx +* `remove`: 刪除 idx * `prepend`: 前置 -* `dequeue`: 移除头部 +* `dequeue`: 移除頭部 * `push`:添加到末尾 * `pop`: 取尾巴 -* `dedup`:删除连续值 -* `uniq`:删除重复元素(通过 sort |> dedup 实现,因此顺序可能会改变) -* `swap`:交换元素 -* `reverse`:反转元素 +* `dedup`:刪除連續值 +* `uniq`:刪除重復元素(通過 sort |> dedup 實現,因此順序可能會改變) +* `swap`:交換元素 +* `reverse`:反轉元素 * `sort`: 排序元素 * `first`: * `last`: @@ -248,15 +248,15 @@ Nat 和 Range 有迭代器,所以 `Nat.iter().map n -> n**2`, `(3..10).iter(). * `__setitem__!`: * `__delitem__!`: * `插入!`:添加到 idx -* `remove!`: 删除 idx +* `remove!`: 刪除 idx * `prepend!`:前置 -* `dequeue!`: 删除开头 +* `dequeue!`: 刪除開頭 * `push!`:添加到末尾 * `pop!`:拿尾巴 -* `dedup!`:删除连续值 -* `uniq!`: 删除重复元素(通过排序实现!|> dedup!,因此顺序可能会改变) -* `swap!`:交换元素 -* `reverse!`:反转元素 +* `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 index 1d020183..3d683634 100644 --- a/doc/zh_TW/API/types/classes/Array!(T).md +++ b/doc/zh_TW/API/types/classes/Array!(T).md @@ -1,3 +1,3 @@ # Array! T -表示可变长度数组的类型。在编译时长度未知时使用。 有一个语法糖叫做` [t]!`。在`Array! T = ArrayWithMutLength! T, !_`中被定义 \ No newline at end of file +表示可變長度數組的類型。在編譯時長度未知時使用。 有一個語法糖叫做` [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 index c186d029..54011ea8 100644 --- a/doc/zh_TW/API/types/classes/Array(T).md +++ b/doc/zh_TW/API/types/classes/Array(T).md @@ -1,3 +1,3 @@ # Array T: Type -由`Array T = ArrayWithLen T, _`定义。 有一种语法糖叫做`[T]`。 \ No newline at end of file +由`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 index 074bbe5d..6e7eaa7c 100644 --- a/doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md +++ b/doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md @@ -1,6 +1,6 @@ # ArrayWithLen T: Type, N: Nat -`[T; N]`是语法糖。还有一个[`Array` 类型](./Array.md)省略了长度。 +`[T; N]`是語法糖。還有一個[`Array` 類型](./Array.md)省略了長度。 ## 方法 @@ -11,9 +11,9 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] ``` * all(self, pred: T -> Bool) -> Bool - 返回是否所有元素都满足 pred。 - 如果元素为 0,则无论 pred 为 `True`,但会发出警告。 - 该规范本身已被多种语言采用,是逻辑一致性所必需的。 + 返回是否所有元素都滿足 pred。 + 如果元素為 0,則無論 pred 為 `True`,但會發出警告。 + 該規范本身已被多種語言采用,是邏輯一致性所必需的。 ```python assert [].all(_ -> False) @@ -26,7 +26,7 @@ assert ["a", "b", "c", "d", "e"].values_at([0, 1, 3]) == ["a", "b", "d"] ## ArrayWithLen T, N | T <: Eq 的方法 * freq self -> [{T: Nat}] - 返回对象出现的次数。 + 返回對象出現的次數。 ```python assert ["a", "b", "c", "b", "c", "b"].freq() \ diff --git a/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md index 842084ca..b4704e32 100644 --- a/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md +++ b/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md @@ -1,6 +1,6 @@ # ArrayWithMutLength! T: Type, N: Nat! -一个可变长度数组,其长度在编译时已知。还有语法糖`ArrayWithMutLength(T, !N) == [T; !N]` +一個可變長度數組,其長度在編譯時已知。還有語法糖`ArrayWithMutLength(T, !N) == [T; !N]` ## 方法 @@ -10,14 +10,14 @@ * sample!(ref! self) -> T * sample! ref! self, M: Nat -> [T; M] - 随机选择里面的一个元素并返回一个副本 + 隨機選擇里面的一個元素并返回一個副本 * shuffle!(ref! self) - 把里面的东西随机摆放 + 把里面的東西隨機擺放 * assert_len ref! self(_ ~> N, ...), N: Nat -> () or Panic - 验证长度。 - `panic!` 如果长度无效。 + 驗證長度。 + `panic!` 如果長度無效。 ## Impl diff --git a/doc/zh_TW/API/types/classes/Complex.md b/doc/zh_TW/API/types/classes/Complex.md index e9e8b49a..c3dd5521 100644 --- a/doc/zh_TW/API/types/classes/Complex.md +++ b/doc/zh_TW/API/types/classes/Complex.md @@ -1,8 +1,8 @@ # Complex -表示复数的类型。在 Erg 中表示数字的类型,例如 Float、Int和Nat,通常派生于Complex +表示復數的類型。在 Erg 中表示數字的類型,例如 Float、Int和Nat,通常派生于Complex -## 父类 +## 父類 Num 和 Norm diff --git a/doc/zh_TW/API/types/classes/Dict!.md b/doc/zh_TW/API/types/classes/Dict!.md index 20e33c4c..1b7ae72c 100644 --- a/doc/zh_TW/API/types/classes/Dict!.md +++ b/doc/zh_TW/API/types/classes/Dict!.md @@ -1,6 +1,6 @@ # Dict! K, V -表示字典(哈希Map)的类型。 有一个语法糖叫做`{K: V}` +表示字典(哈希Map)的類型。 有一個語法糖叫做`{K: V}` ## 方法 diff --git a/doc/zh_TW/API/types/classes/Either.md b/doc/zh_TW/API/types/classes/Either.md index 43a45deb..fd7e11ff 100644 --- a/doc/zh_TW/API/types/classes/Either.md +++ b/doc/zh_TW/API/types/classes/Either.md @@ -1,6 +1,6 @@ # Either L, R = L or R -表示L或R的类型。 您可以将其视为Or类型的二元形式 +表示L或R的類型。 您可以將其視為Or類型的二元形式 ## 方法 diff --git a/doc/zh_TW/API/types/classes/Float.md b/doc/zh_TW/API/types/classes/Float.md index 06479f12..8e64241a 100644 --- a/doc/zh_TW/API/types/classes/Float.md +++ b/doc/zh_TW/API/types/classes/Float.md @@ -1,21 +1,21 @@ # 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 +表示實數(包含小數的數)的類型。符合IEEE 754的浮點數,在其他語言中一般是float的類型。 +Float的大小為8(1byte)~128(16byte)。如果只是Float,則表示`Float64`。 +Erg 中的 0.1 實際上屬于 Ratio 類型,而不是 Float 類型。沒有浮點類型字面量,它是由 `(Ratio object)f64` 生成的(例如 (1/2)f64, 15f64)。 f64 對應實數 1 -## 父类 +## 父類 Complex 和 Ord ## 方法 * sgn(self) -> {-1, 0, 1} - 返回标志 + 返回標志 * truncate(self) -> Int - 返回最接近自身的整数 + 返回最接近自身的整數 * separate(self) -> [Str] * separate(self, dight: Nat) -> [Str] - 按digit位数划分。没有自变量 + 按digit位數劃分。沒有自變量 diff --git a/doc/zh_TW/API/types/classes/Inf.md b/doc/zh_TW/API/types/classes/Inf.md index 0e7e02b9..bbdabfe0 100644 --- a/doc/zh_TW/API/types/classes/Inf.md +++ b/doc/zh_TW/API/types/classes/Inf.md @@ -1,7 +1,7 @@ # Inf -Inf是一个类,其唯一实例是inf。 -inf的主要用途是用于区间类型。 -例如,大于等于 2 的整数类型是 `2.. Self(L1+L2, R1+R2) -正常加法。 `Int` 和 `Nat` 的添加在此定义为假装它在每个类中定义 +正常加法。 `Int` 和 `Nat` 的添加在此定義為假裝它在每個類中定義 ```python 0..10 + 1..12 == 1..22 diff --git a/doc/zh_TW/API/types/classes/Interval.md b/doc/zh_TW/API/types/classes/Interval.md index 68e69030..56e3bf4f 100644 --- a/doc/zh_TW/API/types/classes/Interval.md +++ b/doc/zh_TW/API/types/classes/Interval.md @@ -1,6 +1,6 @@ # Interval begin, end := WellOrder -表示有序集合类型 (WellOrder) 的子类型的类型。Interval 类型具有派生类型,例如 PreOpen(x<..y)。 +表示有序集合類型 (WellOrder) 的子類型的類型。Interval 類型具有派生類型,例如 PreOpen(x<..y)。 ```python Months = 1..12 @@ -10,9 +10,9 @@ Winter = November..December or January..February ``` ```python -0..1 # 整数范围 -0.0..1.0 # 真实(有理)范围 +0..1 # 整數范圍 +0.0..1.0 # 真實(有理)范圍 # 或 0/1..1/1 相同 ``` -计算机无法处理无限位数的数字,所以实数的范围实际上是有理数的范围。 \ No newline at end of file +計算機無法處理無限位數的數字,所以實數的范圍實際上是有理數的范圍。 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Matrix.md b/doc/zh_TW/API/types/classes/Matrix.md index bbb43b4f..b653846d 100644 --- a/doc/zh_TW/API/types/classes/Matrix.md +++ b/doc/zh_TW/API/types/classes/Matrix.md @@ -1,7 +1,7 @@ # Matrix T: Num, Shape: [M, N] -表示矩阵的类型。 它继承自 Tensor[M, N] +表示矩陣的類型。 它繼承自 Tensor[M, N] -## 定义 +## 定義 Inherit Tensor T, [M, N] diff --git a/doc/zh_TW/API/types/classes/Nat.md b/doc/zh_TW/API/types/classes/Nat.md index 05911648..e02e9db6 100644 --- a/doc/zh_TW/API/types/classes/Nat.md +++ b/doc/zh_TW/API/types/classes/Nat.md @@ -1,8 +1,8 @@ # Nat -表示自然数的类型。 用于数组索引和范围类型 +表示自然數的類型。 用于數組索引和范圍類型 -## 定义 +## 定義 ```python Nat = 0.._ diff --git a/doc/zh_TW/API/types/classes/Neg.md b/doc/zh_TW/API/types/classes/Neg.md index 7298453f..ef25b01d 100644 --- a/doc/zh_TW/API/types/classes/Neg.md +++ b/doc/zh_TW/API/types/classes/Neg.md @@ -1,8 +1,8 @@ # Neg -表示负整数的类型。 Pos和Neg和{0} == Int -它还具有一些值得注意的属性,例如不被零除和 Neg * Neg == Pos +表示負整數的類型。 Pos和Neg和{0} == Int +它還具有一些值得注意的屬性,例如不被零除和 Neg * Neg == Pos -## 定义 +## 定義 Inf<..-1 diff --git a/doc/zh_TW/API/types/classes/Never.md b/doc/zh_TW/API/types/classes/Never.md index 0336f19c..c2288573 100644 --- a/doc/zh_TW/API/types/classes/Never.md +++ b/doc/zh_TW/API/types/classes/Never.md @@ -1,7 +1,7 @@ # Never -它是所有类型的子类型。 它是一个`Class`,因为它拥有所有的方法,当然还有 `.new`。但是,它没有实例,并且Erg会在即将创建的那一刻停止。 -还有一种叫做`Panic`的类型没有实例,但是`Never`用于正常终止或故意无限循环,`Panic`用于异常终止。 +它是所有類型的子類型。 它是一個`Class`,因為它擁有所有的方法,當然還有 `.new`。但是,它沒有實例,并且Erg會在即將創建的那一刻停止。 +還有一種叫做`Panic`的類型沒有實例,但是`Never`用于正常終止或故意無限循環,`Panic`用于異常終止。 ```python # Never <: Panic @@ -9,5 +9,5 @@ f(): Panic = exit 0 # OK g(): Never = panic() # TypeError ``` -`Never`/`Panic`的 OR 类型,例如`T 或 Never`可以转换为`T`。 这是因为`Never`在语义上是一个从不出现的选项(如果出现了,程序会立即停止)。 -但是,在函数的返回值类型中使用时,`or Never`不能省略,因为它表示程序可能会终止。 \ No newline at end of file +`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 index b73422a0..2dc71d41 100644 --- a/doc/zh_TW/API/types/classes/NonZero.md +++ b/doc/zh_TW/API/types/classes/NonZero.md @@ -1,6 +1,6 @@ # NonZero N -表示非零数的类。 保证除零的安全性 +表示非零數的類。 保證除零的安全性 ```mermaid classDiagram diff --git a/doc/zh_TW/API/types/classes/Object.md b/doc/zh_TW/API/types/classes/Object.md index 79a6e635..62740f79 100644 --- a/doc/zh_TW/API/types/classes/Object.md +++ b/doc/zh_TW/API/types/classes/Object.md @@ -1,6 +1,6 @@ # Object -它是所有类型的超类型 +它是所有類型的超類型 ## 方法 diff --git a/doc/zh_TW/API/types/classes/Operator.md b/doc/zh_TW/API/types/classes/Operator.md index 581e7ac5..0d40c2d7 100644 --- a/doc/zh_TW/API/types/classes/Operator.md +++ b/doc/zh_TW/API/types/classes/Operator.md @@ -1,7 +1,7 @@ # Operator [...T], O -是运算符的类型 +是運算符的類型 -## 定义 +## 定義 Inherit Func [...T], O diff --git a/doc/zh_TW/API/types/classes/Option.md b/doc/zh_TW/API/types/classes/Option.md index bbcefdf9..979f8d25 100644 --- a/doc/zh_TW/API/types/classes/Option.md +++ b/doc/zh_TW/API/types/classes/Option.md @@ -1,12 +1,12 @@ # Option T = T or NoneType -表示“可能失败”的类型。 +表示“可能失敗”的類型。 ## 方法 * unwrap(self, msg = "unwrapped a None value") -> T or Panic -提取它,期望内容是 `T` 类型。 如果是 `None`,则输出 `msg` 并恐慌 +提取它,期望內容是 `T` 類型。 如果是 `None`,則輸出 `msg` 并恐慌 ```python x = "...".parse(Int).into(Option Int) diff --git a/doc/zh_TW/API/types/classes/Pos.md b/doc/zh_TW/API/types/classes/Pos.md index 404b30ae..42edd789 100644 --- a/doc/zh_TW/API/types/classes/Pos.md +++ b/doc/zh_TW/API/types/classes/Pos.md @@ -1,8 +1,8 @@ # Pos -Pos是一种表示正数(大于或等于1的整数)的类型。 -由于不包括0,因此具有消除被零除的可能性等优点。 +Pos是一種表示正數(大于或等于1的整數)的類型。 +由于不包括0,因此具有消除被零除的可能性等優點。 -## 定义 +## 定義 `Pos = 1.._` diff --git a/doc/zh_TW/API/types/classes/Ratio.md b/doc/zh_TW/API/types/classes/Ratio.md index 58b4211b..1e98ca7c 100644 --- a/doc/zh_TW/API/types/classes/Ratio.md +++ b/doc/zh_TW/API/types/classes/Ratio.md @@ -1,5 +1,5 @@ # 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类型之前,请进行真实的性能测试。 业余爱好者无条件偏爱较轻的模具。 +表示有理數的類型。 它主要用于當您要使用分數時。 +實際上,Erg中的/運算符返回 Ratio。1/3等不被評估為 0.33333... 并且被處理為1/3。 此外,0.1 相當于 1/10。 所以`0.1 + 0.2 == 0.3`。 這聽起來很明顯,但在 Python中它是False。 +但是,Ratio類型的效率往往比Float類型略低。 在執行速度很重要且不需要精確數值的地方應該使用浮點類型。 然而,正如Rob Pike所說,過早優化是萬惡之源。 在丟棄Ratio類型并使用Float類型之前,請進行真實的性能測試。 業余愛好者無條件偏愛較輕的模具。 diff --git a/doc/zh_TW/API/types/classes/Record.md b/doc/zh_TW/API/types/classes/Record.md index 7dc5f93f..1e9056a7 100644 --- a/doc/zh_TW/API/types/classes/Record.md +++ b/doc/zh_TW/API/types/classes/Record.md @@ -1,7 +1,7 @@ # Record -记录所属的类。例如,`{i = 1}` 是`Structural {i = Int}` 类型的元素,并且是`{i = Int}` 类的实例 -请注意,其他类的实例是记录类型的元素,而不是记录类的实例 +記錄所屬的類。例如,`{i = 1}` 是`Structural {i = Int}` 類型的元素,并且是`{i = Int}` 類的實例 +請注意,其他類的實例是記錄類型的元素,而不是記錄類的實例 ```python assert not Structural({i = Int}) in Class diff --git a/doc/zh_TW/API/types/classes/Result.md b/doc/zh_TW/API/types/classes/Result.md index 67134e03..43656839 100644 --- a/doc/zh_TW/API/types/classes/Result.md +++ b/doc/zh_TW/API/types/classes/Result.md @@ -4,4 +4,4 @@ Result T, E <: Error = Either T, E ``` -和 `Option` 一样,它代表“一个可能失败的值”,但它可以有失败的上下文。 用法与`Either`几乎相同。 \ No newline at end of file +和 `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 index af0f1ee7..317d291d 100644 --- a/doc/zh_TW/API/types/classes/Str!.md +++ b/doc/zh_TW/API/types/classes/Str!.md @@ -1,3 +1,3 @@ # StrWithLen! N: Nat! = Inherit StrWithLen N -表示可变长度字符串的类型 +表示可變長度字符串的類型 diff --git a/doc/zh_TW/API/types/classes/Str.md b/doc/zh_TW/API/types/classes/Str.md index 269ea06a..b384d572 100644 --- a/doc/zh_TW/API/types/classes/Str.md +++ b/doc/zh_TW/API/types/classes/Str.md @@ -1,9 +1,9 @@ # Str -(不变长度)表示字符串的类型。 简单的 `Str` 类型是删除了字符数的 `StrWithLen N` 类型(`Str = StrWithLen _`) +(不變長度)表示字符串的類型。 簡單的 `Str` 類型是刪除了字符數的 `StrWithLen N` 類型(`Str = StrWithLen _`) ## 方法 * isnumeric -返回字符串是否为阿拉伯数字。 使用 `isunicodenumeric` 判断汉字数字和其他表示数字的字符(注意此行为与 Python 不同)。 \ No newline at end of file +返回字符串是否為阿拉伯數字。 使用 `isunicodenumeric` 判斷漢字數字和其他表示數字的字符(注意此行為與 Python 不同)。 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Subroutine.md b/doc/zh_TW/API/types/classes/Subroutine.md index 60bd76de..60cbb806 100644 --- a/doc/zh_TW/API/types/classes/Subroutine.md +++ b/doc/zh_TW/API/types/classes/Subroutine.md @@ -1,12 +1,12 @@ # Subroutine -Func和Proc的基本类型。 +Func和Proc的基本類型。 ## 方法 * return -中断子程序并返回指定的值。 用于快速逃离嵌套 +中斷子程序并返回指定的值。 用于快速逃離嵌套 ```python f x = diff --git a/doc/zh_TW/API/types/classes/Tensor.md b/doc/zh_TW/API/types/classes/Tensor.md index 2fa51a80..b9cfd3f8 100644 --- a/doc/zh_TW/API/types/classes/Tensor.md +++ b/doc/zh_TW/API/types/classes/Tensor.md @@ -1,7 +1,7 @@ # Tensor Shape: [Nat; N] - 用于有效操作多维数组的类。 它还定义了诸如多维数组上的乘法之类的操作 - Matrix、Vector 等都继承自该类型 + 用于有效操作多維數組的類。 它還定義了諸如多維數組上的乘法之類的操作 + Matrix、Vector 等都繼承自該類型 ```python Tensor.arange(0..9) # Tensor [10] diff --git a/doc/zh_TW/API/types/classes/TransCell(T).md b/doc/zh_TW/API/types/classes/TransCell(T).md index afb24e2c..38349392 100644 --- a/doc/zh_TW/API/types/classes/TransCell(T).md +++ b/doc/zh_TW/API/types/classes/TransCell(T).md @@ -1,7 +1,7 @@ # TransCell! T: Type! -它是一个单元格,其内容可以针对每个模具进行更改。 由于它是T类型的子类型,因此它也表现为T类型 -当它在初始化时输入T时很有用,并且在某个点之后总是输入U +它是一個單元格,其內容可以針對每個模具進行更改。 由于它是T類型的子類型,因此它也表現為T類型 +當它在初始化時輸入T時很有用,并且在某個點之后總是輸入U ```python a = TransCell!.new None diff --git a/doc/zh_TW/API/types/classes/Tuple.md b/doc/zh_TW/API/types/classes/Tuple.md index 6ee22bb4..9277cf54 100644 --- a/doc/zh_TW/API/types/classes/Tuple.md +++ b/doc/zh_TW/API/types/classes/Tuple.md @@ -1,12 +1,12 @@ # Tuple T: ...Type -包含多种类型对象的集合 +包含多種類型對象的集合 ## 方法 * zip self, other - 组合两个有序集合(数组或元组) + 組合兩個有序集合(數組或元組) ```python assert ([1, 2, 3].zip [4, 5, 6])[0] == (1, 4) @@ -14,8 +14,8 @@ * zip_by self, op, other - 一种泛化 zip 的方法。 您可以指定一个二进制操作来组合 - `()`、`[]`、`{}`、`{:}` 也可以指定为运算符,分别生成元组、数组、集合和字典 + 一種泛化 zip 的方法。 您可以指定一個二進制操作來組合 + `()`、`[]`、`{}`、`{:}` 也可以指定為運算符,分別生成元組、數組、集合和字典 ```python assert ([1, 2, 3].zip([4, 5, 6]))[0] == (1, 4) diff --git a/doc/zh_TW/API/types/classes/Vector.md b/doc/zh_TW/API/types/classes/Vector.md index f9a159ed..d5351a61 100644 --- a/doc/zh_TW/API/types/classes/Vector.md +++ b/doc/zh_TW/API/types/classes/Vector.md @@ -1,3 +1,3 @@ # Vector T: Num, N: Nat -表示向量的类型。与同名的Rust和C++类型不同,这种类型只处理数字。 \ No newline at end of file +表示向量的類型。與同名的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 index 8494aa4f..083de661 100644 --- a/doc/zh_TW/API/types/patches/BinOp.md +++ b/doc/zh_TW/API/types/patches/BinOp.md @@ -1,7 +1,7 @@ # BinOp L, R, O -二元运算符的类型 +二元運算符的類型 -## 修补程序 +## 修補程序 Operator [L, R], O diff --git a/doc/zh_TW/API/types/patches/UnaryOp.md b/doc/zh_TW/API/types/patches/UnaryOp.md index 6b56481a..b4ec87f0 100644 --- a/doc/zh_TW/API/types/patches/UnaryOp.md +++ b/doc/zh_TW/API/types/patches/UnaryOp.md @@ -1,7 +1,7 @@ # UnaryOp T, O -一元运算符的类型 +一元運算符的類型 -## 定义 +## 定義 Operator [T], O diff --git a/doc/zh_TW/API/types/traits/Add(R,O).md b/doc/zh_TW/API/types/traits/Add(R,O).md index 4d8b6220..54182f26 100644 --- a/doc/zh_TW/API/types/traits/Add(R,O).md +++ b/doc/zh_TW/API/types/traits/Add(R,O).md @@ -7,14 +7,14 @@ Add R = Trait { } ``` -`Add`是一种定义加法的类型。加法有两种类型的`+`:方法和函数 -`+`作为二元函数,即`_+_`,定义如下: +`Add`是一種定義加法的類型。加法有兩種類型的`+`:方法和函數 +`+`作為二元函數,即`_+_`,定義如下: ```python `_+_`(l: Add(R, O), r: R): O = l.`_+_` r ``` -这个定义的目的是让 `+` 可以被视为一个函数而不是一个方法 +這個定義的目的是讓 `+` 可以被視為一個函數而不是一個方法 ```python assert [1, 2, 3].fold(0, `_+_`) == 6 @@ -23,7 +23,7 @@ call op, x, y = op(x, y) assert call(`_+_`, 1, 2) == 3 ``` -加法是这样输入的 +加法是這樣輸入的 ```python f: |O: Type; A <: Add(Int, O)| A -> O diff --git a/doc/zh_TW/API/types/traits/Div(R,O).md b/doc/zh_TW/API/types/traits/Div(R,O).md index 020acba5..085960f6 100644 --- a/doc/zh_TW/API/types/traits/Div(R,O).md +++ b/doc/zh_TW/API/types/traits/Div(R,O).md @@ -1,6 +1,6 @@ # Div R, O -如果除以零没有错误,请使用“SafeDiv” +如果除以零沒有錯誤,請使用“SafeDiv” ```python Div R, O = Trait { diff --git a/doc/zh_TW/API/types/traits/Into.md b/doc/zh_TW/API/types/traits/Into.md index de92a824..e9224512 100644 --- a/doc/zh_TW/API/types/traits/Into.md +++ b/doc/zh_TW/API/types/traits/Into.md @@ -1,8 +1,8 @@ # Into T -一种类型,表明它可以被类型转换为类型T。 -即使Self和T之间没有继承关系,也是在关系可以相互转换的时候定义的。 -与继承不同,没有隐式转换。您必须始终调用 `.into` 方法。 +一種類型,表明它可以被類型轉換為類型T。 +即使Self和T之間沒有繼承關系,也是在關系可以相互轉換的時候定義的。 +與繼承不同,沒有隱式轉換。您必須始終調用 `.into` 方法。 ## 方法 diff --git a/doc/zh_TW/API/types/traits/Num.md b/doc/zh_TW/API/types/traits/Num.md index d5e3b2d8..92315877 100644 --- a/doc/zh_TW/API/types/traits/Num.md +++ b/doc/zh_TW/API/types/traits/Num.md @@ -1,13 +1,13 @@ # Num -## 定义初始化 +## 定義初始化 ```python Num R = Add(R) and Sub(R) and Mul(R) and Eq Num = Num Self ``` -## 父类 +## 父類 Add and Sub and Mul and Eq diff --git a/doc/zh_TW/API/types/traits/Sample.md b/doc/zh_TW/API/types/traits/Sample.md index 5d2a6cdb..7e57d1eb 100644 --- a/doc/zh_TW/API/types/traits/Sample.md +++ b/doc/zh_TW/API/types/traits/Sample.md @@ -1,20 +1,20 @@ # Sample -具有“随机”选择实例的`sample`和`sample!`方法的特征。`sample`方法总是返回相同的实例,而`sample!`方法返回一个随机实例,该实例随调用而变化 +具有“隨機”選擇實例的`sample`和`sample!`方法的特征。`sample`方法總是返回相同的實例,而`sample!`方法返回一個隨機實例,該實例隨調用而變化 -请注意,这是一个假设您想要一个适当的实例进行测试等的特征,并且它不一定是随机的。 如果您想要随机抽样,请使用“随机”模块。 +請注意,這是一個假設您想要一個適當的實例進行測試等的特征,并且它不一定是隨機的。 如果您想要隨機抽樣,請使用“隨機”模塊。 -所有主要的值类都实现了 `Sample`。它还在由“Sample”类组成的元组类型、记录类型、Or类型和筛选类型中实现 +所有主要的值類都實現了 `Sample`。它還在由“Sample”類組成的元組類型、記錄類型、Or類型和篩選類型中實現 ```python assert Int.sample() == 42 assert Str.sample() == "example" -# Int默认在64bit范围内采样 +# Int默認在64bit范圍內采樣 print! Int.sample!() # 1313798 print! {x = Int; y = Int}.sample!() # {x = -32432892, y = 78458576891} ``` -下面是一个`Sample`的实现示例 +下面是一個`Sample`的實現示例 ```python EmailAddress = Class {header = Str; domain = Str}, Impl=Sample and Show diff --git a/doc/zh_TW/API/types/traits/Unpack.md b/doc/zh_TW/API/types/traits/Unpack.md index 7c721151..e11011b1 100644 --- a/doc/zh_TW/API/types/traits/Unpack.md +++ b/doc/zh_TW/API/types/traits/Unpack.md @@ -1,6 +1,6 @@ # Unpack -标记性状。实现时,元素可以像记录一样通过模式匹配来分解 +標記性狀。實現時,元素可以像記錄一樣通過模式匹配來分解 ```python C = Class {i = Int}, Impl=Unpack diff --git a/doc/zh_TW/compiler/TODO_hint.md b/doc/zh_TW/compiler/TODO_hint.md index 790ce1f7..2cf268ad 100644 --- a/doc/zh_TW/compiler/TODO_hint.md +++ b/doc/zh_TW/compiler/TODO_hint.md @@ -1,4 +1,4 @@ -# 提示(未实现) +# 提示(未實現) -* `x 未定义`(x 已被`Del` 删除)=> `提示:在第 X 行删除` -*补丁方法重复:“提示:指定补丁(如`T.foo(1)`)或使用`Del`删除任何`.foo`” \ No newline at end of file +* `x 未定義`(x 已被`Del` 刪除)=> `提示:在第 X 行刪除` +*補丁方法重復:“提示:指定補丁(如`T.foo(1)`)或使用`Del`刪除任何`.foo`” \ No newline at end of file diff --git a/doc/zh_TW/compiler/TODO_recov_suggest.md b/doc/zh_TW/compiler/TODO_recov_suggest.md index 93a193b1..07c6fc60 100644 --- a/doc/zh_TW/compiler/TODO_recov_suggest.md +++ b/doc/zh_TW/compiler/TODO_recov_suggest.md @@ -1,11 +1,11 @@ -# 错误恢复建议(尚未实现) +# 錯誤恢復建議(尚未實現) * `1 or 2`, `1 and 2` => `{1, 2}`? -* `U = Inherit T` => 非类类型不能被继承,或者`U = Class T`? -* `Int and Str` => 不允许多重继承,或者`Int or Str`? +* `U = Inherit T` => 非類類型不能被繼承,或者`U = Class T`? +* `Int and Str` => 不允許多重繼承,或者`Int or Str`? * `: [1, 2]` => `: {1, 2}`? * `: [Int, 2]` => `: [Int; 2]`? -* `[Int; Str]` => `(Int, Str)`(Tuple) 还是 `[Int: Str]`(Dict)? +* `[Int; Str]` => `(Int, Str)`(Tuple) 還是 `[Int: Str]`(Dict)? * `{x: Int}` => `{x = Int}`? * `{x = Int}!` => `{x = Int!}`? * `ref! immut_expr` => `ref! !immut_expr`? \ No newline at end of file diff --git a/doc/zh_TW/compiler/TODO_warn.md b/doc/zh_TW/compiler/TODO_warn.md index 9f1fcf23..a84e53c0 100644 --- a/doc/zh_TW/compiler/TODO_warn.md +++ b/doc/zh_TW/compiler/TODO_warn.md @@ -1,5 +1,5 @@ -# 警告(尚未实现) +# 警告(尚未實現) -* `t = {(record type)}` => `T = {(record type)}`?(只有定义为常量的类型才能用于类型说明) +* `t = {(record type)}` => `T = {(record type)}`?(只有定義為常量的類型才能用于類型說明) * `{I: Int | ...}!` => `{I: Int! | ...}` -* for/while 块中的`return x`(`x != ()`) => `f::return`(外部块)? \ No newline at end of file +* for/while 塊中的`return x`(`x != ()`) => `f::return`(外部塊)? \ No newline at end of file diff --git a/doc/zh_TW/compiler/abandoned.md b/doc/zh_TW/compiler/abandoned.md index dc120306..d566fdf1 100644 --- a/doc/zh_TW/compiler/abandoned.md +++ b/doc/zh_TW/compiler/abandoned.md @@ -1,10 +1,10 @@ -# 废弃/拒绝的语言规范 +# 廢棄/拒絕的語言規范 -## 重载(临时多态性) +## 重載(臨時多態性) -被放弃了,因为它可以用参数+子类型多态来代替,并且与Python的语义不兼容。 有关详细信息,请参阅 [overload](../syntax/type/overloading.md) 文章。 +被放棄了,因為它可以用參數+子類型多態來代替,并且與Python的語義不兼容。 有關詳細信息,請參閱 [overload](../syntax/type/overloading.md) 文章。 -## 具有显式生命周期的所有权系统 +## 具有顯式生命周期的所有權系統 -原计划引入 Rust 之类的所有权系统,但由于与 Python 的语义不兼容以及需要引入生命周期注解等复杂规范而被放弃,并且所有不可变对象都是 RC。托管的可变对象现在只有一个所有权. -Dyne 没有 C# 和 Nim 那样的 GIL,策略是允许值对象和低级操作在安全范围内。 \ No newline at end of file +原計劃引入 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 index f33fdfaf..9fddde10 100644 --- a/doc/zh_TW/compiler/architecture.md +++ b/doc/zh_TW/compiler/architecture.md @@ -1,42 +1,42 @@ -# `ergc` 的架构 +# `ergc` 的架構 -## 1. 扫描 Erg 脚本 (.er) 并生成 `TokenStream` (parser/lex.rs) +## 1. 掃描 Erg 腳本 (.er) 并生成 `TokenStream` (parser/lex.rs) -* parser/lexer/Lexer 生成`TokenStream`(这是一个Token的迭代器,TokenStream可以通过lexer.collect()生成) - * `Lexer` 由 `Lexer::new` 或 `Lexer::from_str` 构造,其中 `Lexer::new` 从文件或命令选项中读取代码。 - * `Lexer` 可以作为迭代器按顺序生成令牌;如果您想一次获得 `TokenStream`,请使用 `Lexer::lex`。 - * `Lexer` 输出 `LexError` 为错误,但 `LexError` 没有足够的信息显示自己。如果要显示错误,请使用 `LexerRunner` 转换错误。 - * 如果你想单独使用 `Lexer`,也可以使用 `LexerRunner`;`Lexer` 只是一个迭代器,并没有实现 `Runnable` 特性。 - * `Runnable` 由 `LexerRunner`、`ParserRunner`、`Compiler` 和 `VirtualMachine` 实现。 +* parser/lexer/Lexer 生成`TokenStream`(這是一個Token的迭代器,TokenStream可以通過lexer.collect()生成) + * `Lexer` 由 `Lexer::new` 或 `Lexer::from_str` 構造,其中 `Lexer::new` 從文件或命令選項中讀取代碼。 + * `Lexer` 可以作為迭代器按順序生成令牌;如果您想一次獲得 `TokenStream`,請使用 `Lexer::lex`。 + * `Lexer` 輸出 `LexError` 為錯誤,但 `LexError` 沒有足夠的信息顯示自己。如果要顯示錯誤,請使用 `LexerRunner` 轉換錯誤。 + * 如果你想單獨使用 `Lexer`,也可以使用 `LexerRunner`;`Lexer` 只是一個迭代器,并沒有實現 `Runnable` 特性。 + * `Runnable` 由 `LexerRunner`、`ParserRunner`、`Compiler` 和 `VirtualMachine` 實現。 -## 2. 转换 `TokenStream` -> `AST` (parser/parse.rs) +## 2. 轉換 `TokenStream` -> `AST` (parser/parse.rs) -* `Parser` 和 `Lexer` 一样,有两个构造函数,`Parser::new` 和 `Parser::from_str`,而 `Parser::parse` 会给出 `AST`。 -* `AST` 是 `Vec` 的包装器类型。 +* `Parser` 和 `Lexer` 一樣,有兩個構造函數,`Parser::new` 和 `Parser::from_str`,而 `Parser::parse` 會給出 `AST`。 +* `AST` 是 `Vec` 的包裝器類型。 -### 2.5 脱糖 `AST` +### 2.5 脫糖 `AST` -* 扩展嵌套变量 (`Desugarer::desugar_nest_vars_pattern`) -* desugar 多模式定义语法(`Desugarer::desugar_multiple_pattern_def`) +* 擴展嵌套變量 (`Desugarer::desugar_nest_vars_pattern`) +* desugar 多模式定義語法(`Desugarer::desugar_multiple_pattern_def`) -## 3. 类型检查和推断,转换 `AST` -> `HIR` (compiler/lower.rs) +## 3. 類型檢查和推斷,轉換 `AST` -> `HIR` (compiler/lower.rs) -* `HIR` 有每个变量的类型信息。它是用于“高级中间表示”的。 -* `HIR` 只保存变量的类型,但这已经足够了。在极端情况下,这是因为 Erg 只有转换(或运算符)应用程序的参数对象。 -* `ASTLower` 可以用与`Parser` 和`Lexer` 相同的方式构造。 -* 如果没有错误发生,`ASTLowerer::lower` 将输出 `HIR` 和 `CompileWarnings` 的元组。 -* `ASTLowerer`归`Compiler`所有。与传统结构不同,`ASTLowerer`处理代码上下文并且不是一次性的。 -* 如果类型推断的结果不完整(如果存在未知类型变量),名称解析时会出错。 +* `HIR` 有每個變量的類型信息。它是用于“高級中間表示”的。 +* `HIR` 只保存變量的類型,但這已經足夠了。在極端情況下,這是因為 Erg 只有轉換(或運算符)應用程序的參數對象。 +* `ASTLower` 可以用與`Parser` 和`Lexer` 相同的方式構造。 +* 如果沒有錯誤發生,`ASTLowerer::lower` 將輸出 `HIR` 和 `CompileWarnings` 的元組。 +* `ASTLowerer`歸`Compiler`所有。與傳統結構不同,`ASTLowerer`處理代碼上下文并且不是一次性的。 +* 如果類型推斷的結果不完整(如果存在未知類型變量),名稱解析時會出錯。 -## 4. 检查副作用(compiler/effectcheck.rs) +## 4. 檢查副作用(compiler/effectcheck.rs) -## 4. 检查所有权(compiler/memcheck.rs) +## 4. 檢查所有權(compiler/memcheck.rs) -## 5. 从`HIR`(compiler/codegen.rs)生成字节码(`CodeObj`) +## 5. 從`HIR`(compiler/codegen.rs)生成字節碼(`CodeObj`) -* 根据表达式的类型信息,将执行量化子程序的名称解析。 +* 根據表達式的類型信息,將執行量化子程序的名稱解析。 -##(6.(未来计划)转换字节码 -> LLVM IR) +##(6.(未來計劃)轉換字節碼 -> LLVM IR) -* 字节码是基于堆栈的,而 LLVM IR 是基于寄存器的。 - 这个转换过程会多出几层中间过程。 \ No newline at end of file +* 字節碼是基于堆棧的,而 LLVM IR 是基于寄存器的。 + 這個轉換過程會多出幾層中間過程。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/errors.md b/doc/zh_TW/compiler/errors.md index 722d1339..b0f043d9 100644 --- a/doc/zh_TW/compiler/errors.md +++ b/doc/zh_TW/compiler/errors.md @@ -2,27 +2,27 @@ ## AssignError -尝试重写不可变变量时发生 +嘗試重寫不可變變量時發生 ## AttributeError -尝试访问不存在的属性时发生 +嘗試訪問不存在的屬性時發生 ## PurityError -当您在不允许副作用的范围内(函数、不可变类型等)编写导致副作用的代码时发生 +當您在不允許副作用的范圍內(函數、不可變類型等)編寫導致副作用的代碼時發生 ## MoveError -尝试访问已移动的变量时发生 +嘗試訪問已移動的變量時發生 ## BorrowError -在存在对对象的借用时尝试获取可变引用时发生 +在存在對對象的借用時嘗試獲取可變引用時發生 ## CyclicError -当你有一个明显不可阻挡的循环时发生 +當你有一個明顯不可阻擋的循環時發生 ```python i: Int = i @@ -38,58 +38,58 @@ U = T ## BytecodeError -当加载的字节码损坏时发生 +當加載的字節碼損壞時發生 ## CompileSystemError -在编译器内部发生错误时发生 +在編譯器內部發生錯誤時發生 ## EnvironmentError -如果您在安装期间没有访问权限,则会发生这种情况 +如果您在安裝期間沒有訪問權限,則會發生這種情況 ## FeatureError -在检测到未正式提供的实验性功能时发生 +在檢測到未正式提供的實驗性功能時發生 ## ImportError ## IndentationError -检测到不良缩进时发生 +檢測到不良縮進時發生 派生自SyntaxError ## NameError -当您访问不存在的变量时发生 +當您訪問不存在的變量時發生 ## NotImplementedError -当您调用具有定义但没有实现的 API 时发生 +當您調用具有定義但沒有實現的 API 時發生 派生自 TypeError ## PatternError -当检测到非法模式时发生 +當檢測到非法模式時發生 派生自SyntaxError ## SyntaxError -在检测到错误语法时发生 +在檢測到錯誤語法時發生 ## TabError -在使用制表符进行缩进/间距时发生 +在使用制表符進行縮進/間距時發生 派生自SyntaxError ## TypeError -当对象类型不匹配时发生 +當對象類型不匹配時發生 ## UnboundLocalError -在定义之前使用变量时发生 -更准确地说,它发生在以前使用过在范围内定义的变量时 +在定義之前使用變量時發生 +更準確地說,它發生在以前使用過在范圍內定義的變量時 ```python i = 0 @@ -99,8 +99,8 @@ f x = y + i ``` -在这段代码中,`y = i + x` 中的 `i` 是一个未定义的变量 -但是,常量可以在定义之前在另一个函数中调用 +在這段代碼中,`y = i + x` 中的 `i` 是一個未定義的變量 +但是,常量可以在定義之前在另一個函數中調用 ```python f() = g() @@ -111,7 +111,7 @@ g() = f() ## SyntaxWarning -它在语法上很好,但是当我们检测到冗余或不常见的代码(不必要的 `()` 等)时就会发生这种情况 +它在語法上很好,但是當我們檢測到冗余或不常見的代碼(不必要的 `()` 等)時就會發生這種情況 ```python if (True): # SyntaxWarning: unnecessary parentheses @@ -120,12 +120,12 @@ if (True): # SyntaxWarning: unnecessary parentheses ## DeprecationWarning -在不推荐使用引用的对象时发生 -(开发人员在生成此警告时应始终提供替代方法作为提示) +在不推薦使用引用的對象時發生 +(開發人員在生成此警告時應始終提供替代方法作為提示) ## FutureWarning -当您检测到将来可能导致问题的代码时发生 -此警告是由版本兼容性问题(包括库)以及语法和 API 的更改引起的 +當您檢測到將來可能導致問題的代碼時發生 +此警告是由版本兼容性問題(包括庫)以及語法和 API 的更改引起的 ## ImportWarning diff --git a/doc/zh_TW/compiler/hir.md b/doc/zh_TW/compiler/hir.md index 748cc4d6..48040873 100644 --- a/doc/zh_TW/compiler/hir.md +++ b/doc/zh_TW/compiler/hir.md @@ -1,9 +1,9 @@ -# 高级中间表示(HIR, High-level Intermediate Representation) +# 高級中間表示(HIR, High-level Intermediate Representation) -HIR 是 Erg 编译器从 AST 生成的结构 -此结构包含源代码中每个表达式的完整类型信息,并且在语法上已脱糖 -AST与源代码一一对应(纯文本),但是HIR去掉了不必要的代码信息,添加了省略的类型信息,所以HIR可以转换为源代码很难恢复 -让我们在下面的代码中查看 HIR 的示例 +HIR 是 Erg 編譯器從 AST 生成的結構 +此結構包含源代碼中每個表達式的完整類型信息,并且在語法上已脫糖 +AST與源代碼一一對應(純文本),但是HIR去掉了不必要的代碼信息,添加了省略的類型信息,所以HIR可以轉換為源代碼很難恢復 +讓我們在下面的代碼中查看 HIR 的示例 ```python v = ![] @@ -12,7 +12,7 @@ for! 0..10, i => log v.sum() ``` -从此代码生成的 AST 如下所示: +從此代碼生成的 AST 如下所示: ```python AST(Module[ @@ -69,7 +69,7 @@ AST(Module[ ]) ``` -从 AST 生成的 HIR 如下所示: +從 AST 生成的 HIR 如下所示: ```python HIR(Module[ @@ -144,5 +144,5 @@ HIR(Module[ ]) ``` -对象类型被推断为尽可能小。 另一方面,子例程推断实现存在的类型 -因此,实际参数的类型和形式参数的类型可能不匹配 \ No newline at end of file +對象類型被推斷為盡可能小。 另一方面,子例程推斷實現存在的類型 +因此,實際參數的類型和形式參數的類型可能不匹配 \ No newline at end of file diff --git a/doc/zh_TW/compiler/inference.md b/doc/zh_TW/compiler/inference.md index d40a5298..979baebf 100644 --- a/doc/zh_TW/compiler/inference.md +++ b/doc/zh_TW/compiler/inference.md @@ -1,8 +1,8 @@ -# 类型推断算法 +# 類型推斷算法 -> __Warning__:此部分正在编辑中,可能包含一些错误 +> __Warning__:此部分正在編輯中,可能包含一些錯誤 -显示了下面使用的符号 +顯示了下面使用的符號 ```python Free type variables (type, unbound): ?T, ?U, ... @@ -12,7 +12,7 @@ Type assignment rule (S): { ?T --> T, ... } Type argument evaluation environment (E): { e -> e', ... } ``` -我们以下面的代码为例: +我們以下面的代碼為例: ```python v = ![] @@ -20,51 +20,51 @@ v.push! 1 print! v ``` -Erg 的类型推断主要使用 Hindley-Milner 类型推断算法(尽管已经进行了各种扩展)。具体而言,类型推断是通过以下过程执行的。术语将在后面解释。 +Erg 的類型推斷主要使用 Hindley-Milner 類型推斷算法(盡管已經進行了各種擴展)。具體而言,類型推斷是通過以下過程執行的。術語將在后面解釋。 -1. 推断右值的类型(搜索) -2. 实例化结果类型 -3. 如果是调用,执行类型替换(substitute) -4. 解决已经单态化的特征 -5. 如果有类型变量值,求值/归约(eval) -6. 删除链接类型变量(deref) -7. 传播可变依赖方法的变化 -8. 如果有左值并且是Callable,则泛化参数类型(generalize) -9. 如果有左值,对(返回值)类型进行泛化(generalize) -10. 如果是赋值,则在符号表(`Context`)中注册类型信息(更新) +1. 推斷右值的類型(搜索) +2. 實例化結果類型 +3. 如果是調用,執行類型替換(substitute) +4. 解決已經單態化的特征 +5. 如果有類型變量值,求值/歸約(eval) +6. 刪除鏈接類型變量(deref) +7. 傳播可變依賴方法的變化 +8. 如果有左值并且是Callable,則泛化參數類型(generalize) +9. 如果有左值,對(返回值)類型進行泛化(generalize) +10. 如果是賦值,則在符號表(`Context`)中注冊類型信息(更新) -具体操作如下。 +具體操作如下。 第 1 行。 Def{sig: v, block: ![]} - 获取块类型: - 获取 UnaryOp 类型: - getArray 类型:`['T; 0]` - 实例化:`[?T; 0]` - (替代,评估被省略) + 獲取塊類型: + 獲取 UnaryOp 類型: + getArray 類型:`['T; 0]` + 實例化:`[?T; 0]` + (替代,評估被省略) 更新:`Γ: {v: [?T; 0]!}` - 表达式 返回`NoneType`:OK + 表達式 返回`NoneType`:OK 第 2 行 CallMethod {obj: v, name: push!, args: [1]} - 获取 obj 类型:`Array!(?T, 0)` + 獲取 obj 類型:`Array!(?T, 0)` 搜索:`Γ Array!(?T, 0).push!({1})` 得到:`= Array!('T ~> 'T, 'N ~> 'N+1).push!('T) => NoneType` - 实例化:`Array!(?T, ?N).push!(?T) => NoneType` + 實例化:`Array!(?T, ?N).push!(?T) => NoneType` 替代(`S: {?T --> Nat, ?N --> 0}`): `Array!(Nat ~> Nat, 0 ~> 0+1).push!(Nat) => NoneType` - 评估: `Array!(Nat, 0 ~> 1).push!({1}) => NoneType` + 評估: `Array!(Nat, 0 ~> 1).push!({1}) => NoneType` 更新:`Γ:{v:[Nat; 1]!}` - 表达式 返回`NoneType`:OK + 表達式 返回`NoneType`:OK -第 3 行。调用 {obj: print!, args: [v]} - 获取参数类型:`[[Nat; 1]!]` - 获取 obj 类型: +第 3 行。調用 {obj: print!, args: [v]} + 獲取參數類型:`[[Nat; 1]!]` + 獲取 obj 類型: 搜索:`Γ print!([Nat; 1]!)` 得到:`= print!(...Object) => NoneType` - 表达式 返回`NoneType`:OK + 表達式 返回`NoneType`:OK -## 类型变量的实现 +## 類型變量的實現 -类型变量最初在 [ty.rs](../../src/common/ty.rs) 的 `Type` 中表示如下。它现在以不同的方式实现,但本质上是相同的想法,所以我将以更天真的方式考虑这种实现。 -`RcCell` 是 `Rc>` 的包装类型。 +類型變量最初在 [ty.rs](../../src/common/ty.rs) 的 `Type` 中表示如下。它現在以不同的方式實現,但本質上是相同的想法,所以我將以更天真的方式考慮這種實現。 +`RcCell` 是 `Rc>` 的包裝類型。 ```rust pub enum Type { @@ -74,78 +74,78 @@ pub enum Type { } ``` -类型变量可以通过将实体类型保存在外部字典中来实现,并且类型变量本身只有它的键。但是,据说使用 `RcCell` 的实现通常更有效(需要验证,[来源](https://mobile.twitter.com/bd_gfngfn/status/1296719625086877696?s=21))。 +類型變量可以通過將實體類型保存在外部字典中來實現,并且類型變量本身只有它的鍵。但是,據說使用 `RcCell` 的實現通常更有效(需要驗證,[來源](https://mobile.twitter.com/bd_gfngfn/status/1296719625086877696?s=21))。 -类型变量首先被初始化为 `Type::Var(RcCell::new(None))`。 -当分析代码并确定类型时,会重写此类型变量。 -如果内容直到最后都保持为 None ,它将是一个无法确定为具体类型的类型变量(当场)。例如,具有 `id x = x` 的 `x` 类型。 -我将这种状态下的类型变量称为 __Unbound 类型变量__(我不知道确切的术语)。另一方面,我们将分配了某种具体类型的变量称为 __Linked 类型变量__。 +類型變量首先被初始化為 `Type::Var(RcCell::new(None))`。 +當分析代碼并確定類型時,會重寫此類型變量。 +如果內容直到最后都保持為 None ,它將是一個無法確定為具體類型的類型變量(當場)。例如,具有 `id x = x` 的 `x` 類型。 +我將這種狀態下的類型變量稱為 __Unbound 類型變量__(我不知道確切的術語)。另一方面,我們將分配了某種具體類型的變量稱為 __Linked 類型變量__。 -两者都是自由类型变量(该术语显然以“自由变量”命名)。这些是编译器用于推理的类型变量。它之所以有这样一个特殊的名字,是因为它不同于程序员指定类型的类型变量,例如 `id: 'T -> 'T` 中的 `'T`。 +兩者都是自由類型變量(該術語顯然以“自由變量”命名)。這些是編譯器用于推理的類型變量。它之所以有這樣一個特殊的名字,是因為它不同于程序員指定類型的類型變量,例如 `id: 'T -> 'T` 中的 `'T`。 -未绑定类型变量表示为`?T`、`?U`。在类型论的上下文中,经常使用 α 和 β,但这一种是用来简化输入的。 -请注意,这是出于一般讨论目的而采用的表示法,实际上并未使用字符串标识符实现。 +未綁定類型變量表示為`?T`、`?U`。在類型論的上下文中,經常使用 α 和 β,但這一種是用來簡化輸入的。 +請注意,這是出于一般討論目的而采用的表示法,實際上并未使用字符串標識符實現。 -进入类型环境时,未绑定的类型变量 `Type::Var` 被替换为 `Type::MonoQuantVar`。这称为 __quantified 类型变量__。这类似于程序员指定的类型变量,例如“T”。内容只是一个字符串,并没有像自由类型变量那样链接到具体类型的工具。 +進入類型環境時,未綁定的類型變量 `Type::Var` 被替換為 `Type::MonoQuantVar`。這稱為 __quantified 類型變量__。這類似于程序員指定的類型變量,例如“T”。內容只是一個字符串,并沒有像自由類型變量那樣鏈接到具體類型的工具。 -用量化类型变量替换未绑定类型变量的操作称为__generalization__(或泛化)。如果将其保留为未绑定类型变量,则类型将通过一次调用固定(例如,调用 `id True` 后,`id 1` 的返回类型将是 `Bool`),所以它必须是概括的。 -以这种方式,在类型环境中注册了包含量化类型变量的通用定义。 +用量化類型變量替換未綁定類型變量的操作稱為__generalization__(或泛化)。如果將其保留為未綁定類型變量,則類型將通過一次調用固定(例如,調用 `id True` 后,`id 1` 的返回類型將是 `Bool`),所以它必須是概括的。 +以這種方式,在類型環境中注冊了包含量化類型變量的通用定義。 -## 概括、类型方案、具体化 +## 概括、類型方案、具體化 -让我们将未绑定类型变量 `?T` 泛化为 `gen` 的操作表示。令生成的广义类型变量为 `|T: Type| T`。 -在类型论中,量化类型,例如多相关类型 `α->α`,通过在它们前面加上 `∀α.` 来区分(像 ∀ 这样的符号称为(通用)量词。)。 -这样的表示(例如`∀α.α->α`)称为类型方案。 Erg 中的类型方案表示为 `|T: Type| T -> T`。 -类型方案通常不被认为是一流的类型。以这种方式配置类型系统可以防止类型推断起作用。但是,在Erg中,在一定条件下可以算是一流的类型。有关详细信息,请参阅 [rank2 类型](../syntax/type/advanced/rank2type.md)。 +讓我們將未綁定類型變量 `?T` 泛化為 `gen` 的操作表示。令生成的廣義類型變量為 `|T: Type| T`。 +在類型論中,量化類型,例如多相關類型 `α->α`,通過在它們前面加上 `?α.` 來區分(像 ? 這樣的符號稱為(通用)量詞。)。 +這樣的表示(例如`?α.α->α`)稱為類型方案。 Erg 中的類型方案表示為 `|T: Type| T -> T`。 +類型方案通常不被認為是一流的類型。以這種方式配置類型系統可以防止類型推斷起作用。但是,在Erg中,在一定條件下可以算是一流的類型。有關詳細信息,請參閱 [rank2 類型](../syntax/type/advanced/rank2type.md)。 -现在,当在使用它的类型推断(例如,`id 1`,`id True`)中使用获得的类型方案(例如`'T -> 'T(id's type scheme)`)时,必须释放generalize。这种逆变换称为 __instantiation__。我们将调用操作`inst`。 +現在,當在使用它的類型推斷(例如,`id 1`,`id True`)中使用獲得的類型方案(例如`'T -> 'T(id's type scheme)`)時,必須釋放generalize。這種逆變換稱為 __instantiation__。我們將調用操作`inst`。 ```python gen ?T = 'T -inst 'T = ?T (?T ∉ Γ) +inst 'T = ?T (?T ? Γ) ``` -重要的是,这两个操作都替换了所有出现的类型变量。 例如,如果你实例化 `'T -> 'T`,你会得到 `?T -> ?T`。 -实例化需要替换 dict,但为了泛化,只需将 `?T` 与 `'T` 链接以替换它。 +重要的是,這兩個操作都替換了所有出現的類型變量。 例如,如果你實例化 `'T -> 'T`,你會得到 `?T -> ?T`。 +實例化需要替換 dict,但為了泛化,只需將 `?T` 與 `'T` 鏈接以替換它。 -之后,给出参数的类型以获取目标类型。 此操作称为类型替换,将用 `subst` 表示。 -此外,如果表达式是调用,则获取返回类型的操作表示为 `subst_call_ret`。 第一个参数是参数类型列表,第二个参数是要分配的类型。 +之后,給出參數的類型以獲取目標類型。 此操作稱為類型替換,將用 `subst` 表示。 +此外,如果表達式是調用,則獲取返回類型的操作表示為 `subst_call_ret`。 第一個參數是參數類型列表,第二個參數是要分配的類型。 -类型替换规则 `{?T --> X}` 意味着将 `?T` 和 `X` 重写为相同类型。 此操作称为 __Unification__。 `X` 也可以是类型变量。 -[单独部分](./unification.md) 中描述了详细的统一算法。 我们将统一操作表示为“统一”。 +類型替換規則 `{?T --> X}` 意味著將 `?T` 和 `X` 重寫為相同類型。 此操作稱為 __Unification__。 `X` 也可以是類型變量。 +[單獨部分](./unification.md) 中描述了詳細的統一算法。 我們將統一操作表示為“統一”。 ```python unify(?T, Int) == Ok(()) # ?T == (Int) -# S为类型分配规则,T为适用类型 +# S為類型分配規則,T為適用類型 subst(S: {?T --> X}, T: ?T -> ?T) == X -> X # Type assignment rules are {?T --> X, ?U --> T} subst_call_ret([X, Y], (?T, ?U) -> ?U) == Y ``` -## 半统一(semi-unification) +## 半統一(semi-unification) -统一的一种变体称为半统一(__Semi-unification__)。 这是更新类型变量约束以满足子类型关系的操作。 -在某些情况下,类型变量可能是统一的,也可能不是统一的,因此称为“半”统一。 +統一的一種變體稱為半統一(__Semi-unification__)。 這是更新類型變量約束以滿足子類型關系的操作。 +在某些情況下,類型變量可能是統一的,也可能不是統一的,因此稱為“半”統一。 -例如,在参数分配期间会发生半统一。 -因为实际参数的类型必须是形式参数类型的子类型。 -如果参数类型是类型变量,我们需要更新子类型关系以满足它。 +例如,在參數分配期間會發生半統一。 +因為實際參數的類型必須是形式參數類型的子類型。 +如果參數類型是類型變量,我們需要更新子類型關系以滿足它。 ```python -# 如果形参类型是T +# 如果形參類型是T f(x: T): T = ... a: U -# 必须为 U <: T,否则类型错误 +# 必須為 U <: T,否則類型錯誤 f(a) ``` ## 泛化 -泛化不是一项简单的任务。 当涉及多个作用域时,类型变量的“级别管理”就变得很有必要了。 -为了看到层级管理的必要性,我们首先确认没有层级管理的类型推断会导致问题。 -推断以下匿名函数的类型。 +泛化不是一項簡單的任務。 當涉及多個作用域時,類型變量的“級別管理”就變得很有必要了。 +為了看到層級管理的必要性,我們首先確認沒有層級管理的類型推斷會導致問題。 +推斷以下匿名函數的類型。 ```python x -> @@ -153,8 +153,8 @@ x -> y ``` -首先,Erg 分配类型变量如下: -y 的类型也是未知的,但暂时未分配。 +首先,Erg 分配類型變量如下: +y 的類型也是未知的,但暫時未分配。 ```python x(: ?T) -> @@ -162,8 +162,8 @@ x(: ?T) -> y ``` -首先要确定的是右值 x 的类型。 右值是一种“用途”,因此我们将其具体化。 -但是 x 的类型 `?T` 已经被实例化了,因为它是一个自由变量。 Yo`?T` 成为右值的类型。 +首先要確定的是右值 x 的類型。 右值是一種“用途”,因此我們將其具體化。 +但是 x 的類型 `?T` 已經被實例化了,因為它是一個自由變量。 Yo`?T` 成為右值的類型。 ```python x(: ?T) -> @@ -171,7 +171,7 @@ x(: ?T) -> y ``` -注册为左值 y 的类型时进行泛化。 然而,正如我们稍后将看到的,这种概括是不完善的,并且会产生错误的结果。 +注冊為左值 y 的類型時進行泛化。 然而,正如我們稍后將看到的,這種概括是不完善的,并且會產生錯誤的結果。 ```python x(: ?T) -> @@ -185,7 +185,7 @@ x(: ?T) -> y ``` -y 的类型现在是一个量化类型变量“T”。 在下一行中,立即使用 `y`。 具体的。 +y 的類型現在是一個量化類型變量“T”。 在下一行中,立即使用 `y`。 具體的。 ```python x: ?T -> @@ -193,7 +193,7 @@ x: ?T -> y(: inst 'T) ``` -请注意,实例化必须创建一个与任何已经存在的(自由)类型变量不同的(自由)类型变量(概括类似)。 这样的类型变量称为新类型变量。 +請注意,實例化必須創建一個與任何已經存在的(自由)類型變量不同的(自由)類型變量(概括類似)。 這樣的類型變量稱為新類型變量。 ```python x: ?T -> @@ -201,20 +201,20 @@ x: ?T -> y(: ?U) ``` -并查看生成的整个表达式的类型。 `?T -> ?U`。 -但显然这个表达式应该是`?T -> ?T`,所以我们知道推理有问题。 -发生这种情况是因为我们没有“级别管理”类型变量。 +并查看生成的整個表達式的類型。 `?T -> ?U`。 +但顯然這個表達式應該是`?T -> ?T`,所以我們知道推理有問題。 +發生這種情況是因為我們沒有“級別管理”類型變量。 -所以我们用下面的符号来介绍类型变量的层次。 级别表示为自然数。 +所以我們用下面的符號來介紹類型變量的層次。 級別表示為自然數。 ```python -# 普通类型变量 +# 普通類型變量 ?T<1>, ?T<2>, ... -# 具有子类型约束的类型变量 +# 具有子類型約束的類型變量 ?T<1>(<:U) or ?T(<:U)<1>, ... ``` -让我们再尝试一次: +讓我們再嘗試一次: ```python x -> @@ -222,8 +222,8 @@ x -> y ``` -首先,按如下方式分配一个 leveled 类型变量: toplevel 级别为 1。随着范围的加深,级别增加。 -函数参数属于内部范围,因此它们比函数本身高一级。 +首先,按如下方式分配一個 leveled 類型變量: toplevel 級別為 1。隨著范圍的加深,級別增加。 +函數參數屬于內部范圍,因此它們比函數本身高一級。 ```python # level 1 @@ -233,7 +233,7 @@ x (: ?T<2>) -> y ``` -首先,实例化右值`x`。和以前一样,没有任何改变。 +首先,實例化右值`x`。和以前一樣,沒有任何改變。 ```python x (: ?T<2>) -> @@ -241,9 +241,9 @@ x (: ?T<2>) -> y ``` -这是关键。 这是分配给左值`y`的类型时的概括。 -早些时候,这里的结果很奇怪,所以我们将改变泛化算法。 -如果类型变量的级别小于或等于当前范围的级别,则泛化使其保持不变。 +這是關鍵。 這是分配給左值`y`的類型時的概括。 +早些時候,這里的結果很奇怪,所以我們將改變泛化算法。 +如果類型變量的級別小于或等于當前范圍的級別,則泛化使其保持不變。 ```python gen ?T = if n <= current_level, then= ?T, else= 'T @@ -265,7 +265,7 @@ x (: ?T<2>) -> y ``` -y 的类型现在是一个未绑定的类型变量 `?T<2>`。 具体如下几行:但是 `y` 的类型没有被概括,所以什么也没有发生 +y 的類型現在是一個未綁定的類型變量 `?T<2>`。 具體如下幾行:但是 `y` 的類型沒有被概括,所以什么也沒有發生 ```python x (: ?T<2>) -> @@ -279,9 +279,9 @@ x (: ?T<2>) -> y (: ?T<2>) ``` -我们成功获得了正确的类型`?T<2> -> ?T<2>`。 +我們成功獲得了正確的類型`?T<2> -> ?T<2>`。 -让我们看另一个例子。 这是更一般的情况,具有函数/运算符应用程序和前向引用。 +讓我們看另一個例子。 這是更一般的情況,具有函數/運算符應用程序和前向引用。 ```python fx, y = id(x) + y @@ -290,11 +290,11 @@ id x = x f10,1 ``` -让我们逐行浏览它。 +讓我們逐行瀏覽它。 -在 `f` 的推断过程中,会引用后面定义的函数常量 `id`。 -在这种情况下,在 `f` 之前插入一个假设的 `id` 声明,并为其分配一个自由类型变量。 -注意此时类型变量的级别是`current_level`。 这是为了避免在其他函数中泛化。 +在 `f` 的推斷過程中,會引用后面定義的函數常量 `id`。 +在這種情況下,在 `f` 之前插入一個假設的 `id` 聲明,并為其分配一個自由類型變量。 +注意此時類型變量的級別是`current_level`。 這是為了避免在其他函數中泛化。 ```python id: ?T<1> -> ?U<1> @@ -302,11 +302,11 @@ f x (: ?V<2>), y (: ?W<2>) = id(x) (: subst_call_ret([inst ?V<2>], inst ?T<1> -> ?U<1>)) + y ``` -类型变量之间的统一将高级类型变量替换为低级类型变量。 -如果级别相同,则无所谓。 +類型變量之間的統一將高級類型變量替換為低級類型變量。 +如果級別相同,則無所謂。 -类型变量之间的半统一有点不同。 -不同级别的类型变量不得相互施加类型约束。 +類型變量之間的半統一有點不同。 +不同級別的類型變量不得相互施加類型約束。 ```python # BAD @@ -316,9 +316,9 @@ f x (: ?V<2>), y (: ?W<2>) = id(x) (: ?U<1>) + y (: ?W<2>) ``` -这使得无法确定在何处实例化类型变量。 -对于 Type 类型变量,执行正常统一而不是半统一。 -也就是说,统一到下层。 +這使得無法確定在何處實例化類型變量。 +對于 Type 類型變量,執行正常統一而不是半統一。 +也就是說,統一到下層。 ```python # OK @@ -363,7 +363,7 @@ f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) = id(x) + x ``` -定义时,提高层次,使其可以泛化。 +定義時,提高層次,使其可以泛化。 ```python # ?T<1 -> 2> @@ -371,7 +371,7 @@ f(x, y) (: |'W: Type| (?T<1>, 'W) -> ?U<1>(<: Add(?W<2>)).AddO) = id x (: ?T<2>) -> ?U<2> = x (: inst ?T<2>) ``` -如果已经分配了返回类型,则与结果类型统一(`?U<2> --> ?T<2>`)。 +如果已經分配了返回類型,則與結果類型統一(`?U<2> --> ?T<2>`)。 ```python # ?U<2> --> ?T<2> @@ -381,9 +381,9 @@ 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>) ``` -如果类型变量已经被实例化为一个简单的类型变量, -依赖于它的类型变量也将是一个 Type 类型变量。 -广义类型变量对于每个函数都是独立的。 +如果類型變量已經被實例化為一個簡單的類型變量, +依賴于它的類型變量也將是一個 Type 類型變量。 +廣義類型變量對于每個函數都是獨立的。 ```python f(x, y) (: |'W: Type, 'T <: Add('W)| ('T, 'W) -> 'T.AddO) = @@ -403,7 +403,7 @@ f(10, 1) (: subst_call_ret([inst {10}, inst {1}], inst |'W: Type, 'T <: Add('W)| f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<1>) -> ? T<1>.AddO)) ``` -类型变量绑定到具有实现的最小类型 +類型變量綁定到具有實現的最小類型 ```python # ?T(:> {10} <: Add(?W<1>))<1> @@ -411,15 +411,15 @@ f(10, 1) (: subst_call_ret([inst {10}, inst {1}], (?T<1>(<: Add(?W<1>)), ?W<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 相对于第一个参数是协变的 +# 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 # 如果只有一个候选人,完成评估 +# ?T(:> ?W(:> {10}) or {1}, <: Nat).AddO == Nat # 如果只有一個候選人,完成評估 f(10, 1) (: (?W(:> {10}, <: Nat), ?W(:> {1})) -> Nat) -# 程序到此结束,所以去掉类型变量 +# 程序到此結束,所以去掉類型變量 f(10, 1) (: ({10}, {1}) -> Nat) ``` -整个程序的结果类型是: +整個程序的結果類型是: ```python f|W: Type, T <: Add(W)|(x: T, y: W): T.AddO = id(x) + y @@ -428,7 +428,7 @@ id|T: Type|(x: T): T = x f(10, 1): Nat ``` -我还重印了原始的、未明确键入的程序。 +我還重印了原始的、未明確鍵入的程序。 ```python fx, y = id(x) + y diff --git a/doc/zh_TW/compiler/overview.md b/doc/zh_TW/compiler/overview.md index e5e5c7f8..8d7d86c8 100644 --- a/doc/zh_TW/compiler/overview.md +++ b/doc/zh_TW/compiler/overview.md @@ -1,36 +1,36 @@ -# `erg` 概览 +# `erg` 概覽 -我们将介绍每一层的功能以及特别重要的功能和方法。 +我們將介紹每一層的功能以及特別重要的功能和方法。 -## 1. 词法分析 +## 1. 詞法分析 -* `Lexer` 进行词法分析。 `Lexer::next`(`Lexer`被实现为一个迭代器)负责词法分析的主要逻辑。 `Token` 作为解析的结果输出。 +* `Lexer` 進行詞法分析。 `Lexer::next`(`Lexer`被實現為一個迭代器)負責詞法分析的主要邏輯。 `Token` 作為解析的結果輸出。 ## 2. 解析 -* `Parser` 进行解析。特别重要的是`Parser::parse_expr`。作为解析的结果,输出作为`ast::Expr`的集合的`AST`。 +* `Parser` 進行解析。特別重要的是`Parser::parse_expr`。作為解析的結果,輸出作為`ast::Expr`的集合的`AST`。 -## 3. 脱糖 +## 3. 脫糖 -* 脱糖由 `Desugarer` 完成。 `AST` 将被输出。 +* 脫糖由 `Desugarer` 完成。 `AST` 將被輸出。 -## 4. 类型检查/类型推断 +## 4. 類型檢查/類型推斷 -* `ASTLowerer` 进行打字。类型检查主要由 `Context` 完成。尤其重要的是 `Context::supertype_of`(确定子类型关系)、`Context::unify/sub_unify`(统一/半统一类型变量)、`Context::init_builtin_*`(定义内置 API)。 `HIR` 作为分析结果输出。 +* `ASTLowerer` 進行打字。類型檢查主要由 `Context` 完成。尤其重要的是 `Context::supertype_of`(確定子類型關系)、`Context::unify/sub_unify`(統一/半統一類型變量)、`Context::init_builtin_*`(定義內置 API)。 `HIR` 作為分析結果輸出。 -## 5. 副作用检查 +## 5. 副作用檢查 * `SideEffectChecker` 可以。 -## 6. 所有权检查 +## 6. 所有權檢查 * `OwnershipChecker` 可以。 -## 7. 字节码生成 +## 7. 字節碼生成 -* `CodeGenerator` 将 `HIR` 转换为 `CodeObj`。 `CodeObj` 保存字节码和执行配置。特别重要的是`CodeGenerator::compile_expr`。 +* `CodeGenerator` 將 `HIR` 轉換為 `CodeObj`。 `CodeObj` 保存字節碼和執行配置。特別重要的是`CodeGenerator::compile_expr`。 --- -* 以上所有的处理都是由`Compiler`作为一个门面组合起来的。 -* 当然 Python 会执行生成的字节码,称为 `DummyVM`。 \ No newline at end of file +* 以上所有的處理都是由`Compiler`作為一個門面組合起來的。 +* 當然 Python 會執行生成的字節碼,稱為 `DummyVM`。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/parsing.md b/doc/zh_TW/compiler/parsing.md index aa540a33..501e2bf8 100644 --- a/doc/zh_TW/compiler/parsing.md +++ b/doc/zh_TW/compiler/parsing.md @@ -1,9 +1,9 @@ -# 解析 Erg 语言 +# 解析 Erg 語言 -## 空格的处理 +## 空格的處理 -Erg语法的一个特点是它对空间敏感。 -这是为了弥补因省略`()`而造成的表达力损失。在 Nim 中可以找到类似的语法,它也允许省略 `()`。 +Erg語法的一個特點是它對空間敏感。 +這是為了彌補因省略`()`而造成的表達力損失。在 Nim 中可以找到類似的語法,它也允許省略 `()`。 ```python f +1 == f(+1) @@ -16,18 +16,18 @@ f(1,) == f(1) ## 左值,右值 -在 Erg 中,左侧的值并不像 `=` 的左侧那么简单。 -事实上,`=` 左侧有一个右值(非常令人困惑),而 `=` 右侧有一个左值。 +在 Erg 中,左側的值并不像 `=` 的左側那么簡單。 +事實上,`=` 左側有一個右值(非常令人困惑),而 `=` 右側有一個左值。 右值中甚至可以有左值。 ```python -# i 是左边的值,Array(Int) 和 [1, 2, 3] 是右边的值 +# i 是左邊的值,Array(Int) 和 [1, 2, 3] 是右邊的值 i: Array(Int) = [1, 2, 3] -# `[1, 2, 3].iter().map i -> i + 1`是右边的值,但是->左边的i是左边的值 +# `[1, 2, 3].iter().map i -> i + 1`是右邊的值,但是->左邊的i是左邊的值 a = [1, 2, 3].iter().map i -> i + 1 -# {x = 1; y = 2} 是右侧值,但 x, y 是左侧值 +# {x = 1; y = 2} 是右側值,但 x, y 是左側值 r = {x = 1; y = 2} ``` -左侧和右侧值的精确定义是“如果它是可评估的,则为右侧值,否则为左侧值”。 -例如,考虑代码 ``i = 1; i``,其中第二个 `i` 是右侧值,因为它是可评估的,但第一个 `i` 是左侧值。 \ No newline at end of file +左側和右側值的精確定義是“如果它是可評估的,則為右側值,否則為左側值”。 +例如,考慮代碼 ``i = 1; i``,其中第二個 `i` 是右側值,因為它是可評估的,但第一個 `i` 是左側值。 \ No newline at end of file diff --git a/doc/zh_TW/compiler/refinement_subtyping.md b/doc/zh_TW/compiler/refinement_subtyping.md index 631a9da8..aa0cf9ba 100644 --- a/doc/zh_TW/compiler/refinement_subtyping.md +++ b/doc/zh_TW/compiler/refinement_subtyping.md @@ -1,4 +1,4 @@ -# 筛子类型 +# 篩子類型 ```python {I: Int | I >= 0} @@ -6,11 +6,11 @@ {T: (Ratio, Ratio) | T.0 >= 0; T.1 >= 0} ``` -Erg 通过将 Enum 和 Interval 类型转换为筛选类型来实现类型确定。 +Erg 通過將 Enum 和 Interval 類型轉換為篩選類型來實現類型確定。 -## 转换为筛型 +## 轉換為篩型 -在 [Sieve types] 一节中,我们说过区间类型和枚举类型是 sieve 类型的语法糖。每个转换如下。 +在 [Sieve types] 一節中,我們說過區間類型和枚舉類型是 sieve 類型的語法糖。每個轉換如下。 * {0} -> {I: Int | I == 0} * {0, 1} -> {I: Int | I == 0 or I == 1} @@ -21,36 +21,36 @@ Erg 通过将 Enum 和 Interval 类型转换为筛选类型来实现类型确定 * {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 的子类型的算法。正式地,(所有)子类型定义如下: +描述了一種用于確定篩類型 A 是否是另一篩類型 B 的子類型的算法。正式地,(所有)子類型定義如下: ```console -A <: B <=> ∀a∈A; a∈B +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 @@ -67,29 +67,29 @@ A <: B <=> ∀a∈A; a∈B * {I >= l} <: {I <= r} = False * {I <= l} <: {I >= r} = False -布尔表达式的简化规则如下。 min, max 不能被删除。此外,多个 or, and 被转换为嵌套的 min, max。 +布爾表達式的簡化規則如下。 min, max 不能被刪除。此外,多個 or, and 被轉換為嵌套的 min, max。 -* 组合规则 +* 組合規則 * `I == a` => `I >= a 和 I <= a` * `i != a` => `I >= a+1 或 I <= a-1` -* 一致性规则 +* 一致性規則 * `I >= a 或 I <= b (a < b)` == `{...}` -* 恒常规则 +* 恒常規則 * `I >= a 和 I <= b (a > b)` == `{}` -* 替换规则 - * 以 `I >= n` 和 `I <= n` 的顺序替换顺序表达式。 -* 扩展规则 +* 替換規則 + * 以 `I >= n` 和 `I <= n` 的順序替換順序表達式。 +* 擴展規則 * `I == n 或 I >= n+1` => `I >= n` * `I == n 或 I <= n-1` => `I <= n` -* 最大规则 +* 最大規則 * `I <= m 或 I <= n` => `I <= max(m, n)` * `I >= m 和 I >= n` => `I >= max(m, n)` -* 最低规则 +* 最低規則 * `I >= m 或 I >= n` => `I >= min(m, n)` * `I <= m 和 I <= n` => `I <= min(m, n)` -* 淘汰规则 - * 当 `I >= a (n >= a)` 或 `I <= b (n <= b)` 或 `I == n` 在右侧时,左侧的 `I == n` 被删除能够。 - * 如果无法消除所有左手方程,则为 False +* 淘汰規則 + * 當 `I >= a (n >= a)` 或 `I <= b (n <= b)` 或 `I == n` 在右側時,左側的 `I == n` 被刪除能夠。 + * 如果無法消除所有左手方程,則為 False 例如 diff --git a/doc/zh_TW/compiler/trait_method_resolving.md b/doc/zh_TW/compiler/trait_method_resolving.md index 66574713..1f3a6f88 100644 --- a/doc/zh_TW/compiler/trait_method_resolving.md +++ b/doc/zh_TW/compiler/trait_method_resolving.md @@ -1,31 +1,31 @@ -# 解决补丁方法 +# 解決補丁方法 -`Nat` 是零个或多个`Int`,`Int` 的子类型。 -`Nat` 在 Python 类层次结构中不存在。 我想知道 Erg 是如何解决这个补丁方法的? +`Nat` 是零個或多個`Int`,`Int` 的子類型。 +`Nat` 在 Python 類層次結構中不存在。 我想知道 Erg 是如何解決這個補丁方法的? ```python 1.times do: log "hello world" ``` -`.times` 是一种 `NatImpl` 补丁方法。 -由于`1`是`Int`的一个实例,首先通过跟踪`Int`的MRO(方法解析顺序)来搜索它。 -Erg 在 `Int` 的 MRO 中有 `Int`、`Object`。它来自 Python(Python 中的`int.__mro__ == [int, object]`)。 -`.times` 方法在它们中都不存在。现在让我们探索那个子类型。 +`.times` 是一種 `NatImpl` 補丁方法。 +由于`1`是`Int`的一個實例,首先通過跟蹤`Int`的MRO(方法解析順序)來搜索它。 +Erg 在 `Int` 的 MRO 中有 `Int`、`Object`。它來自 Python(Python 中的`int.__mro__ == [int, object]`)。 +`.times` 方法在它們中都不存在。現在讓我們探索那個子類型。 ~ -整数显然应该在其超类型中包含实数、复数甚至整数,但这一事实并没有出现在 Python 兼容层中。 -然而,`1 in Complex` 和 `1 in Num` 在 Erg 中实际上是 `True`。 -至于`Complex`,即使是与`Int`没有继承关系的类,也被判断为类型兼容。这到底是怎么回事? +整數顯然應該在其超類型中包含實數、復數甚至整數,但這一事實并沒有出現在 Python 兼容層中。 +然而,`1 in Complex` 和 `1 in Num` 在 Erg 中實際上是 `True`。 +至于`Complex`,即使是與`Int`沒有繼承關系的類,也被判斷為類型兼容。這到底是怎么回事? ~ -一个对象有无数种它所属的类型。 -但是我们真的只需要考虑带有方法的类型,即带有名称的类型。 +一個對象有無數種它所屬的類型。 +但是我們真的只需要考慮帶有方法的類型,即帶有名稱的類型。 -Erg 编译器有一个补丁类型的哈希图,其中包含所有提供的方法及其实现。 -每次定义新类型时都会更新此表。 +Erg 編譯器有一個補丁類型的哈希圖,其中包含所有提供的方法及其實現。 +每次定義新類型時都會更新此表。 ```python provided_method_table = { @@ -37,47 +37,47 @@ provided_method_table = { } ``` -具有 `.times` 方法的类型是 `Nat`、`Foo`。从这些中,找到与“{1}”类型匹配的一个。 -有两种类型的符合性确定。它们是筛式判断和记录式判断。这是通过筛子类型确定来完成的。 +具有 `.times` 方法的類型是 `Nat`、`Foo`。從這些中,找到與“{1}”類型匹配的一個。 +有兩種類型的符合性確定。它們是篩式判斷和記錄式判斷。這是通過篩子類型確定來完成的。 -##筛型确定 +##篩型確定 -检查候选类型是否与 `1` 的类型 `{1}` 兼容。与“{1}”兼容的筛子类型有“{0, 1}”、“0..9”等。 -有限元代数类型,例如 `0..1 或 3..4`、`-1..2 和 0..3`,在声明为基本类型(即 {0, 1, 3, 4}`,`{0, 1, 2}`)。 -在这种情况下,`Nat` 是 `0.._ == {I: Int | I >= 0}`,所以 `{1}` 与 `Nat` 兼容。 +檢查候選類型是否與 `1` 的類型 `{1}` 兼容。與“{1}”兼容的篩子類型有“{0, 1}”、“0..9”等。 +有限元代數類型,例如 `0..1 或 3..4`、`-1..2 和 0..3`,在聲明為基本類型(即 {0, 1, 3, 4}`,`{0, 1, 2}`)。 +在這種情況下,`Nat` 是 `0.._ == {I: Int | I >= 0}`,所以 `{1}` 與 `Nat` 兼容。 -## 确定记录类型 +## 確定記錄類型 -检查候选类型是否与 `Int` 兼容,1 类。 -其他是`Int`的修复程序并且`Int`具有所有必需属性的也是兼容的。 +檢查候選類型是否與 `Int` 兼容,1 類。 +其他是`Int`的修復程序并且`Int`具有所有必需屬性的也是兼容的。 ~ -所以`Nat`适合。但是,如果 `Foo` 也匹配,则由 `Nat` 和 `Foo` 之间的包含关系决定。 -即,选择子类型方法。 -如果两者之间没有包含关系,则会发生编译错误(这是一种安全措施,防止违背程序员的意图执行方法)。 -要消除错误,您需要明确指定补丁。 +所以`Nat`適合。但是,如果 `Foo` 也匹配,則由 `Nat` 和 `Foo` 之間的包含關系決定。 +即,選擇子類型方法。 +如果兩者之間沒有包含關系,則會發生編譯錯誤(這是一種安全措施,防止違背程序員的意圖執行方法)。 +要消除錯誤,您需要明確指定補丁。 ```python o.method(x) -> P.method(o, x) ``` -## 通用方法解析修补程序 +## 通用方法解析修補程序 -像这样定义一个补丁: +像這樣定義一個補丁: ```python FnType T: Type = Patch T -> T FnType.type = T ``` -在 `FnType` 补丁下可以使用如下代码。 我想知道这将如何解决。 +在 `FnType` 補丁下可以使用如下代碼。 我想知道這將如何解決。 ```python assert (Int -> Int).type == Int ``` -首先,`FnType(T)` 以下列格式注册到`provided_method_table` 中。 +首先,`FnType(T)` 以下列格式注冊到`provided_method_table` 中。 ```python provided_method_table = { @@ -87,8 +87,8 @@ provided_method_table = { } ``` -`FnType(T)` 检查匹配类型。 在这种情况下,`FnType(T)` 补丁类型是 `Type -> Type`。 -这匹配 `Int -> Int`。 如果合适,进行单态化和替换(取 `T -> T` 和 `Int -> Int`、`{T => Int}` 的差异)。 +`FnType(T)` 檢查匹配類型。 在這種情況下,`FnType(T)` 補丁類型是 `Type -> Type`。 +這匹配 `Int -> Int`。 如果合適,進行單態化和替換(取 `T -> T` 和 `Int -> Int`、`{T => Int}` 的差異)。 ```python assert FnType(Int).type == Int diff --git a/doc/zh_TW/compiler/transpile.md b/doc/zh_TW/compiler/transpile.md index 396c72d7..fa0afc6b 100644 --- a/doc/zh_TW/compiler/transpile.md +++ b/doc/zh_TW/compiler/transpile.md @@ -1,15 +1,15 @@ -# Erg 代码如何转译成 Python 代码? +# Erg 代碼如何轉譯成 Python 代碼? -准确地说,Erg 代码被转译为 Python 字节码。 -但是,由于 Python 字节码几乎可以重构为 Python 代码,因此这里以等效的 Python 代码为例。 -顺便说一句,这里展示的示例是低优化级别。 -更高级的优化消除了不需要实例化的东西。 +準確地說,Erg 代碼被轉譯為 Python 字節碼。 +但是,由于 Python 字節碼幾乎可以重構為 Python 代碼,因此這里以等效的 Python 代碼為例。 +順便說一句,這里展示的示例是低優化級別。 +更高級的優化消除了不需要實例化的東西。 -## 记录,记录类型 +## 記錄,記錄類型 -它将被转译为一个命名元组。 -对于 namedtuple,请参阅 [此处](https://docs.python.jp/3/library/collections.html#collections.namedtuple)。 -有一个类似的函数,dataclass,但是由于 `__eq__` 和 `__hash__` 的自动实现,dataclass 的性能略有下降。 +它將被轉譯為一個命名元組。 +對于 namedtuple,請參閱 [此處](https://docs.python.jp/3/library/collections.html#collections.namedtuple)。 +有一個類似的函數,dataclass,但是由于 `__eq__` 和 `__hash__` 的自動實現,dataclass 的性能略有下降。 ```python Employee = Class {.name = Str; .id = Int} @@ -32,16 +32,16 @@ employee = Employee('John Smith', 100) assert employee.name == 'John Smith' ``` -如果可以进一步优化,它也将转换为简单的元组。 +如果可以進一步優化,它也將轉換為簡單的元組。 -## 多态类型 +## 多態類型 > 在制品 -## 即时范围 +## 即時范圍 -如果没有发生命名空间冲突,它只会被破坏和扩展。 -`x::y` 等名称在字节码中使用,不能与 Python 代码关联,但如果强制表示,则会如下所示。 +如果沒有發生命名空間沖突,它只會被破壞和擴展。 +`x::y` 等名稱在字節碼中使用,不能與 Python 代碼關聯,但如果強制表示,則會如下所示。 ```python x = @@ -54,7 +54,7 @@ x::y = 1 x = x::y + 1 ``` -万一发生冲突,定义和使用只能在内部引用的函数。 +萬一發生沖突,定義和使用只能在內部引用的函數。 ```python x = @@ -70,10 +70,10 @@ def _(): x = _() ``` -## 可见性 +## 可見性 -它对公共变量没有任何作用,因为它是 Python 的默认值。 -私有变量由 mangling 处理。 +它對公共變量沒有任何作用,因為它是 Python 的默認值。 +私有變量由 mangling 處理。 ```python x=1 diff --git a/doc/zh_TW/compiler/type_var_normalization.md b/doc/zh_TW/compiler/type_var_normalization.md index fded3f21..cbf621e6 100644 --- a/doc/zh_TW/compiler/type_var_normalization.md +++ b/doc/zh_TW/compiler/type_var_normalization.md @@ -1,30 +1,30 @@ -# 归一化 +# 歸一化 -* Erg 的类型参数规范化基于 SymPy 的简化函数。 +* Erg 的類型參數規范化基于 SymPy 的簡化函數。 -例如,当您定义 `concat: |T, M, N|([T; M], [T; N] -> [T; M+N])` 时,您可以匹配类型变量和参数而无需实例化它们.必须作出判断。 -平等判断自然有其局限性,但目前可能的判断及其方法如下。 +例如,當您定義 `concat: |T, M, N|([T; M], [T; N] -> [T; M+N])` 時,您可以匹配類型變量和參數而無需實例化它們.必須作出判斷。 +平等判斷自然有其局限性,但目前可能的判斷及其方法如下。 -* 加法/乘法对称性: +* 加法/乘法對稱性: `n+m == m+n` - 类型变量被排序和规范化为字符串。 + 類型變量被排序和規范化為字符串。 -* 加法、乘法、减法和除法等价: +* 加法、乘法、減法和除法等價: `n+n == 2*n` - 归一化为 Σ[c] x == c*x,其中 c 是一个常数。 - 常量通过将它们放在二进制操作的左侧进行标准化。 + 歸一化為 Σ[c] x == c*x,其中 c 是一個常數。 + 常量通過將它們放在二進制操作的左側進行標準化。 -* 双重表达式的相等性: +* 雙重表達式的相等性: `n+m+l == m+n+l == l+m+n == ...` `n+m*l == m*l+n` - 通过排序归一化确定。 - 乘法和除法块放置在加法和减法的左侧。通过比较最左侧的类型变量对块进行排序。 + 通過排序歸一化確定。 + 乘法和除法塊放置在加法和減法的左側。通過比較最左側的類型變量對塊進行排序。 * 基本不等式: @@ -34,6 +34,6 @@ `n >= m 和 m >= n -> m == n` -* 不等式的传递性: +* 不等式的傳遞性: `n > 0 -> n > -1` \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/branches.md b/doc/zh_TW/dev_guide/branches.md index c4380f04..599d39a7 100644 --- a/doc/zh_TW/dev_guide/branches.md +++ b/doc/zh_TW/dev_guide/branches.md @@ -1,35 +1,35 @@ -# 分支机构命名和运营策略 +# 分支機構命名和運營策略 ## main -* 主要开发分支 -* 必须满足以下条件 +* 主要開發分支 +* 必須滿足以下條件 -* 编译成功 +* 編譯成功 -## beta(目前不创建) +## beta(目前不創建) * 最新的 Beta 版本 -* 必须满足以下条件 +* 必須滿足以下條件 -* 编译成功 -* 所有测试都会成功 +* 編譯成功 +* 所有測試都會成功 ## feature-* -* 开发特定功能的分支 -* 切开 main +* 開發特定功能的分支 +* 切開 main -* 没有条件 +* 沒有條件 ## issue-* -* 解决特定 issue 的分支 +* 解決特定 issue 的分支 -* 没有条件 +* 沒有條件 ## fix-* -* 修复特定错误的分支(如果该问题是一个错误,则代替`issue-*`创建)。 +* 修復特定錯誤的分支(如果該問題是一個錯誤,則代替`issue-*`創建)。 -* 没有条件。 \ No newline at end of file +* 沒有條件。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/build_features.md b/doc/zh_TW/dev_guide/build_features.md index 0de6c136..1aea65b9 100644 --- a/doc/zh_TW/dev_guide/build_features.md +++ b/doc/zh_TW/dev_guide/build_features.md @@ -1,21 +1,21 @@ -# `erg` 构建功能 +# `erg` 構建功能 -## 调试 +## 調試 -进入调试模式。结果,Erg 内部的行为顺序显示在日志中。 -独立于 Rust 的 `debug_assertions` 标志。 +進入調試模式。結果,Erg 內部的行為順序顯示在日志中。 +獨立于 Rust 的 `debug_assertions` 標志。 ## japanese -将系统语言设置为日语。 -Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为日语。 +將系統語言設置為日語。 +Erg 內部選項、幫助(幫助、版權、許可證等)和錯誤顯示為日語。 ## simplified_chinese -将系统语言设置为简体中文。 -Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为简体中文。 +將系統語言設置為簡體中文。 +Erg 內部選項、幫助(幫助、版權、許可證等)和錯誤顯示為簡體中文。 ## traditional_chinese -将系统语言设置为繁体中文。 -Erg 内部选项、帮助(帮助、版权、许可证等)和错误显示为繁体中文。 \ No newline at end of file +將系統語言設置為繁體中文。 +Erg 內部選項、幫助(幫助、版權、許可證等)和錯誤顯示為繁體中文。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/directories.md b/doc/zh_TW/dev_guide/directories.md index a44615e3..542ae411 100644 --- a/doc/zh_TW/dev_guide/directories.md +++ b/doc/zh_TW/dev_guide/directories.md @@ -1,24 +1,24 @@ -# Erg存储表结构 +# Erg存儲表結構 ```console - └─┬ assets:图片等 - ├─ CODE_OF_CONDUCT:行为准则 + └─┬ assets:圖片等 + ├─ CODE_OF_CONDUCT:行為準則 ├─┬ compiler │ ├─ erg_common:通用工具 │ ├─ erg_compiler │ └─ erg_parser:解析器 - ├─┬ doc: 文档 + ├─┬ doc: 文檔 │ ├─┬ CN - │ │ ├─ API:Erg标准API - │ │ ├─ compiler:关于编译器实现 - │ │ ├─ dev_guide:开发者和贡献者指南 - │ │ ├─ python:Erg开发必备的Python知识 - │ │ ├─ syntax:Erg语法 + │ │ ├─ API:Erg標準API + │ │ ├─ compiler:關于編譯器實現 + │ │ ├─ dev_guide:開發者和貢獻者指南 + │ │ ├─ python:Erg開發必備的Python知識 + │ │ ├─ syntax:Erg語法 │ │ └─ tools:Erg命令行工具 │ └─┬ JA │ ... - ├─ examples:示例代码 - ├─ library:Erg脚本库 - ├─ src:main.rs和驱动所在目录 - └─ tests:测试代码 + ├─ examples:示例代碼 + ├─ library:Erg腳本庫 + ├─ src:main.rs和驅動所在目錄 + └─ tests:測試代碼 ``` \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/doc_guideline.md b/doc/zh_TW/dev_guide/doc_guideline.md index 56899909..9c2e5241 100644 --- a/doc/zh_TW/dev_guide/doc_guideline.md +++ b/doc/zh_TW/dev_guide/doc_guideline.md @@ -1,13 +1,13 @@ # 格式 -任何不符合以下规则的文件都将得到更正。 +任何不符合以下規則的文件都將得到更正。 -* 以某种语气写代码注释或内部文档。 -* 向外部(普通用户)展示的文档应该越来越多地编写。 -* 始终包含定义、含义或文档中首次出现的术语的链接。 -* 仅对理解正文所必需的补充句子使用括号作为附加条件,对于理解正文不是必需的句子使用脚注[1]( #1)。 -* 如果文档内容过时,按照【此方法】更新(https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)。 +* 以某種語氣寫代碼注釋或內部文檔。 +* 向外部(普通用戶)展示的文檔應該越來越多地編寫。 +* 始終包含定義、含義或文檔中首次出現的術語的鏈接。 +* 僅對理解正文所必需的補充句子使用括號作為附加條件,對于理解正文不是必需的句子使用腳注[1]( #1)。 +* 如果文檔內容過時,按照【此方法】更新(https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)。 --- -1 参见这里了解如何编写脚注。[↩](#f1) \ No newline at end of file +1 參見這里了解如何編寫腳注。[?](#f1) \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/env.md b/doc/zh_TW/dev_guide/env.md index 3c98f96d..99679c35 100644 --- a/doc/zh_TW/dev_guide/env.md +++ b/doc/zh_TW/dev_guide/env.md @@ -1,19 +1,19 @@ -# 开发环境 +# 開發環境 -## 你需要安装什么 +## 你需要安裝什么 -* Rust(与 rustup 一起安装) +* Rust(與 rustup 一起安裝) * 版本 >= 1.63.0 * 2021年版 -* [预提交](https://pre-commit.com/) +* [預提交](https://pre-commit.com/) -* Python3 解释器 +* Python3 解釋器 -## 推荐 +## 推薦 -* 编辑器:Visual Studio Code -* VSCode 扩展:Rust-analyzer、GitLens、Git Graph、GitHub Pull Requests and Issues、Markdown All in One、markdownlint -* 操作系统:Windows 10/11 | Ubuntu 20.04/22.04 | Mac OS Monterey +* 編輯器:Visual Studio Code +* VSCode 擴展:Rust-analyzer、GitLens、Git Graph、GitHub Pull Requests and Issues、Markdown All in One、markdownlint +* 操作系統:Windows 10/11 | Ubuntu 20.04/22.04 | Mac OS Monterey * 其他:pyenv、模具 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/faq_syntax.md b/doc/zh_TW/dev_guide/faq_syntax.md index 9ff0b713..af1cb5f9 100644 --- a/doc/zh_TW/dev_guide/faq_syntax.md +++ b/doc/zh_TW/dev_guide/faq_syntax.md @@ -1,31 +1,31 @@ # Erg design's "Why" and Answers -## 当我们有所有权系统时,为什么要与 GC 共存? +## 當我們有所有權系統時,為什么要與 GC 共存? -因为 Erg 推出所有权系统的动机并不是为了 Rust 那样的“不依赖 GC 的内存管理”。最初,由于 Erg 是一种语言,目前使用 Python VM,因此最终仍使用 GC。Erg 引入产权系统的目标是“可变状态的局部化”。在 Erg 中,可变对象具有所有权概念。这是根据共享可变状态容易成为 bug 的温床,甚至是类型安全性的侵犯(详见)来判断的。 +因為 Erg 推出所有權系統的動機并不是為了 Rust 那樣的“不依賴 GC 的內存管理”。最初,由于 Erg 是一種語言,目前使用 Python VM,因此最終仍使用 GC。Erg 引入產權系統的目標是“可變狀態的局部化”。在 Erg 中,可變對象具有所有權概念。這是根據共享可變狀態容易成為 bug 的溫床,甚至是類型安全性的侵犯(詳見)來判斷的。 -## 为什么类型参数周围的括号不是 <> 或 []? +## 為什么類型參數周圍的括號不是 <> 或 []? -因为在和中会发生语法冲突。 +因為在和中會發生語法沖突。 ```python # []版 id[T: Type] [t]: [T] = t -y = id[Int] # 这是一个功能吗? +y = id[Int] # 這是一個功能嗎? # <>版 id {t: T} = t -y = (id 1) # 这是一个元组吗? +y = (id 1) # 這是一個元組嗎? # {}版 id{T: Type} {t: T} = t -y = id{Int} # 这是一个功能吗? +y = id{Int} # 這是一個功能嗎? # ||版 id|T: Type| t: T = t y = id|Int| # OK ``` -## {i=1} 的类型为 {i=Int},但在 OCaml 等环境中为 {i:Int}。为什么 Erg 采用前者的语法? +## {i=1} 的類型為 {i=Int},但在 OCaml 等環境中為 {i:Int}。為什么 Erg 采用前者的語法? -Erg 设计为将类型本身也视为值。 +Erg 設計為將類型本身也視為值。 ```python A = [Int; 3] @@ -38,69 +38,69 @@ S = {.i = Int} assert S.i == Int ``` -## 你打算在 Erg 中实现宏吗? +## 你打算在 Erg 中實現宏嗎? -目前没有。宏观大致分为四个目的。第一个是编译时计算。这在 Erg 中由编译时函数负责。第二,代码执行的延迟。这可以用 do 块来代替。第三个是处理通用化,对此多相关数和全称类型是比宏观更好的解决方案。第四个是自动生成代码,但这会造成可读性的下降,所以我们不敢在 Erg 中实现。因此,宏的大部分功能都由 Erg 型系统承担,因此没有动力进行部署。 +目前沒有。宏觀大致分為四個目的。第一個是編譯時計算。這在 Erg 中由編譯時函數負責。第二,代碼執行的延遲。這可以用 do 塊來代替。第三個是處理通用化,對此多相關數和全稱類型是比宏觀更好的解決方案。第四個是自動生成代碼,但這會造成可讀性的下降,所以我們不敢在 Erg 中實現。因此,宏的大部分功能都由 Erg 型系統承擔,因此沒有動力進行部署。 -## 为什么 Erg 没有例外机制? +## 為什么 Erg 沒有例外機制? -在许多情况下,错误处理类型是更好的解决方案。类型是一种错误处理方法,通常在较新的编程语言中使用。 +在許多情況下,錯誤處理類型是更好的解決方案。類型是一種錯誤處理方法,通常在較新的編程語言中使用。 -在 Erg 中,运算符使你可以在不太注意错误的情况下编写。 +在 Erg 中,運算符使你可以在不太注意錯誤的情況下編寫。 ```python read_file!() = - f = open!("foo.txt")? # 如果失败则立即返回错误,所以 f 是文件类型 + f = open!("foo.txt")? # 如果失敗則立即返回錯誤,所以 f 是文件類型 f.read_all!() -# 也可以使用 try 过程捕获类似的异常 +# 也可以使用 try 過程捕獲類似的異常 try!: do! s = read_file!()? print! s e => - # 发生错误时执行的块 + # 發生錯誤時執行的塊 print! e exit 1 ``` -在引入 Python 函数时,缺省情况下,所有函数都被视为包含异常,返回类型为。如果你知道不调度异常,请在中指明。 +在引入 Python 函數時,缺省情況下,所有函數都被視為包含異常,返回類型為。如果你知道不調度異常,請在中指明。 -此外,Erg 没有引入异常机制的另一个原因是它计划引入并行编程的功能。这是因为异常机制与并行执行不兼容(例如,如果并行执行导致多个异常,则很难处理)。 +此外,Erg 沒有引入異常機制的另一個原因是它計劃引入并行編程的功能。這是因為異常機制與并行執行不兼容(例如,如果并行執行導致多個異常,則很難處理)。 -## Erg 似乎消除了 Python 被认为是坏做法的功能,但为什么没有取消继承? +## Erg 似乎消除了 Python 被認為是壞做法的功能,但為什么沒有取消繼承? -Python 的库中有一些类设计为继承,如果完全取消继承,这些操作就会出现问题。然而,由于 Erg 的类默认为 final,并且原则上禁止多重和多层继承,因此继承的使用相对安全。 +Python 的庫中有一些類設計為繼承,如果完全取消繼承,這些操作就會出現問題。然而,由于 Erg 的類默認為 final,并且原則上禁止多重和多層繼承,因此繼承的使用相對安全。 -## 为什么多相关数的子类型推理默认指向记名trait? +## 為什么多相關數的子類型推理默認指向記名trait? -默认情况下,指向结构托盘会使类型指定变得复杂,并且可能会混合程序员的非预期行为。 +默認情況下,指向結構托盤會使類型指定變得復雜,并且可能會混合程序員的非預期行為。 ```python -# 如果 T 是结构特征的子类型... +# 如果 T 是結構特征的子類型... # f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T f|T| x, y: T = x + y - x -# T 是名义特征的子类型 +# T 是名義特征的子類型 # g: |T <: Add() and Sub()| (T, T) -> T g|T| x, y: T = x + y - x ``` -## Erg 是否实现了定义自己的运算符的功能? +## Erg 是否實現了定義自己的運算符的功能? -A:没有那个计划。最重要的原因是,如果允许定义自己的运算符,就会出现如何处理组合顺序的问题。可以定义自己的运算符的 Scala 和 Haskell 等都有不同的对应,但这可以看作是可能产生解释差异的语法的证据。此外,独立运算符还有一个缺点,那就是可能产生可读性较低的代码。 +A:沒有那個計劃。最重要的原因是,如果允許定義自己的運算符,就會出現如何處理組合順序的問題。可以定義自己的運算符的 Scala 和 Haskell 等都有不同的對應,但這可以看作是可能產生解釋差異的語法的證據。此外,獨立運算符還有一個缺點,那就是可能產生可讀性較低的代碼。 -## 为什么 Erg 取消了 += 这样的扩展赋值运算符? +## 為什么 Erg 取消了 += 這樣的擴展賦值運算符? -首先,Erg 中没有变量的可变性。也就是不能重新赋值。一旦对象与一个变量关联,它将一直绑定到该变量,直到它脱离作用域并被释放。在 Erg 中,可变性是指对象的可变性。明白了这个,故事就简单了。例如,表示,但由于变量是不可重新赋值的,因此这种语法是非法的。还有一个 Erg 的设计原则是运算符没有副作用。Python 通常也是如此,但对于某些对象(如 Dict),扩展赋值运算符会更改对象的内部状态。这算不上是一个很漂亮的设计。因此,扩展赋值运算符被完全废弃。 +首先,Erg 中沒有變量的可變性。也就是不能重新賦值。一旦對象與一個變量關聯,它將一直綁定到該變量,直到它脫離作用域并被釋放。在 Erg 中,可變性是指對象的可變性。明白了這個,故事就簡單了。例如,表示,但由于變量是不可重新賦值的,因此這種語法是非法的。還有一個 Erg 的設計原則是運算符沒有副作用。Python 通常也是如此,但對于某些對象(如 Dict),擴展賦值運算符會更改對象的內部狀態。這算不上是一個很漂亮的設計。因此,擴展賦值運算符被完全廢棄。 -## 为什么 Erg 在语法上特别对待有副作用的过程? +## 為什么 Erg 在語法上特別對待有副作用的過程? -副作用的局部化是代码维护的一个关键因素。 +副作用的局部化是代碼維護的一個關鍵因素。 -但是,确实也不是没有方法可以不在语言上特殊对待副作用。例如,可以用代数效果(类型系统上的功能)替代过程。但这样的合一并不总是正确的。例如,Haskell 没有对字符串进行特殊处理,只是一个字符数组,但这种抽象是错误的。 +但是,確實也不是沒有方法可以不在語言上特殊對待副作用。例如,可以用代數效果(類型系統上的功能)替代過程。但這樣的合一并不總是正確的。例如,Haskell 沒有對字符串進行特殊處理,只是一個字符數組,但這種抽象是錯誤的。 -什么情况下,可以说合一化是错的?一个指标是“是否会因其合一而难以看到错误信息”。Erg 设计师发现,将副作用特殊处理会使错误消息更容易阅读。 +什么情況下,可以說合一化是錯的?一個指標是“是否會因其合一而難以看到錯誤信息”。Erg 設計師發現,將副作用特殊處理會使錯誤消息更容易閱讀。 -Erg 有一个强大的类型系统,但并不是所有的类型都决定了它。如果这样做了,你的下场就跟 Java 试图用类来控制一切一样。 \ No newline at end of file +Erg 有一個強大的類型系統,但并不是所有的類型都決定了它。如果這樣做了,你的下場就跟 Java 試圖用類來控制一切一樣。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/i18n_messages.md b/doc/zh_TW/dev_guide/i18n_messages.md index 7a2fdbb5..e663e5bd 100644 --- a/doc/zh_TW/dev_guide/i18n_messages.md +++ b/doc/zh_TW/dev_guide/i18n_messages.md @@ -1,12 +1,12 @@ -# 多语言错误信息 +# 多語言錯誤信息 -Erg 正在推动消息(开始、选项、文档、提示、警告、错误消息等)的多语言化。如果你不熟悉 Rust 或 Erg,也可以参与此项目。请务必配合。 +Erg 正在推動消息(開始、選項、文檔、提示、警告、錯誤消息等)的多語言化。如果你不熟悉 Rust 或 Erg,也可以參與此項目。請務必配合。 -以下是多语种方法的说明。 +以下是多語種方法的說明。 ## 查找`switch_lang!` -在 Erg 源代码中找到(使用 grep 或编辑器的搜索功能)。我们应该能找到下面这样的东西。 +在 Erg 源代碼中找到(使用 grep 或編輯器的搜索功能)。我們應該能找到下面這樣的東西。 ```rust switch_lang!( @@ -15,27 +15,27 @@ switch_lang!( ), ``` -此消息目前仅支持日语和英语。让我们尝试添加简体消息。 +此消息目前僅支持日語和英語。讓我們嘗試添加簡體消息。 ## 添加消息 -请在查看其他语言内容的同时添加翻译消息。最后不要忘记逗号(,)。 +請在查看其他語言內容的同時添加翻譯消息。最后不要忘記逗號(,)。 ```rust switch_lang!( "japanese" => format!("この機能({name})はまだ正式に提供されていません"), - "simplified_chinese" => format!("该功能({name})还没有正式提供"), + "simplified_chinese" => format!("該功能({name})還沒有正式提供"), "english" => format!("this feature({name}) is not implemented yet"), ), ``` -另外,英语是默认设置,一定要排在最后。 +另外,英語是默認設置,一定要排在最后。 -`{name}`部分是 Rust 的格式化功能,允许你将变量的内容(`name`)嵌入到字符串中。 +`{name}`部分是 Rust 的格式化功能,允許你將變量的內容(`name`)嵌入到字符串中。 -## 构建 +## 構建 -现在,我们使用选项构建它。 +現在,我們使用選項構建它。 screenshot_i18n_messages @@ -43,13 +43,13 @@ switch_lang!( ## FAQ -Q:像这样的指定是什么意思?A:{RED} 及更高版本将显示为红色。重新启动交互渲染。 +Q:像這樣的指定是什么意思?A:{RED} 及更高版本將顯示為紅色。重新啟動交互渲染。 -Q:如果想添加自己的语言,该如何替换部分?答:目前支持以下语言。 +Q:如果想添加自己的語言,該如何替換部分?答:目前支持以下語言。 -* "english"(默认设置) -* "japanese" (日语) -* "simplified_chinese" (简体中文) -* "traditional_chinese" (繁体中文) +* "english"(默認設置) +* "japanese" (日語) +* "simplified_chinese" (簡體中文) +* "traditional_chinese" (繁體中文) -如果你想添加其他语言,请提出请求。 \ No newline at end of file +如果你想添加其他語言,請提出請求。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/rust_code_guideline.md b/doc/zh_TW/dev_guide/rust_code_guideline.md index 0c15a9f7..d76615d9 100644 --- a/doc/zh_TW/dev_guide/rust_code_guideline.md +++ b/doc/zh_TW/dev_guide/rust_code_guideline.md @@ -1,23 +1,23 @@ -# Rust 代码指南 +# Rust 代碼指南 -## 本地规则 +## 本地規則 -* 使用 `log!` 进行调试输出(使用 `println!` 等进行输出处理,这也是发布所必需的)。 -* 未使用或内部变量/方法(私有且仅用于特定功能)必须以 `_` 为前缀。如果要避免与保留字冲突,请在末尾添加一个`_`。 +* 使用 `log!` 進行調試輸出(使用 `println!` 等進行輸出處理,這也是發布所必需的)。 +* 未使用或內部變量/方法(私有且僅用于特定功能)必須以 `_` 為前綴。如果要避免與保留字沖突,請在末尾添加一個`_`。 -## 推荐代码 +## 推薦代碼 -* 定义和使用特定领域的枚举而不是数字枚举或布尔值。 -* 将访问修饰符保持在最低限度。即使在发布时也要优先使用 `pub(mod)` 或 `pub(crate)`。 -* 将 for 表达式中的可迭代对象显式转换为迭代器(`for i in x.iter()` 而不是 `for i in x`)。 -* 懒惰的评价。例如,如果 `default` 不是文字,请使用 `unwrap_or_else` 而不是 `unwrap_or`。 +* 定義和使用特定領域的枚舉而不是數字枚舉或布爾值。 +* 將訪問修飾符保持在最低限度。即使在發布時也要優先使用 `pub(mod)` 或 `pub(crate)`。 +* 將 for 表達式中的可迭代對象顯式轉換為迭代器(`for i in x.iter()` 而不是 `for i in x`)。 +* 懶惰的評價。例如,如果 `default` 不是文字,請使用 `unwrap_or_else` 而不是 `unwrap_or`。 -## 不鼓励使用代码 +## 不鼓勵使用代碼 -* 大量使用返回类型重载。特别是使用大量非显而易见的 `.into` 的代码。这是因为类型推断结果可能违反直觉。在这种情况下,建议使用 `from` 代替。 -* 大量使用 `Deref`。这有效地提出了与继承相同的问题。 +* 大量使用返回類型重載。特別是使用大量非顯而易見的 `.into` 的代碼。這是因為類型推斷結果可能違反直覺。在這種情況下,建議使用 `from` 代替。 +* 大量使用 `Deref`。這有效地提出了與繼承相同的問題。 -## 根据上下文做出决策的代码 +## 根據上下文做出決策的代碼 -* 定义未使用的辅助方法。 -* 大量使用 `unwrap` 和 `clone`。在某些情况下,没有什么比这样做更好的了。 \ No newline at end of file +* 定義未使用的輔助方法。 +* 大量使用 `unwrap` 和 `clone`。在某些情況下,沒有什么比這樣做更好的了。 \ No newline at end of file diff --git a/doc/zh_TW/dev_guide/terms.md b/doc/zh_TW/dev_guide/terms.md index 8dc55e6e..4d970d66 100644 --- a/doc/zh_TW/dev_guide/terms.md +++ b/doc/zh_TW/dev_guide/terms.md @@ -1,10 +1,10 @@ -# 词汇表 +# 詞匯表 ## 象征 ### ! -添加到标识符末尾的标记以指示它是过程,变量类型或变异运算符。 +添加到標識符末尾的標記以指示它是過程,變量類型或變異運算符。 ### [#](../syntax/00_basic.md/# comment) @@ -234,7 +234,7 @@ ### [Assertion] -检查(通常在运行时)代码中的条件是否为真。 这是使用 `assert` 函数等来完成的。 +檢查(通常在運行時)代碼中的條件是否為真。 這是使用 `assert` 函數等來完成的。 ```python sum = !0 @@ -244,42 +244,42 @@ for! 0..10, i => assert sum == 55 ``` -### 值对象 +### 值對象 -在 Erg 中,相当于基础对象。 它可以在编译时进行评估,并且具有简单的比较方法。 +在 Erg 中,相當于基礎對象。 它可以在編譯時進行評估,并且具有簡單的比較方法。 -### [附件补丁](../syntax/29_decorator.md#attach) +### [附件補丁](../syntax/29_decorator.md#attach) -为特征提供标准实现的补丁。 +為特征提供標準實現的補丁。 -### Ad hoc 多态性 -> [无重载](../syntax/type/overloading.md) +### Ad hoc 多態性 -> [無重載](../syntax/type/overloading.md) -具有所谓重载的多态性。 +具有所謂重載的多態性。 -### 属性-> [属性] +### 屬性-> [屬性] -`x.y` 标识符中的 `y` 部分。 +`x.y` 標識符中的 `y` 部分。 ### Arity -运算符需要多少个操作数。 +運算符需要多少個操作數。 -### [依赖类型](../syntax/type/dependent_type.md) +### [依賴類型](../syntax/type/dependent_type.md) -参数是值的类型(习惯上说,不是类型)。 +參數是值的類型(習慣上說,不是類型)。 -### 不可变 -> [不可变] +### 不可變 -> [不可變] -表示目标不会改变。 -其他语言中的变量也是不可变/可变的,但是在 Erg 中所有的变量都是不可变的。 +表示目標不會改變。 +其他語言中的變量也是不可變/可變的,但是在 Erg 中所有的變量都是不可變的。 -### 参数 -> [参数] +### 參數 -> [參數] -### 实例 +### 實例 -由类创建的对象。 类类型的元素。 +由類創建的對象。 類類型的元素。 -### [即时封锁](../syntax/00_basic.md#expression separator) +### [即時封鎖](../syntax/00_basic.md#expression separator) ```python x = @@ -288,401 +288,401 @@ x = y+z ``` -### 指数 +### 指數 -形式为“x[i]”,或其“i”部分。我们称 `x` 为 Indexable 对象。 +形式為“x[i]”,或其“i”部分。我們稱 `x` 為 Indexable 對象。 -### [缩进](../syntax/00_basic.md#indent) +### [縮進](../syntax/00_basic.md#indent) -通过向空格移动将文本向右对齐。缩进。 -Ergs 通过缩进表示块。这称为越位规则。 +通過向空格移動將文本向右對齊。縮進。 +Ergs 通過縮進表示塊。這稱為越位規則。 -### 别名 +### 別名 -别名。 +別名。 -### 错误 +### 錯誤 -规范中定义的异常情况。 +規范中定義的異常情況。 -* [错误处理] +* [錯誤處理] -### [运算符](../syntax/06_operator.md) +### [運算符](../syntax/06_operator.md) -将操作应用于其操作数的对象。或表示该对象的符号。 +將操作應用于其操作數的對象。或表示該對象的符號。 -* [运算符绑定强度] +* [運算符綁定強度] -### 覆盖 +### 覆蓋 -在子类中覆盖超类方法。 -在 Erg 中,您必须在覆盖时添加 `Override` 装饰器。 +在子類中覆蓋超類方法。 +在 Erg 中,您必須在覆蓋時添加 `Override` 裝飾器。 -### [不重载](../syntax/type/overloading.md) +### [不重載](../syntax/type/overloading.md) -### 越位规则-> [缩进](../syntax/00_basic.md#indent) +### 越位規則-> [縮進](../syntax/00_basic.md#indent) ### [目的] -* 面向对象 +* 面向對象 -### 操作数 -> [操作数](../syntax/06_operator.md) +### 操作數 -> [操作數](../syntax/06_operator.md) -### 运算符 -> [运算符](../syntax/06_operator.md) +### 運算符 -> [運算符](../syntax/06_operator.md) -##嘉线 +##嘉線 -### [种类](../syntax/type/advanced/kind.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/type/advanced/erasure.md) +* [類型推斷] +* [類型注釋](../syntax/type/conv_type.md) +* [類型參數] +* [類型添加](../syntax/type/advanced/erasure.md) +* [類型變量](../syntax/type/type_variable.md) +* [類型約束] -### 监视 +### 監視 -### 封装 +### 封裝 -隐藏实现细节。 +隱藏實現細節。 -### [多变的] +### [多變的] -不能是一成不变的。 +不能是一成不變的。 -* [可变对象] -* [多变的] -* [变量参考] -* [变量数组] -* [可变参数] +* [可變對象] +* [多變的] +* [變量參考] +* [變量數組] +* [可變參數] -### [函数](../syntax/04_function.md) +### [函數](../syntax/04_function.md) -没有副作用的子程序。 +沒有副作用的子程序。 -* [函数式编程](../syntax/23_scope.md#避免可变状态函数式编程) +* [函數式編程](../syntax/23_scope.md#避免可變狀態函數式編程) -### 基本类型 +### 基本類型 ###主格 -通过名称而不是对称结构来区分。 +通過名稱而不是對稱結構來區分。 -* [命名类型] -> [类](../syntax/type/04_class.md) -* [报喜] -* [名义子类型](../syntax/type/05_nst_vs_sst.md) +* [命名類型] -> [類](../syntax/type/04_class.md) +* [報喜] +* [名義子類型](../syntax/type/05_nst_vs_sst.md) -### 捕获-> [关闭] +### 捕獲-> [關閉] -### [协变] +### [協變] -在 Erg 中,如果 `T <: U` 则 `K(T) <: K(U)` 则称 `K` 是协变的。 +在 Erg 中,如果 `T <: U` 則 `K(T) <: K(U)` 則稱 `K` 是協變的。 -### [关键字参数] +### [關鍵字參數] -`k` 以函数调用 `f(k: v)` 的形式出现。您可以通过形式参数名称而不是按顺序指定实际参数。 +`k` 以函數調用 `f(k: v)` 的形式出現。您可以通過形式參數名稱而不是按順序指定實際參數。 ### 空集 -> [{}] ### 部分 -* [区间类型](../syntax/type/11_interval.md) -* 区间运算符 +* [區間類型](../syntax/type/11_interval.md) +* 區間運算符 ### 嵌入式 -Erg 标准 API 未在 .er 文件中实现。 +Erg 標準 API 未在 .er 文件中實現。 -### [类](../syntax/type/04_class.md) +### [類](../syntax/type/04_class.md) -具有继承功能的结构/抽象数据类型。在 Erg 中,它是一种实现命名子类型化和覆盖的类型。 -在 Erg 中,模块是模块对象负责,类型是类型对象,而其他语言可能负责模块和类型。 +具有繼承功能的結構/抽象數據類型。在 Erg 中,它是一種實現命名子類型化和覆蓋的類型。 +在 Erg 中,模塊是模塊對象負責,類型是類型對象,而其他語言可能負責模塊和類型。 -### [关闭] +### [關閉] -### [全局变量] +### [全局變量] ### [克隆] -### [继承](../syntax/type/07_inheritance.md) +### [繼承](../syntax/type/07_inheritance.md) -定义一个类是另一个类的父类集。 -继承的类称为超类,继承的类称为子类。 -子类具有其超类的所有功能。 +定義一個類是另一個類的父類集。 +繼承的類稱為超類,繼承的類稱為子類。 +子類具有其超類的所有功能。 -### 高楼层 +### 高樓層 -* [高阶种类](../syntax/type/advanced/kind.md) -* 高阶类型 -* 高阶函数 +* [高階種類](../syntax/type/advanced/kind.md) +* 高階類型 +* 高階函數 -### [公共变量] +### [公共變量] -### [结构子类型] +### [結構子類型] ### ~~后向引用~~ -> [后向引用] -### [复制] +### [復制] -### 评论 +### 評論 ### [集合](../syntax/10_array.md) -### 冒号 -> [:] +### 冒號 -> [:] -### [构造函数](../syntax/type/04_class.md) +### [構造函數](../syntax/type/04_class.md) ### 容器 -### 编译器 +### 編譯器 -### [编译时计算](../syntax/04_function.md#compile-time function) +### [編譯時計算](../syntax/04_function.md#compile-time function) -### 逗号 -> [,] +### 逗號 -> [,] -## sa线 +## sa線 -### 递归 +### 遞歸 -参考自己。 +參考自己。 -* 递归 -* [递归函数](../syntax/04_function.md#递归函数) +* 遞歸 +* [遞歸函數](../syntax/04_function.md#遞歸函數) -### 下标 -> [索引] +### 下標 -> [索引] -### [子类型多态性](../syntax/type/overloading.md) +### [子類型多態性](../syntax/type/overloading.md) -具有子类型的多态性。子类型对应于类型中的集合包含。 +具有子類型的多態性。子類型對應于類型中的集合包含。 ### 子程序 -模块化处理的对象。 Erg 中函数、过程和方法的通用术语。 +模塊化處理的對象。 Erg 中函數、過程和方法的通用術語。 -### [参考](../syntax/18_memory_management.md#borrowed) +### [參考](../syntax/18_memory_management.md#borrowed) -* 参考对象 -* [引用计数 (RC)](../syntax/18_memory_management.md#memory management) +* 參考對象 +* [引用計數 (RC)](../syntax/18_memory_management.md#memory management) * 引用相等 -> [副作用](../syntax/07_side_effect.md) -### [标识符](../syntax/02_variable.md/# 赋值) +### [標識符](../syntax/02_variable.md/# 賦值) -### 签名 +### 簽名 -* 类型签名 +* 類型簽名 ### [dict](../syntax/11_dict.md) -### 自然数 -> Nat +### 自然數 -> Nat ### 泛型 -> 泛型 -### 发电机 +### 發電機 -### 投影类型 +### 投影類型 -### 借用-> [参考](../syntax/18_memory_management.md#borrowed) +### 借用-> [參考](../syntax/18_memory_management.md#borrowed) -### [阴影](../syntax/02_name.md# variables) +### [陰影](../syntax/02_name.md# variables) -通过在内部范围内定义具有相同名称的变量来覆盖对变量的引用。 +通過在內部范圍內定義具有相同名稱的變量來覆蓋對變量的引用。 ### kind -> [kind](../syntax/type/advanced/kind.md) -大致类型的类型。 +大致類型的類型。 ### set -> set -在 Erg 中,它表示一个 Set 对象。 +在 Erg 中,它表示一個 Set 對象。 -### 谓词 +### 謂詞 -* 谓词函数 +* 謂詞函數 -返回布尔类型的函数。 +返回布爾類型的函數。 -### 条件分支 +### 條件分支 -### 所有权 +### 所有權 -对象唯一性的概念。 -如果您拥有对象的所有权,则可以使用 mutable 参考它。 +對象唯一性的概念。 +如果您擁有對象的所有權,則可以使用 mutable 參考它。 ### Boolean -> Bool -### 单例 +### 單例 -从只能创建一个实例的类创建的实例。一种设计模式,可确保只创建一个类的一个实例。 +從只能創建一個實例的類創建的實例。一種設計模式,可確保只創建一個類的一個實例。 ### [Symbol] -> [Identifier](../syntax/02_name.md) -* 符号化 +* 符號化 -### [脚本](../syntax/00_basic.md# 脚本) +### [腳本](../syntax/00_basic.md# 腳本) 包含 Erg 程序的文件。 -### 范围 +### 范圍 -变量管理单元。外部作用域不能引用内部作用域中存在的变量。 -当范围退出时,引用计数为 0 的对象将被释放。 +變量管理單元。外部作用域不能引用內部作用域中存在的變量。 +當范圍退出時,引用計數為 0 的對象將被釋放。 -### 扩展运算符 -> expansion assignment +### 擴展運算符 -> expansion assignment ### [切片](../syntax/10_array.md#slice) -表示数组子序列的对象,以 `x[a..b]` 的形式生成。 +表示數組子序列的對象,以 `x[a..b]` 的形式生成。 ### 控制字符 -### 整数 -> Int +### 整數 -> Int -一组自然数加上负数。 +一組自然數加上負數。 -### [设置](../syntax/12_set.md) +### [設置](../syntax/12_set.md) -### 分号 -> ; +### 分號 -> ; -### [声明](../syntax/03_declaration.md) +### [聲明](../syntax/03_declaration.md) -显式类型变量。 +顯式類型變量。 ### 全名 -* 通用类型 -> [多态类型](../syntax/type/quantified.md) - * 封闭式通用 - * 打开通用 -* 通用函数 -> 多相关函数 +* 通用類型 -> [多態類型](../syntax/type/quantified.md) + * 封閉式通用 + * 打開通用 +* 通用函數 -> 多相關函數 * 通用量化 -### 前缀运算符 +### 前綴運算符 -运算符 `∘` 以 `∘x` 的形式应用。 +運算符 `°` 以 `°x` 的形式應用。 -### 相互递归 +### 相互遞歸 -### 下标 -> index +### 下標 -> index -### 属性 +### 屬性 -* 属性子类型 +* 屬性子類型 -## 塔线 +## 塔線 -### [代数](../syntax/02_name.md) +### [代數](../syntax/02_name.md) -* [代数类型](../syntax/type/13_algebraic.md) -* 代数数据类型 +* [代數類型](../syntax/type/13_algebraic.md) +* 代數數據類型 -### [赋值](../syntax/02_variable.md/#assignment) +### [賦值](../syntax/02_variable.md/#assignment) ### 多 -* [多重继承](../syntax/type/07_inheritance.md/#禁止多重继承) -* 多重赋值 -* 重载 -> [不重载] +* [多重繼承](../syntax/type/07_inheritance.md/#禁止多重繼承) +* 多重賦值 +* 重載 -> [不重載] -### 多态性 +### 多態性 -* [多态类型](../syntax/type/quantified.md) -* 多相关系数 +* [多態類型](../syntax/type/quantified.md) +* 多相關系數 -### 多态性 -> [多态性] +### 多態性 -> [多態性] -### 鸭子类型 +### 鴨子類型 -### [元组](../syntax/11_tuple.md) +### [元組](../syntax/11_tuple.md) -### 单相 +### 單相 -* 单相 -* 单相型 -* 单相关系数 +* 單相 +* 單相型 +* 單相關系數 -### [延迟初始化] +### [延遲初始化] ### 提取分配 -### 抽象语法树 -> [AST] +### 抽象語法樹 -> [AST] -### 中缀运算符 +### 中綴運算符 -运算符 `∘` 以 `x∘y` 的形式应用。 +運算符 `°` 以 `x°y` 的形式應用。 -### [常数](../syntax/02_name.md/#constant) +### [常數](../syntax/02_name.md/#constant) -不可变的,编译时可评估的代数。 +不可變的,編譯時可評估的代數。 -* [常量类型](../syntax/type/advanced/const.md) -* [常量表达式](../syntax/type/advanced/const.md) +* [常量類型](../syntax/type/advanced/const.md) +* [常量表達式](../syntax/type/advanced/const.md) -### 定义 +### 定義 -分配与变量对应的对象。 +分配與變量對應的對象。 -### 提供的属性 +### 提供的屬性 -可作为 API 使用的属性。特别是由特征自动实现的属性。 +可作為 API 使用的屬性。特別是由特征自動實現的屬性。 -### 申请 +### 申請 -将参数传递给函数对象并获取评估结果。 +將參數傳遞給函數對象并獲取評估結果。 -### [装饰器](../syntax/29_decorator.md) +### [裝飾器](../syntax/29_decorator.md) ``` python @deco f x = ... ``` -语法糖,或“装饰”。大致等于`_f x = ...; f = 装饰 _f`。 `deco` 本身只是一个高阶子程序。 +語法糖,或“裝飾”。大致等于`_f x = ...; f = 裝飾 _f`。 `deco` 本身只是一個高階子程序。 -### 析构函数 +### 析構函數 -对象被销毁时调用的方法。 +對象被銷毀時調用的方法。 ### 程序 -> [procedure](../syntax/08_procedure.md) -读取和写入可变状态的子程序。 -有时会说程序的执行结果可以根据调用过程的顺序而改变,但如果我们谈论交换性,这是不正确的。 -例如,作为函数子类型的运算符通常不可交换。 +讀取和寫入可變狀態的子程序。 +有時會說程序的執行結果可以根據調用過程的順序而改變,但如果我們談論交換性,這是不正確的。 +例如,作為函數子類型的運算符通常不可交換。 -### [默认参数](../syntax/04_function.md/#default arguments default-parameters) +### [默認參數](../syntax/04_function.md/#default arguments default-parameters) -通过指定形式参数的默认值,可以在调用时省略实际参数的指定的函数。 +通過指定形式參數的默認值,可以在調用時省略實際參數的指定的函數。 -### 扩张 +### 擴張 -* 扩展运算符 -* 扩展分配 +* 擴展運算符 +* 擴展分配 ### [特殊格式](../syntax/../API/special.md) -不能作为实际参数传递的对象。 +不能作為實際參數傳遞的對象。 -### 匿名函数 -> [anonymous function](../syntax/20_lambda.md) +### 匿名函數 -> [anonymous function](../syntax/20_lambda.md) -由匿名函数运算符`->`创建的函数对象。可以在不定义名称的情况下使用。 +由匿名函數運算符`->`創建的函數對象。可以在不定義名稱的情況下使用。 -### 点运算符 (`.`) -> attribute reference +### 點運算符 (`.`) -> attribute reference -### 顶部 +### 頂部 -* 顶部类型 -> [结构对象] -* 顶级 -> [对象] +* 頂部類型 -> [結構對象] +* 頂級 -> [對象] ### [特征](../syntax/type/03_trait.md) @@ -690,15 +690,15 @@ f x = ... ### [理解](../syntax/27_comprehension.md) -### ~~中缀运算符~~ -> 中缀运算符 +### ~~中綴運算符~~ -> 中綴運算符 -### 命名空间 +### 命名空間 ## 是一行 -### [数组](../syntax/10_array.md) +### [數組](../syntax/10_array.md) -### [派生类型](../syntax/type/variances.md/# 用户定义的类型变体) +### [派生類型](../syntax/type/variances.md/# 用戶定義的類型變體) ### [模式(匹配)](../syntax/26_pattern_matching.md) @@ -706,87 +706,87 @@ f x = ... ### hashmap -> [dict](../syntax/11_dict.md) -### [补丁](../syntax/type/07_patch.md) +### [補丁](../syntax/type/07_patch.md) -### 公共变量-> [public variables](../syntax/19_visibility.md) +### 公共變量-> [public variables](../syntax/19_visibility.md) -### 参数 -> [argument](../syntax/04_function.md) +### 參數 -> [argument](../syntax/04_function.md) -### [参数多态](../syntax/type/overloading.md) +### [參數多態](../syntax/type/overloading.md) -### [逆变](../syntax/type/advanced/variance.md) +### [逆變](../syntax/type/advanced/variance.md) ### 相比 -* 比较运算符 -* 可比类型 +* 比較運算符 +* 可比類型 -### [私有变量](../syntax/19_visibility.md) +### [私有變量](../syntax/19_visibility.md) -### 标准 +### 標準 -* 标准输出 -* 标准输入 -* 标准库 +* 標準輸出 +* 標準輸入 +* 標準庫 ### [副作用](../syntax/07_side_effect.md) -代码应该/不应该读/写外部可变状态。 +代碼應該/不應該讀/寫外部可變狀態。 -### 复数 -> 复数 +### 復數 -> 復數 -### 浮动 -> 浮动 +### 浮動 -> 浮動 -### 私有变量 -> 私有变量 +### 私有變量 -> 私有變量 -### 布尔代数-> Bool +### 布爾代數-> Bool ### [程序](../syntax/08_procedure.md) -### [参数](../syntax/04_function.md) +### [參數](../syntax/04_function.md) -### 部分类型 -> Subtyping +### 部分類型 -> Subtyping -### [不可变] +### [不可變] -在 Erg 中,一个对象永远不应该改变它的内容。 +在 Erg 中,一個對象永遠不應該改變它的內容。 -* [不可变对象] -* [不可变类型] -* [不可变引用] +* [不可變對象] +* [不可變類型] +* [不可變引用] -### [筛子类型](../syntax/type/12_refinement.md) +### [篩子類型](../syntax/type/12_refinement.md) ### [堵塞] -### 解构赋值 +### 解構賦值 -### [变量](../syntax/02_variable.md) +### [變量](../syntax/02_variable.md) ### 底部 -* 底部类型 -> [{}] -* 底层 -> [从不] +* 底部類型 -> [{}] +* 底層 -> [從不] -### [多态性] +### [多態性] ## ma line -### ~~ 前缀运算符 ~~ -> 前缀运算符 +### ~~ 前綴運算符 ~~ -> 前綴運算符 -### [标记类型](../syntax/type/advanced/marker_trait.md) +### [標記類型](../syntax/type/advanced/marker_trait.md) -### [匿名函数](../syntax/21_lambda.md) +### [匿名函數](../syntax/21_lambda.md) -### 可变 -> [可变] +### 可變 -> [可變] -### [移动] +### [移動] ### 方法 ### 元字符 -### [模块](../syntax/24_module.md) +### [模塊](../syntax/24_module.md) ### [字符串] -> [字符串] @@ -796,43 +796,43 @@ f x = ... ## 或行 -### [幻像类型](../syntax/type/advanced/phantom.md) +### [幻像類型](../syntax/type/advanced/phantom.md) -### 请求属性 +### 請求屬性 ### [元素] -### [称呼] +### [稱呼] -## 拉线 +## 拉線 -### [图书馆] +### [圖書館] -### lambda 表达式 -> [匿名函数](../syntax/20_lambda.md) +### lambda 表達式 -> [匿名函數](../syntax/20_lambda.md) ### 排名 -* [rank2 多态性](../syntax/type/advanced/rank2type.md) +* [rank2 多態性](../syntax/type/advanced/rank2type.md) ### [文字](../syntax/01_literal.md) -* [文字标识符](../syntax/18_naming_rule.md/#literal identifier) +* [文字標識符](../syntax/18_naming_rule.md/#literal identifier) ### [量化](../syntax/type/quantified.md) ### [布局](../syntax/type/mut.md) -### [枚举](../syntax/type/10_enum.md) +### [枚舉](../syntax/type/10_enum.md) -### [记录](../syntax/12_record.md) +### [記錄](../syntax/12_record.md) -* [记录类型] -* 记录多态 -> Column Polymorphism +* [記錄類型] +* 記錄多態 -> Column Polymorphism -### 列多态 +### 列多態 -### [局部变量](../syntax/19_visibility.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 index 1a8a2dba..49a40529 100644 --- a/doc/zh_TW/dev_guide/unify_terms.md +++ b/doc/zh_TW/dev_guide/unify_terms.md @@ -1,56 +1,56 @@ -# 术语统一 +# 術語統一 -## 可访问性,可见性 +## 可訪問性,可見性 -使用可见性。 +使用可見性。 -## 类型绑定,类型约束 +## 類型綁定,類型約束 -给定量化和细化类型的谓词表达式列表。使用类型边界。 +給定量化和細化類型的謂詞表達式列表。使用類型邊界。 ## 子程序、例程、子程序 使用子程序。 -## 引用透明/不透明,有/没有副作用 +## 引用透明/不透明,有/沒有副作用 -使用有/无副作用。 +使用有/無副作用。 -## 标识符、代数、变量、名称、符号 +## 標識符、代數、變量、名稱、符號 -就其本义而言, +就其本義而言, -* 符号:在源代码中实心编写的字符(符号、控制字符等除外),不是字符串对象(未包含在“”中)。符号在 Ruby、Lisp 等中作为原始类型存在,但在 Erg 中它们不被视为对象。 -* 标识符:(并且可以)引用某个对象的符号,而不是保留字。例如,在 Python 中 class 和 def 不能用作标识符。由于 Erg 没有保留字,所以除了某些符号外,所有符号都可以用作标识符。 -* 名称:与标识符的含义几乎相同。它有时与 Erg 中的代数同义使用。 -* 代数名称:相当于Erg中的标识符。在 C 中,函数名称是标识符,而不是代数名称。 “代数”指的是语言特性本身,它允许您使用 `=`(变量赋值运算符)或 `=`(常量赋值运算符)来分配对象。 +* 符號:在源代碼中實心編寫的字符(符號、控制字符等除外),不是字符串對象(未包含在“”中)。符號在 Ruby、Lisp 等中作為原始類型存在,但在 Erg 中它們不被視為對象。 +* 標識符:(并且可以)引用某個對象的符號,而不是保留字。例如,在 Python 中 class 和 def 不能用作標識符。由于 Erg 沒有保留字,所以除了某些符號外,所有符號都可以用作標識符。 +* 名稱:與標識符的含義幾乎相同。它有時與 Erg 中的代數同義使用。 +* 代數名稱:相當于Erg中的標識符。在 C 中,函數名稱是標識符,而不是代數名稱。 “代數”指的是語言特性本身,它允許您使用 `=`(變量賦值運算符)或 `=`(常量賦值運算符)來分配對象。 ```python -代数名称<:(名称==标识符)​​<:符号 -变量 + 常数 == 代数 +代數名稱<:(名稱==標識符)??<:符號 +變量 + 常數 == 代數 ``` -然而,应该称为“代数”的东西,往往被称为“变量”。这就是数学术语的效果。 -值内容可以改变的变量是可变变量,值内容不改变的变量是不可变变量。 -请注意,常量始终是不可变的。 +然而,應該稱為“代數”的東西,往往被稱為“變量”。這就是數學術語的效果。 +值內容可以改變的變量是可變變量,值內容不改變的變量是不可變變量。 +請注意,常量始終是不可變的。 -Erg 中不使用代数名称和名称,使用统一标识符。 -但是,一般来说,具有 `v = 1` 的 `v` 称为“变量 v”,而具有 `C = 1` 的 `C` 称为“常量 C”。 . +Erg 中不使用代數名稱和名稱,使用統一標識符。 +但是,一般來說,具有 `v = 1` 的 `v` 稱為“變量 v”,而具有 `C = 1` 的 `C` 稱為“常量 C”。 . -## 属性、字段、属性 +## 屬性、字段、屬性 -使用属性。顺便说一句,记录是一个函数,它可以定义一个没有类的具有元素属性的对象。 +使用屬性。順便說一句,記錄是一個函數,它可以定義一個沒有類的具有元素屬性的對象。 -## 应用程序,调用 +## 應用程序,調用 -为子例程对象提供参数并获得结果。 -使用呼叫。这是因为Application有“应用软件”的用法。 +為子例程對象提供參數并獲得結果。 +使用呼叫。這是因為Application有“應用軟件”的用法。 -## 数组列表 +## 數組列表 -使用数组。 Erg 数组(通常)在内存中是连续的。 -List 是指所谓的链表,或者说列表作为 Python 数据类型。 +使用數組。 Erg 數組(通常)在內存中是連續的。 +List 是指所謂的鏈表,或者說列表作為 Python 數據類型。 -## lambda 函数、lambda 表达式、匿名函数 +## lambda 函數、lambda 表達式、匿名函數 -与匿名函数统一。在英文中,可以使用 Lambda 来缩短字符数,但正式名称是 Anonymous function。 \ No newline at end of file +與匿名函數統一。在英文中,可以使用 Lambda 來縮短字符數,但正式名稱是 Anonymous function。 \ No newline at end of file diff --git a/doc/zh_TW/faq_general.md b/doc/zh_TW/faq_general.md index 8d1166e1..9c8181f1 100644 --- a/doc/zh_TW/faq_general.md +++ b/doc/zh_TW/faq_general.md @@ -1,37 +1,37 @@ -# Erg常见问题 +# Erg常見問題 -此常见问题解答适用于一般 Erg 初学者。 -对于个别(常见)技术问题,请参阅 [此处](./faq_technical.md) 了解个别(常见)技术问题,以及 -[这里](./dev_guide/faq_syntax.md) 了解更多信息。 +此常見問題解答適用于一般 Erg 初學者。 +對于個別(常見)技術問題,請參閱 [此處](./faq_technical.md) 了解個別(常見)技術問題,以及 +[這里](./dev_guide/faq_syntax.md) 了解更多信息。 -## Erg 是 Python 兼容语言是什么意思? +## Erg 是 Python 兼容語言是什么意思? -~~A:Erg的可执行系统EVM(Erg VirtualMachine)执行Erg字节码,是Python字节码的扩展。它在 Python 字节码中引入了静态类型系统和其他特性(例如向不带参数的指令引入参数,以及在自由编号中实现唯一指令)。这让 Erg 可以无缝调用 Python 代码并快速执行。~~ +~~A:Erg的可執行系統EVM(Erg VirtualMachine)執行Erg字節碼,是Python字節碼的擴展。它在 Python 字節碼中引入了靜態類型系統和其他特性(例如向不帶參數的指令引入參數,以及在自由編號中實現唯一指令)。這讓 Erg 可以無縫調用 Python 代碼并快速執行。~~ -A: Erg 代码被转译成 Python 字节码。也就是说,它运行在与 Python 相同的解释器上。最初,我们计划开发一个兼容 Cpython 的解释器,并将其与编译器结合起来形成“Erg”。但是,由于处理系统的发展远远落后于编译器,我们决定提前只发布编译器(但解释器仍在开发中)。 +A: Erg 代碼被轉譯成 Python 字節碼。也就是說,它運行在與 Python 相同的解釋器上。最初,我們計劃開發一個兼容 Cpython 的解釋器,并將其與編譯器結合起來形成“Erg”。但是,由于處理系統的發展遠遠落后于編譯器,我們決定提前只發布編譯器(但解釋器仍在開發中)。 -## 哪些语言影响了Erg? +## 哪些語言影響了Erg? -我们受到的语言多于我们双手所能指望的数量,但 Python、Rust、Nim 和 Haskell 的影响最大。 -我们从 Python 继承了许多语义,从 Rust 继承了面向表达式和 trait,从 Nim 继承了过程,从 Haskell 继承了函数式编程相关的特性。 +我們受到的語言多于我們雙手所能指望的數量,但 Python、Rust、Nim 和 Haskell 的影響最大。 +我們從 Python 繼承了許多語義,從 Rust 繼承了面向表達式和 trait,從 Nim 繼承了過程,從 Haskell 繼承了函數式編程相關的特性。 -## 可以调用 Python 的语言包括 Julia。你为什么创建 Erg? +## 可以調用 Python 的語言包括 Julia。你為什么創建 Erg? -答:Erg 设计的动机之一是拥有一种易于使用且具有强大类型系统的语言。即具有类型推断、种类、依赖类型等的语言。 -Julia 是可以有类型的,但它确实是一种动态类型语言,不具备静态类型语言的编译时错误检测优势。 +答:Erg 設計的動機之一是擁有一種易于使用且具有強大類型系統的語言。即具有類型推斷、種類、依賴類型等的語言。 +Julia 是可以有類型的,但它確實是一種動態類型語言,不具備靜態類型語言的編譯時錯誤檢測優勢。 -## Erg 支持多种编程风格,包括函数式和面向对象的编程。这不是与 Python 的“应该有一种——最好只有一种——明显的方法”相反吗? +## Erg 支持多種編程風格,包括函數式和面向對象的編程。這不是與 Python 的“應該有一種——最好只有一種——明顯的方法”相反嗎? -答:在 Erg 中,该术语是在更狭窄的上下文中使用的。例如,Erg API 中一般没有别名;在这种情况下,Erg是“唯一一种方式”。 -在更大的上下文中,例如 FP 或 OOP,只有一种做事方式并不一定很方便。 -例如,JavaScript 有几个库可以帮助创建不可变的程序,而 C 有几个用于垃圾收集的库。 -然而,即使是这样的基本功能也有多个库不仅需要时间来选择,而且在集成使用不同库的代码时也会产生很大的困难。 -即使在纯函数式语言 Haskell 中,也有支持 OOP 的库。 -如果程序员没有一些东西,他们会自己创造它们。因此,我们认为将它们作为标准提供会更好。 -这也符合 Python 的“含电池”概念。 +答:在 Erg 中,該術語是在更狹窄的上下文中使用的。例如,Erg API 中一般沒有別名;在這種情況下,Erg是“唯一一種方式”。 +在更大的上下文中,例如 FP 或 OOP,只有一種做事方式并不一定很方便。 +例如,JavaScript 有幾個庫可以幫助創建不可變的程序,而 C 有幾個用于垃圾收集的庫。 +然而,即使是這樣的基本功能也有多個庫不僅需要時間來選擇,而且在集成使用不同庫的代碼時也會產生很大的困難。 +即使在純函數式語言 Haskell 中,也有支持 OOP 的庫。 +如果程序員沒有一些東西,他們會自己創造它們。因此,我們認為將它們作為標準提供會更好。 +這也符合 Python 的“含電池”概念。 -## Erg 这个名字的由来是什么? +## Erg 這個名字的由來是什么? -它以cgs单位系统中的能量单位erg命名。它具有双重含义:一种为程序员提供能量的符合人体工程学的语言。 +它以cgs單位系統中的能量單位erg命名。它具有雙重含義:一種為程序員提供能量的符合人體工程學的語言。 -还有其他几个候选者,但之所以选择它是因为它最短(根据 Ruby 的开发者 Matz 的说法,语言名称越短越好)并且具有相当高的可搜索性。 \ No newline at end of file +還有其他幾個候選者,但之所以選擇它是因為它最短(根據 Ruby 的開發者 Matz 的說法,語言名稱越短越好)并且具有相當高的可搜索性。 \ No newline at end of file diff --git a/doc/zh_TW/faq_technical.md b/doc/zh_TW/faq_technical.md index 813cce5f..8fcf254d 100644 --- a/doc/zh_TW/faq_technical.md +++ b/doc/zh_TW/faq_technical.md @@ -1,34 +1,34 @@ -# 技术常见问题 +# 技術常見問題 -本节回答有关使用 Erg 语言的技术问题。换句话说,它包含以 What 或 Which 开头的问题,以及可以用 Yes/No 回答的问题。 +本節回答有關使用 Erg 語言的技術問題。換句話說,它包含以 What 或 Which 開頭的問題,以及可以用 Yes/No 回答的問題。 -有关如何确定语法的更多信息,请参阅 [此处](./dev_guide/faq_syntax.md) 了解基础语法决策,以及 [此处](./dev_guide/../faq_general.md)。 +有關如何確定語法的更多信息,請參閱 [此處](./dev_guide/faq_syntax.md) 了解基礎語法決策,以及 [此處](./dev_guide/../faq_general.md)。 -## Erg 中有异常机制吗? +## Erg 中有異常機制嗎? -答:不会。Erg 使用 `Result` 类型代替。请参阅 [此处](./dev_guide/faq_syntax.md) 了解 Erg 没有异常机制的原因。 +答:不會。Erg 使用 `Result` 類型代替。請參閱 [此處](./dev_guide/faq_syntax.md) 了解 Erg 沒有異常機制的原因。 -## Erg 是否有与 TypeScript 的 `Any` 等价的类型? +## Erg 是否有與 TypeScript 的 `Any` 等價的類型? -答:不,没有。所有对象都至少属于 `Object` 类,但是这种类型只提供了一组最小的属性,所以你不能像使用 Any 那样对它做任何你想做的事情。 -`Object` 类通过`match` 等动态检查转换为所需的类型。它与Java 和其他语言中的`Object` 是同一种。 -在 Erg 世界中,没有像 TypeScript 那样的混乱和绝望,其中 API 定义是“Any”。 +答:不,沒有。所有對象都至少屬于 `Object` 類,但是這種類型只提供了一組最小的屬性,所以你不能像使用 Any 那樣對它做任何你想做的事情。 +`Object` 類通過`match` 等動態檢查轉換為所需的類型。它與Java 和其他語言中的`Object` 是同一種。 +在 Erg 世界中,沒有像 TypeScript 那樣的混亂和絕望,其中 API 定義是“Any”。 -## Never、{}、None、()、NotImplemented 和 Ellipsis 有什么区别? +## Never、{}、None、()、NotImplemented 和 Ellipsis 有什么區別? -A:`Never` 是一种“不可能”的类型。产生运行时错误的子例程将“Never”(或“Never”的合并类型)作为其返回类型。该程序将在检测到这一点后立即停止。尽管 `Never` 类型在定义上也是所有类型的子类,但 `Never` 类型的对象永远不会出现在 Erg 代码中,也永远不会被创建。 `{}` 等价于 `Never`。 -`Ellipsis` 是一个表示省略号的对象,来自 Python。 -`NotImplemented` 也来自 Python。它被用作未实现的标记,但 Erg 更喜欢产生错误的 `todo` 函数。 -`None` 是 `NoneType` 的一个实例。它通常与 `Option` 类型一起使用。 -`()` 是一个单元类型和它自己的一个实例。当您想要返回“无意义的值”(例如过程的返回值)时使用它。 +A:`Never` 是一種“不可能”的類型。產生運行時錯誤的子例程將“Never”(或“Never”的合并類型)作為其返回類型。該程序將在檢測到這一點后立即停止。盡管 `Never` 類型在定義上也是所有類型的子類,但 `Never` 類型的對象永遠不會出現在 Erg 代碼中,也永遠不會被創建。 `{}` 等價于 `Never`。 +`Ellipsis` 是一個表示省略號的對象,來自 Python。 +`NotImplemented` 也來自 Python。它被用作未實現的標記,但 Erg 更喜歡產生錯誤的 `todo` 函數。 +`None` 是 `NoneType` 的一個實例。它通常與 `Option` 類型一起使用。 +`()` 是一個單元類型和它自己的一個實例。當您想要返回“無意義的值”(例如過程的返回值)時使用它。 -## 为什么 `x = p!()` 有效但 `f() = p!()` 会导致 EffectError? +## 為什么 `x = p!()` 有效但 `f() = p!()` 會導致 EffectError? -`!` 不是副作用产品的标记,而是可能导致副作用的对象。 -过程 `p!` 和可变类型 `T!` 会引起副作用,但如果 `p!()` 的返回值是 `Int` 类型,它本身就不再引起副作用。 +`!` 不是副作用產品的標記,而是可能導致副作用的對象。 +過程 `p!` 和可變類型 `T!` 會引起副作用,但如果 `p!()` 的返回值是 `Int` 類型,它本身就不再引起副作用。 -## 当我尝试使用 Python API 时,对于在 Python 中有效的代码,我在 Erg 中收到类型错误。这是什么意思? +## 當我嘗試使用 Python API 時,對于在 Python 中有效的代碼,我在 Erg 中收到類型錯誤。這是什么意思? -A:Erg API 的类型尽可能接近 Python API 规范,但有些情况无法完全表达。 -此外,根据规范有效但被认为不合需要的输入(例如,在应该输入 int 时输入浮点数)可能会被 Erg 开发团队酌情视为类型错误。 \ No newline at end of file +A:Erg API 的類型盡可能接近 Python API 規范,但有些情況無法完全表達。 +此外,根據規范有效但被認為不合需要的輸入(例如,在應該輸入 int 時輸入浮點數)可能會被 Erg 開發團隊酌情視為類型錯誤。 \ No newline at end of file diff --git a/doc/zh_TW/improved_points.md b/doc/zh_TW/improved_points.md index dcea4a90..8d99907b 100644 --- a/doc/zh_TW/improved_points.md +++ b/doc/zh_TW/improved_points.md @@ -1,13 +1,13 @@ -# Python 的改进 +# Python 的改進 -## 执行静态分析(静态类型检查、变量和属性检查) +## 執行靜態分析(靜態類型檢查、變量和屬性檢查) -静态类型检查的好处现在怎么强调都不为过,但是检查变量和属性的存在也是相当重要的一部分。 +靜態類型檢查的好處現在怎么強調都不為過,但是檢查變量和屬性的存在也是相當重要的一部分。 -## 严格范围处理 +## 嚴格范圍處理 -在 Python 中,语句没有范围。 -因此,在 `for` 或 `if` 中定义的变量具有外部影响。 不能随便命名变量。 +在 Python 中,語句沒有范圍。 +因此,在 `for` 或 `if` 中定義的變量具有外部影響。 不能隨便命名變量。 ```python for i in range(10): @@ -16,15 +16,15 @@ for i in range(10): print(x) # 1 ``` -在 Erg 中,所有块都有范围并且是完全隔离的。 +在 Erg 中,所有塊都有范圍并且是完全隔離的。 -## 明确区分可变对象和不可变对象 +## 明確區分可變對象和不可變對象 -Python并不清楚可变和不可变/堆和值对象之间的区别,因此您必须记住元组是不可变的但列表是可变的......您需要记住元组是不可变的,但列表是可变的 ... 等等。 -另外,如果你想让你自己的类不可变,你必须经历一个乏味的过程。 +Python并不清楚可變和不可變/堆和值對象之間的區別,因此您必須記住元組是不可變的但列表是可變的......您需要記住元組是不可變的,但列表是可變的 ... 等等。 +另外,如果你想讓你自己的類不可變,你必須經歷一個乏味的過程。 ```python -# 你能相信这段代码对过去的 Python 版本有效吗? +# 你能相信這段代碼對過去的 Python 版本有效嗎? i = 256 assert i is 256 i = 257 @@ -33,16 +33,16 @@ assert i is not 257 ## Traits -就像 Java 的接口一样,你可以进行基于契约的编程。 +就像 Java 的接口一樣,你可以進行基于契約的編程。 -Python 也有 ABC(抽象基类),但这种结构最适合静态类型。 +Python 也有 ABC(抽象基類),但這種結構最適合靜態類型。 -## 静态解决依赖关系 +## 靜態解決依賴關系 -这可以防止长时间运行程序然后由于缺少模块而出现错误的烦人体验。 +這可以防止長時間運行程序然后由于缺少模塊而出現錯誤的煩人體驗。 -## 内置包管理器 +## 內置包管理器 -具有标准化目录结构和构建文件的可重现构建。 -当然提供了锁定文件生成和版本控制。 -无需为每个项目选择或混合anaconda、pyenv、诗歌等。 +具有標準化目錄結構和構建文件的可重現構建。 +當然提供了鎖定文件生成和版本控制。 +無需為每個項目選擇或混合anaconda、pyenv、詩歌等。 diff --git a/doc/zh_TW/index.md b/doc/zh_TW/index.md index c7d9e9ae..821be649 100644 --- a/doc/zh_TW/index.md +++ b/doc/zh_TW/index.md @@ -2,24 +2,24 @@ ## [API/](./API/index.md) - 本节介绍 Erg 的内置或标准库提供的子程序、类型、常量等的规范。 + 本節介紹 Erg 的內置或標準庫提供的子程序、類型、常量等的規范。 ## [compiler/](./compiler/index.md) - 描述 Erg 编译器的设计(厘米) + 描述 Erg 編譯器的設計(厘米) ## [dev_guide/](./dev_guide/index.md) - 它解释了项目的发展政策,如何做出贡献等。 + 它解釋了項目的發展政策,如何做出貢獻等。 ## [python/](./python/index.md) - 解释了开发 Erg 所需的 Python 知识。 + 解釋了開發 Erg 所需的 Python 知識。 ## [syntax/](./syntax/00_basic.md) - Erg 的语法进行了解释。 + Erg 的語法進行了解釋。 ## [tools/](./tools/index.md) - 解释如何使用 Erg 的外围工具和命令选项。 \ No newline at end of file + 解釋如何使用 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 index abb19725..80a5c66b 100644 --- a/doc/zh_TW/migration_from_py.md +++ b/doc/zh_TW/migration_from_py.md @@ -1,8 +1,8 @@ -# 从 Python 迁移到 Erg 的提示 +# 從 Python 遷移到 Erg 的提示 -## 我想将字符串转换为 int 等。 +## 我想將字符串轉換為 int 等。 -使用 `Str` 类的 `parse` 方法。 它返回一个 `Result` 类型。 +使用 `Str` 類的 `parse` 方法。 它返回一個 `Result` 類型。 ```python s: str @@ -16,7 +16,7 @@ i: Int = res.unwrap() f: Result(Float, FloatParseError) = s. parse Float ``` -您还可以使用 `try_from` 方法。 +您還可以使用 `try_from` 方法。 ```python s: Str diff --git a/doc/zh_TW/python/bytecode_instructions.md b/doc/zh_TW/python/bytecode_instructions.md index c93ec1eb..47e3ae8f 100644 --- a/doc/zh_TW/python/bytecode_instructions.md +++ b/doc/zh_TW/python/bytecode_instructions.md @@ -1,16 +1,16 @@ -# Python 字节码指令 +# Python 字節碼指令 -Python 字节码变量操作命令通过 名称索引(名称索引)访问。 这是为了在 Python 中实现动态变量访问(可以使用 eval 等作为字符串访问)。 -一条指令为 2 个字节,指令和参数以 little endian 形式存储。 -不带参数的指令也使用 2 个字节(参数部分为 0)。 +Python 字節碼變量操作命令通過 名稱索引(名稱索引)訪問。 這是為了在 Python 中實現動態變量訪問(可以使用 eval 等作為字符串訪問)。 +一條指令為 2 個字節,指令和參數以 little endian 形式存儲。 +不帶參數的指令也使用 2 個字節(參數部分為 0)。 -## STORE_NAME(名称索引) +## STORE_NAME(名稱索引) ```python globals[namei] = stack.pop() ``` -## LOAD_NAME(名称索引) +## LOAD_NAME(名稱索引) ```python stack.push(globals[namei]) @@ -18,22 +18,22 @@ stack.push(globals[namei]) Only called at top level. -## LOAD_GLOBAL(名称索引) +## LOAD_GLOBAL(名稱索引) ```python stack.push(globals[namei]) ``` -用于加载内部作用域顶层的STORE_NAME,但顶层的`名称索引`不一定与某个作用域的代码对象中的名称索引相同(名称相同,名称索引不一定) +用于加載內部作用域頂層的STORE_NAME,但頂層的`名稱索引`不一定與某個作用域的代碼對象中的名稱索引相同(名稱相同,名稱索引不一定) -## LOAD_CONST(名称索引) +## LOAD_CONST(名稱索引) ```python stack.push(consts[namei]) ``` -在常量表中加载常量。 -目前(Python 3.9),在 CPython 中,每个 lambda 函数都是 MAKE_FUNCTION,名称为“\” +在常量表中加載常量。 +目前(Python 3.9),在 CPython 中,每個 lambda 函數都是 MAKE_FUNCTION,名稱為“\” ```console >>> dis.dis("[1,2,3].map(lambda x: x+1)") @@ -49,68 +49,68 @@ stack.push(consts[namei]) 18 RETURN_VALUE ``` -## STORE_FAST(名称索引) +## STORE_FAST(名稱索引) fastlocals[namei] = stack.pop() -可能对应于顶层的 STORE_NAME -假定未引用(或单个)变量由此存储 -全局空间有自己的指令是为了优化吗? +可能對應于頂層的 STORE_NAME +假定未引用(或單個)變量由此存儲 +全局空間有自己的指令是為了優化嗎? -## LOAD_FAST(名称索引) +## LOAD_FAST(名稱索引) ```python stack.push(fastlocals[namei]) ``` -fastlocals 是变量名吗? +fastlocals 是變量名嗎? -## LOAD_CLOSURE(名称索引) +## LOAD_CLOSURE(名稱索引) ```python cell = freevars[namei] stack. push(cell) ``` -然后调用 BUILD_TUPLE -它只在闭包内被调用,并且 cellvars 应该在闭包内存储引用。 -与 LOAD_DEREF 不同,每个单元格(填充有引用的容器)都被推入堆栈 +然后調用 BUILD_TUPLE +它只在閉包內被調用,并且 cellvars 應該在閉包內存儲引用。 +與 LOAD_DEREF 不同,每個單元格(填充有引用的容器)都被推入堆棧 -## STORE_DEREF(名称索引) +## STORE_DEREF(名稱索引) ```python cell = freevars[namei] cell.set(stack.pop()) ``` -在内部范围内没有引用的变量是 STORE_FAST,但引用的变量是 STORE_DEREF -在 Python 中,引用计数在该指令内递增和递减 +在內部范圍內沒有引用的變量是 STORE_FAST,但引用的變量是 STORE_DEREF +在 Python 中,引用計數在該指令內遞增和遞減 -## LOAD_DEREF(名称索引) +## LOAD_DEREF(名稱索引) ```python cell = freevars[namei] stack.push(cell.get()) ``` -## 名称列表 +## 名稱列表 -### 变量名 +### 變量名 -fast_locals 对应的函数内部变量名称列表 -即使名称中有同名的变量,它们也基本不一样(新创建的和外部变量不能从那个范围访问) -即没有在范围内定义的外部引用的变量进入 varnames +fast_locals 對應的函數內部變量名稱列表 +即使名稱中有同名的變量,它們也基本不一樣(新創建的和外部變量不能從那個范圍訪問) +即沒有在范圍內定義的外部引用的變量進入 varnames ### 名字 -与全局兼容 -范围内使用的外部常量(仅引用)的名称列表(在顶层,即使是普通变量也包含在名称中) -即在范围之外定义的常量进入名称 +與全局兼容 +范圍內使用的外部常量(僅引用)的名稱列表(在頂層,即使是普通變量也包含在名稱中) +即在范圍之外定義的常量進入名稱 -## 自由变量 +## 自由變量 -与免费变量兼容 -闭包捕获的变量。它在同一个函数实例中静态地运行。 +與免費變量兼容 +閉包捕獲的變量。它在同一個函數實例中靜態地運行。 -## 单元格变量 +## 單元格變量 -对应于 cellvars -在函数内捕获到内部闭包函数的变量。 由于制作了副本,因此原始变量保持原样。 \ No newline at end of file +對應于 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 index 86fd9c27..d0a56f9c 100644 --- a/doc/zh_TW/python/bytecode_specification.md +++ b/doc/zh_TW/python/bytecode_specification.md @@ -36,7 +36,7 @@ ## PyStringObject * If I use a character other than ascii, does it become PyUnicode? -* "あ", "𠮷", and "α" are PyUnicode (no longer used?) +* "あ", "??", and "α" are PyUnicode (no longer used?) * 0 byte: 0x73 (means 's') * 1~4 byte: length of string @@ -71,74 +71,74 @@ * 5~ byte: payload -# Python 字节码规范 +# Python 字節碼規范 ## 格式 -* 0~3 byte(u32):幻数(详见common/bytecode.rs) +* 0~3 byte(u32):幻數(詳見common/bytecode.rs) * 4~7 byte(u32): 0 padding -* 8~12 byte(u32): 时间戳 -* 13~ byte(PyCodeObject): 代码对象 +* 8~12 byte(u32): 時間戳 +* 13~ byte(PyCodeObject): 代碼對象 -## PyCode 对象 +## PyCode 對象 -* 0 byte(u8): '0xe3' (前缀,这意味着代码的'c') -* 01~04 byte(u32): args个数(co_argcount) -* 05~08 byte(u32): position-only args 的数量 (co_posonlyargcount) -* 09~12 byte(u32):仅关键字参数的数量(co_kwonlyargcount) -* 13~16 byte(u32): 本地数 (co_nlocals) -* 17~20 byte(u32): 栈大小(co_stacksize) -* 21~24 byte(u32):标志(co_flags)() -* ? byte:字节码指令,以'0x53'、'0x0'结尾(83, 0):RETURN_VALUE(co_code) -* ? byte(PyTuple):代码中使用的常量(co_consts) -* ? byte(PyTuple):代码中使用的名称(co_names) -* ? byte(PyTuple):代码中定义的变量名,包括params (PyTuple) (co_varnames) -* ? byte(PyTuple):从外部范围捕获的变量(co_freevars) -* ? byte(PyTuple):内部闭包中使用的变量(co_cellvars) -* ? byte(PyUnicode 或 PyShortAscii):文件名,它是从哪里加载的(co_filename) -* ? byte(PyUnicode or PyShortAscii): 代码本身的名字,默认是\ (co_name) -* ?~?+3 byte(u32): 第一行数 (co_firstlineno) +* 0 byte(u8): '0xe3' (前綴,這意味著代碼的'c') +* 01~04 byte(u32): args個數(co_argcount) +* 05~08 byte(u32): position-only args 的數量 (co_posonlyargcount) +* 09~12 byte(u32):僅關鍵字參數的數量(co_kwonlyargcount) +* 13~16 byte(u32): 本地數 (co_nlocals) +* 17~20 byte(u32): 棧大小(co_stacksize) +* 21~24 byte(u32):標志(co_flags)() +* ? byte:字節碼指令,以'0x53'、'0x0'結尾(83, 0):RETURN_VALUE(co_code) +* ? byte(PyTuple):代碼中使用的常量(co_consts) +* ? byte(PyTuple):代碼中使用的名稱(co_names) +* ? byte(PyTuple):代碼中定義的變量名,包括params (PyTuple) (co_varnames) +* ? byte(PyTuple):從外部范圍捕獲的變量(co_freevars) +* ? byte(PyTuple):內部閉包中使用的變量(co_cellvars) +* ? byte(PyUnicode 或 PyShortAscii):文件名,它是從哪里加載的(co_filename) +* ? byte(PyUnicode or PyShortAscii): 代碼本身的名字,默認是\ (co_name) +* ?~?+3 byte(u32): 第一行數 (co_firstlineno) * ? byte(bytes):行表,用 PyStringObject? (co_lnotab) ## PyTupleObject * 0 byte: 0x29 (意思是:')') -* 01~04 byte(u32): 元组项数 -* ? byte(PyObject):项目 +* 01~04 byte(u32): 元組項數 +* ? byte(PyObject):項目 -## PyString 对象 +## PyString 對象 -* 如果我使用 ascii 以外的字符,它会变成 PyUnicode 吗? -* “あ”、“𠮷”和“α”是 PyUnicode(不再使用?) +* 如果我使用 ascii 以外的字符,它會變成 PyUnicode 嗎? +* “あ”、“??”和“α”是 PyUnicode(不再使用?) * 0 byte:0x73(表示's') -* 1~4 byte:字符串长度 -* 5~ byte:有效载荷 +* 1~4 byte:字符串長度 +* 5~ byte:有效載荷 -## PyUnicode 对象 +## PyUnicode 對象 * 0 byte:0x75(表示“u”) -* 1~4 byte:字符串长度 -* 5~ byte:有效载荷 +* 1~4 byte:字符串長度 +* 5~ byte:有效載荷 ## PyShortAsciiObject -* 这叫短,但是即使超过100个字符,仍然会保持在短的状态 -* 或者更确切地说,没有不短的 ascii(短数据类型吗?) +* 這叫短,但是即使超過100個字符,仍然會保持在短的狀態 +* 或者更確切地說,沒有不短的 ascii(短數據類型嗎?) * 0 byte:0xFA(表示“z”) -* 1~4 byte:字符串长度 -* 5~ byte:有效载荷 +* 1~4 byte:字符串長度 +* 5~ byte:有效載荷 ## PyInternedObject -* 实习对象注册在专用地图中,可以与is进行比较 -* 例如字符串,无论其长度如何,都可以在恒定时间内进行比较 +* 實習對象注冊在專用地圖中,可以與is進行比較 +* 例如字符串,無論其長度如何,都可以在恒定時間內進行比較 * 0 byte:0x74(表示't') ## PyShortAsciiInternedObject * 0 byte:0xDA(表示“Z”) -* 1~4 byte:字符串长度 -* 5~ byte:有效载荷 \ No newline at end of file +* 1~4 byte:字符串長度 +* 5~ byte:有效載荷 \ No newline at end of file diff --git a/doc/zh_TW/python/class_system.md b/doc/zh_TW/python/class_system.md index 6623395d..8453038a 100644 --- a/doc/zh_TW/python/class_system.md +++ b/doc/zh_TW/python/class_system.md @@ -1,10 +1,10 @@ -# Python 类系统(与 Erg 比较) +# Python 類系統(與 Erg 比較) ## 方法 -方法可以被前向引用,但这不是一种特殊的技术。 -这是因为动态检查方法的存在。 -(在 Erg 中,方法存在是静态检查的。对于前向引用,函数必须是常量。) +方法可以被前向引用,但這不是一種特殊的技術。 +這是因為動態檢查方法的存在。 +(在 Erg 中,方法存在是靜態檢查的。對于前向引用,函數必須是常量。) ```python >>> class C: @@ -14,10 +14,10 @@ ... def g(self, x): return self.f(x - 1) ``` -## 继承,覆盖 +## 繼承,覆蓋 -一些被覆盖的方法 m 被简单地覆盖,就像变量重新分配一样。 -在父类中引用 m 的方法将在子类中引用被覆盖的 m。 +一些被覆蓋的方法 m 被簡單地覆蓋,就像變量重新分配一樣。 +在父類中引用 m 的方法將在子類中引用被覆蓋的 m。 ```python >>> class C: @@ -31,7 +31,7 @@ 2 ``` -因此,即使它显然被错误地覆盖,直到运行时才会出错。 +因此,即使它顯然被錯誤地覆蓋,直到運行時才會出錯。 ```python >>>> class C: @@ -45,11 +45,11 @@ Traceback (most recent call last): File "", line 1, in ", line 3, in g -类型错误:只能将str(不是“int”)连接到str +類型錯誤:只能將str(不是“int”)連接到str ``` -Erg 静态检查与父类的一致性。 -重写时必须给出“Override”装饰器,并且重写函数的类型必须是被重写函数类型的子类型。 +Erg 靜態檢查與父類的一致性。 +重寫時必須給出“Override”裝飾器,并且重寫函數的類型必須是被重寫函數類型的子類型。 ```python >>> C = Class() @@ -59,15 +59,15 @@ Erg 静态检查与父类的一致性。 >>> D = Inherit C ... .f self = "a" ... -错误[#XX]:文件“”,第 5 行,在 D 中 -要覆盖 f,必须添加 `Override` 装饰器,其类型必须是 `Self.() -> Nat` 或其子类型 -f(self) 已在 C 中定义。要覆盖 f,必须添加 `Override` 装饰器,其类型必须为 `Self. 要覆盖,必须给它一个 `Override` 装饰器,并且它的类型必须是 `Self.() -> Nat` 或 that.f(self) 的子类型。 +錯誤[#XX]:文件“”,第 5 行,在 D 中 +要覆蓋 f,必須添加 `Override` 裝飾器,其類型必須是 `Self.() -> Nat` 或其子類型 +f(self) 已在 C 中定義。要覆蓋 f,必須添加 `Override` 裝飾器,其類型必須為 `Self. 要覆蓋,必須給它一個 `Override` 裝飾器,并且它的類型必須是 `Self.() -> Nat` 或 that.f(self) 的子類型。 ``` -## 类型检查 +## 類型檢查 -类型检查通常都是关于检查函数参数的类型。 -在 Python 中,大多数操作都是方法调用。 如果对象所属的类在调用时没有附加方法,就是这样。 +類型檢查通常都是關于檢查函數參數的類型。 +在 Python 中,大多數操作都是方法調用。 如果對象所屬的類在調用時沒有附加方法,就是這樣。 ```python def f(x): @@ -78,7 +78,7 @@ class C: c = C() f(c) -f(1) # 类型错误 +f(1) # 類型錯誤 ``` ```python @@ -90,5 +90,5 @@ C.m(self) = None c = C.new() f(c) -f(1) # 类型错误:f 将具有方法 `.m` 的类型作为参数,但传递了 Nat +f(1) # 類型錯誤:f 將具有方法 `.m` 的類型作為參數,但傳遞了 Nat ``` diff --git a/doc/zh_TW/syntax/00_basic.md b/doc/zh_TW/syntax/00_basic.md index b640f7fc..0353c0fa 100644 --- a/doc/zh_TW/syntax/00_basic.md +++ b/doc/zh_TW/syntax/00_basic.md @@ -1,46 +1,46 @@ # 基本 -> __Warning__:本文档不完整。 它未经校对(样式、正确链接、误译等)。 此外,Erg 的语法可能在版本 0.* 期间发生破坏性更改,并且文档可能没有相应更新。 请事先了解这一点。 -> 如果您在本文档中发现任何错误,请报告至 [此处的表单](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我们将不胜感激您的建议。 +> __Warning__:本文檔不完整。 它未經校對(樣式、正確鏈接、誤譯等)。 此外,Erg 的語法可能在版本 0.* 期間發生破壞性更改,并且文檔可能沒有相應更新。 請事先了解這一點。 +> 如果您在本文檔中發現任何錯誤,請報告至 [此處的表單](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我們將不勝感激您的建議。 > > [Erg原版(日文)](http://mtshiba.me/TheErgBook/) -本文档描述 Erg 的基本语法。 [标准 API](./API/index.md) 和 [Erg 贡献者的内部文档](./dev_guide/index.md) 位于另一个目录中。 +本文檔描述 Erg 的基本語法。 [標準 API](./API/index.md) 和 [Erg 貢獻者的內部文檔](./dev_guide/index.md) 位于另一個目錄中。 ## 你好,世界! -首先,让我们做“Hello World”。 +首先,讓我們做“Hello World”。 ```python print!("Hello, World!") ``` -这与 Python 和同一家族中的其他语言几乎相同。 最显着的特征是`!`,后面会解释它的含义。 -在 Erg 中,括号 `()` 可以省略,除非在解释上有一些混淆。 -括号的省略与 Ruby 类似,但不能省略可以以多种方式解释的括号。 +這與 Python 和同一家族中的其他語言幾乎相同。 最顯著的特征是`!`,后面會解釋它的含義。 +在 Erg 中,括號 `()` 可以省略,除非在解釋上有一些混淆。 +括號的省略與 Ruby 類似,但不能省略可以以多種方式解釋的括號。 ```python print! "Hello, World!" # OK print! "Hello,", "World!" # OK print!() # OK -print! # OK, 但这并不意味着调用,只是将 `print!` 作为可调用对象 +print! # OK, 但這并不意味著調用,只是將 `print!` 作為可調用對象 -print! f x # OK, 解释为 `print!(f(x))` +print! f x # OK, 解釋為 `print!(f(x))` print!(f(x, y)) # OK print! f(x, y) # OK print! f(x, g y) # OK -print! f x, y # NG, 可以理解为 `print!(f(x), y)` 或 `print!(f(x, y))` print! +print! f x, y # NG, 可以理解為 `print!(f(x), y)` 或 `print!(f(x, y))` print! print!(f x, y) # NG, 可以表示“print!(f(x),y)”或“print!(f(x,y))” print! f(x, g y, z) # NG, 可以表示“print!(x,g(y),z)”或“print!(x,g(y,z))” ``` -## 脚本 +## 腳本 -Erg 代码称为脚本。 脚本可以以文件格式 (.er) 保存和执行。 +Erg 代碼稱為腳本。 腳本可以以文件格式 (.er) 保存和執行。 -## REPL/文件执行 +## REPL/文件執行 -要启动 REPL,只需键入: +要啟動 REPL,只需鍵入: ```sh > erg @@ -66,9 +66,9 @@ Or you can compile from a file. hello, world! ``` -## 注释 +## 注釋 -`#` 之后的代码作为注释被忽略。 使用它来解释代码的意图或暂时禁用代码。 +`#` 之后的代碼作為注釋被忽略。 使用它來解釋代碼的意圖或暫時禁用代碼。 ```python # Comment @@ -79,21 +79,21 @@ Treated as a comment all the way up to the corresponding `]#` ]# ``` -## 表达式,分隔符 +## 表達式,分隔符 -脚本是一系列表达式。 表达式是可以计算或评估的东西,在 Erg 中几乎所有东西都是表达式。 -每个表达式由分隔符分隔 - 新行或分号 `;`-。 -Erg 脚本基本上是从左到右、从上到下进行评估的。 +腳本是一系列表達式。 表達式是可以計算或評估的東西,在 Erg 中幾乎所有東西都是表達式。 +每個表達式由分隔符分隔 - 新行或分號 `;`-。 +Erg 腳本基本上是從左到右、從上到下進行評估的。 ```python -n = 1 # 赋值表达式 -f(1, 2) # 函数调用表达式 -1 + 1 # 运算符调用表达式 +n = 1 # 賦值表達式 +f(1, 2) # 函數調用表達式 +1 + 1 # 運算符調用表達式 f(1, 2); 1 + 1 ``` -如下所示,有一种称为 Instant block 的语法,它将块中评估的最后一个表达式作为变量的值。 -这与没有参数的函数不同,它不添加 `()`。 请注意,即时块仅在运行中评估一次 +如下所示,有一種稱為 Instant block 的語法,它將塊中評估的最后一個表達式作為變量的值。 +這與沒有參數的函數不同,它不添加 `()`。 請注意,即時塊僅在運行中評估一次 ```python i = @@ -102,15 +102,15 @@ i = assert i == 2 ``` -这不能用分号 (`;`) 完成。 +這不能用分號 (`;`) 完成。 ```python -i = (x = 1; x + 1) # 语法错误:不能在括号中使用 `;` +i = (x = 1; x + 1) # 語法錯誤:不能在括號中使用 `;` ``` -## 缩进 +## 縮進 -Erg 和 Python 一样,使用缩进来表示块。 有五个运算符(特殊形式)触发块的开始:`=`、`->`、`=>`、`do` 和 `do!`(此外,`:` 和 `|` ,虽然不是运算符,但也会产生缩进)。 每个的含义将在后面描述。 +Erg 和 Python 一樣,使用縮進來表示塊。 有五個運算符(特殊形式)觸發塊的開始:`=`、`->`、`=>`、`do` 和 `do!`(此外,`:` 和 `|` ,雖然不是運算符,但也會產生縮進)。 每個的含義將在后面描述。 ```python f x, y = @@ -129,20 +129,20 @@ ans = match x: _ -> "unknown" ``` -如果一行太长,可以使用 `\` 将其断开 +如果一行太長,可以使用 `\` 將其斷開 ```python -# 这不是表示 `x + y + z` 而是表示 `x; +y; +z` +# 這不是表示 `x + y + z` 而是表示 `x; +y; +z` X + y + z -# 这意味着`x + y + z` +# 這意味著`x + y + z` x \ + y \ + z ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/01_literal.md b/doc/zh_TW/syntax/01_literal.md index a285d8d3..44b9610e 100644 --- a/doc/zh_TW/syntax/01_literal.md +++ b/doc/zh_TW/syntax/01_literal.md @@ -2,7 +2,7 @@ ## 基本字面量 -### 整数字面量 +### 整數字面量 ```python 0, -0, 1, -1, 2, -2, 3, -3, ... @@ -14,27 +14,27 @@ 0.00, -0.0, 0.1, 400.104, ... ``` -如果“比率”文字的整数或小数部分为`0`,则可以省略`0` +如果“比率”文字的整數或小數部分為`0`,則可以省略`0` ```python assert 1.0 == 1. assert 0.5 == .5 ``` -> __注意__:这个函数 `assert` 用于表明 `1.0` 和 `1.` 相等。 -后续文档可能会使用 `assert` 来表示结果是相等的。 +> __注意__:這個函數 `assert` 用于表明 `1.0` 和 `1.` 相等。 +后續文檔可能會使用 `assert` 來表示結果是相等的。 ### 字符串字面量 可以使用任何 Unicode 可表示的字符串。 -与 Python 不同,引号不能包含在 `'` 中。 如果要在字符串中使用 `"`,请使用 `\"`。 +與 Python 不同,引號不能包含在 `'` 中。 如果要在字符串中使用 `"`,請使用 `\"`。 ```python -"", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "السَّلَامُ عَلَيْكُمْ", ... +"", "a", "abc", "111", "1# 3f2-3*8$", "こんにちは", "?????????? ??????????", ... ``` -`{}` 允许您在字符串中嵌入表达式。 这称为字符串插值。 -如果要输出 `{`、`}` 本身,请使用 `\{`、`\}`。 +`{}` 允許您在字符串中嵌入表達式。 這稱為字符串插值。 +如果要輸出 `{`、`}` 本身,請使用 `\{`、`\}`。 ```python assert "1 + 1 is 2" == "{1} + {1} is {1+1}" @@ -42,10 +42,10 @@ s = "1+1" assert "\{1+1}\" == "\{{s}\}" ``` -### 指数字面量 +### 指數字面量 -这是学术计算中常用的表示指数符号的文字。 它是“比率”类型的一个实例。 -该符号与 Python 中的符号相同。 +這是學術計算中常用的表示指數符號的文字。 它是“比率”類型的一個實例。 +該符號與 Python 中的符號相同。 ```python 1e-34, 0.4e-10, 2.455+e5, 245e5, 25E5, ... @@ -55,11 +55,11 @@ assert "\{1+1}\" == "\{{s}\}" assert 1e-10 == 0.0000000001 ``` -## 复合字面量 +## 復合字面量 -这些文字中的每一个都有自己的文档分别描述它们,因此请参阅该文档以获取详细信息。 +這些文字中的每一個都有自己的文檔分別描述它們,因此請參閱該文檔以獲取詳細信息。 -### [数组字面量](./10_array.md) +### [數組字面量](./10_array.md) ```python [], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ... @@ -71,7 +71,7 @@ assert 1e-10 == 0.0000000001 {:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ... ``` -### [元组字面量](./12_tuple.md) +### [元組字面量](./12_tuple.md) ```python (), (1, 2, 3), (1, "hello", True), ... @@ -89,27 +89,27 @@ assert 1e-10 == 0.0000000001 {}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ... ``` -与 `Array` 字面量不同的是,`Set` 中删除了重复元素 +與 `Array` 字面量不同的是,`Set` 中刪除了重復元素 ```python assert {1, 2, 1} == {1, 2} ``` -### 看起来像文字但不是 +### 看起來像文字但不是 -## 布尔对象 +## 布爾對象 ```python True, False ``` -### None 对象 +### None 對象 ```python None ``` -## Range 对象 +## Range 對象 ```python assert 0..5 == {1, 2, 3, 4, 5} @@ -118,27 +118,27 @@ assert 0..<10 notin 10 assert 0..9 == 0..<10 ``` -## Float 对象 +## Float 對象 ```python assert 0.0f64 == 0 assert 0.0f32 == 0.0f64 ``` -浮点对象是通过将 `Ratio` 对象乘以 `f64` 构造的,后者是 `Float 64` 单位对象 +浮點對象是通過將 `Ratio` 對象乘以 `f64` 構造的,后者是 `Float 64` 單位對象 -## Complex 对象 +## Complex 對象 ```python 1+2im, 0.4-1.2im, 0im, im ``` -一个“复杂”对象只是一个虚数单位对象`im`的算术组合 +一個“復雜”對象只是一個虛數單位對象`im`的算術組合 ## *-less 乘法 -在 Erg 中,您可以省略 `*` 来表示乘法,只要解释上没有混淆即可。 但是,运算符的组合强度设置为强于 `*`。 +在 Erg 中,您可以省略 `*` 來表示乘法,只要解釋上沒有混淆即可。 但是,運算符的組合強度設置為強于 `*`。 ```python # same as `assert (1*m) / (1*s) == 1*(m/s)` @@ -146,5 +146,5 @@ assert 1m / 1s == 1 (m/s) ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/02_name.md b/doc/zh_TW/syntax/02_name.md index cbb0ef36..336458f2 100644 --- a/doc/zh_TW/syntax/02_name.md +++ b/doc/zh_TW/syntax/02_name.md @@ -1,81 +1,81 @@ -# 多变的 +# 多變的 -变量是一种代数; Erg 中的代数 - 如果没有混淆,有时简称为变量 - 指的是命名对象并使它们可从代码的其他地方引用的功能。 +變量是一種代數; Erg 中的代數 - 如果沒有混淆,有時簡稱為變量 - 指的是命名對象并使它們可從代碼的其他地方引用的功能。 -变量定义如下。 -`n` 部分称为变量名(或标识符),`=` 是赋值运算符,`1` 部分是赋值。 +變量定義如下。 +`n` 部分稱為變量名(或標識符),`=` 是賦值運算符,`1` 部分是賦值。 ```python n = 1 ``` -以这种方式定义的“n”此后可以用作表示整数对象“1”的变量。 该系统称为分配(或绑定)。 -我们刚刚说过`1`是一个对象。 稍后我们将讨论对象是什么,但现在我们假设它是可以赋值的,即在赋值运算符的右侧(`=` 等)。 +以這種方式定義的“n”此后可以用作表示整數對象“1”的變量。 該系統稱為分配(或綁定)。 +我們剛剛說過`1`是一個對象。 稍后我們將討論對象是什么,但現在我們假設它是可以賦值的,即在賦值運算符的右側(`=` 等)。 -如果要指定变量的“类型”,请执行以下操作。 类型大致是一个对象所属的集合,后面会解释。 -这里我们指定`n`是自然数(`Nat`)类型。 +如果要指定變量的“類型”,請執行以下操作。 類型大致是一個對象所屬的集合,后面會解釋。 +這里我們指定`n`是自然數(`Nat`)類型。 ```python n: Nat = 1 ``` -请注意,与其他语言不同,不允许多次分配 +請注意,與其他語言不同,不允許多次分配 ```python # NG -l1 = l2 = [1, 2, 3] # 语法错误:不允许多重赋值 +l1 = l2 = [1, 2, 3] # 語法錯誤:不允許多重賦值 # OK l1 = [1, 2, 3] l2 = l1.clone() ``` -也不能重新分配给变量。 稍后将描述可用于保存可变状态的语法 +也不能重新分配給變量。 稍后將描述可用于保存可變狀態的語法 ```python i = 1 -i = i + 1 # 分配错误:不能分配两次 +i = i + 1 # 分配錯誤:不能分配兩次 ``` -您可以在内部范围内定义具有相同名称的变量,但您只是覆盖它,而不是破坏性地重写它的值。 如果您返回外部范围,该值也会返回。 -请注意,这是与 Python “语句”范围不同的行为。 -这种功能通常称为阴影。 但是,与其他语言中的阴影不同,您不能在同一范围内进行阴影。 +您可以在內部范圍內定義具有相同名稱的變量,但您只是覆蓋它,而不是破壞性地重寫它的值。 如果您返回外部范圍,該值也會返回。 +請注意,這是與 Python “語句”范圍不同的行為。 +這種功能通常稱為陰影。 但是,與其他語言中的陰影不同,您不能在同一范圍內進行陰影。 ```python x = 0 -# x = 1 # 赋值错误:不能赋值两次 +# x = 1 # 賦值錯誤:不能賦值兩次 if x.is_zero(), do: - x = 1 # 与同名的外部 x 不同 + x = 1 # 與同名的外部 x 不同 assert x == 1 assert x == 0 ``` -乍一看,以下内容似乎可行,但仍然不可能。 这是一个设计决定,而不是技术限制。 +乍一看,以下內容似乎可行,但仍然不可能。 這是一個設計決定,而不是技術限制。 ```python x = 0 if x.is_zero(), do: - x = x + 1 # 名称错误:无法定义变量引用同名变量 + x = x + 1 # 名稱錯誤:無法定義變量引用同名變量 assert x == 1 assert x == 0 ``` ## 常量 -常数也是一种代数。 如果标识符以大写字母开头,则将其视为常量。 它们被称为常量,因为一旦定义,它们就不会改变。 -`N` 部分称为常量名(或标识符)。 否则,它与变量相同。 +常數也是一種代數。 如果標識符以大寫字母開頭,則將其視為常量。 它們被稱為常量,因為一旦定義,它們就不會改變。 +`N` 部分稱為常量名(或標識符)。 否則,它與變量相同。 ```python N = 0 if True, do: - N = 1 # 赋值错误:常量不能被遮蔽 + N = 1 # 賦值錯誤:常量不能被遮蔽 pass() ``` -常量在定义的范围之外是不可变的。 他们不能被遮蔽。 由于这个属性,常量可以用于模式匹配。 模式匹配在后面解释。 +常量在定義的范圍之外是不可變的。 他們不能被遮蔽。 由于這個屬性,常量可以用于模式匹配。 模式匹配在后面解釋。 -例如,常量用于数学常量、有关外部资源的信息和其他不可变值。 +例如,常量用于數學常量、有關外部資源的信息和其他不可變值。 -除了 [types](./type/01_type_system.md) 之外的对象标识符使用全大写(所有字母大写的样式)是常见的做法。 +除了 [types](./type/01_type_system.md) 之外的對象標識符使用全大寫(所有字母大寫的樣式)是常見的做法。 ```python PI = 3.141592653589793 @@ -90,19 +90,19 @@ match! x: other => print! "other" ``` -当 `x` 为 `3.141592653589793` 时,上面的代码会打印 `π`。 如果 `x` 更改为任何其他数字,它会打印 `other`。 +當 `x` 為 `3.141592653589793` 時,上面的代碼會打印 `π`。 如果 `x` 更改為任何其他數字,它會打印 `other`。 -有些对象不能绑定为常量。 例如,可变对象。 可变对象是其状态可以改变的对象,后面会详细介绍。 -这是因为只有常量表达式才能分配给常量的规则。 常量表达式也将在后面讨论。 +有些對象不能綁定為常量。 例如,可變對象。 可變對象是其狀態可以改變的對象,后面會詳細介紹。 +這是因為只有常量表達式才能分配給常量的規則。 常量表達式也將在后面討論。 ```python X = 1 # OK -X = !1 # 类型错误:无法定义 Int! 对象作为常量 +X = !1 # 類型錯誤:無法定義 Int! 對象作為常量 ``` -## 删除变量 +## 刪除變量 -您可以使用 `Del` 函数删除变量。 依赖于变量的所有其他变量(即直接引用变量值的变量)也将被删除。 +您可以使用 `Del` 函數刪除變量。 依賴于變量的所有其他變量(即直接引用變量值的變量)也將被刪除。 ```python x = 1 @@ -114,19 +114,19 @@ assert f(2) == 3 Del x Del y, Z -f(2) # 名称错误:f 未定义(在第 6 行中删除) +f(2) # 名稱錯誤:f 未定義(在第 6 行中刪除) ``` -注意 `Del` 只能删除用户自定义模块中定义的变量。 无法删除诸如“True”之类的内置常量。 +注意 `Del` 只能刪除用戶自定義模塊中定義的變量。 無法刪除諸如“True”之類的內置常量。 ```python -Del True # 类型错误:无法删除内置常量 -Del print! # TypeError: 无法删除内置变量 +Del True # 類型錯誤:無法刪除內置常量 +Del print! # TypeError: 無法刪除內置變量 ``` -## 附录:赋值和等价 +## 附錄:賦值和等價 -请注意,当 `x = a` 时,`x == a` 不一定为真。 一个例子是`Float.NaN`。 这是 IEEE 754 定义的浮点数的正式规范。 +請注意,當 `x = a` 時,`x == a` 不一定為真。 一個例子是`Float.NaN`。 這是 IEEE 754 定義的浮點數的正式規范。 ```python x = Float.NaN @@ -134,31 +134,31 @@ assert x ! = NaN assert x ! = x ``` -还有其他对象首先没有定义等价关系。 +還有其他對象首先沒有定義等價關系。 ```python f = x -> x**2 + 2x + 1 g = x -> (x + 1)**2 -f == g # 类型错误:无法比较函数对象 +f == g # 類型錯誤:無法比較函數對象 C = Class {i: Int} D = Class {i: Int} -C == D # 类型错误:无法比较类对象 +C == D # 類型錯誤:無法比較類對象 ``` -严格来说,`=` 不会将右侧的值直接分配给左侧的标识符。 -在函数和类对象的情况下,执行“修改”,例如将变量名称信息赋予对象。 但是,结构类型并非如此。 +嚴格來說,`=` 不會將右側的值直接分配給左側的標識符。 +在函數和類對象的情況下,執行“修改”,例如將變量名稱信息賦予對象。 但是,結構類型并非如此。 ```python f x = x -print! f # <函数 f> +print! f # <函數 f> g x = x + 1 -print! g # <函数 g> +print! g # <函數 g> C = Class {i: Int} -print! C # <类 C> +print! C # <類 C> ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/03_declaration.md b/doc/zh_TW/syntax/03_declaration.md index 458c4097..7de06ec0 100644 --- a/doc/zh_TW/syntax/03_declaration.md +++ b/doc/zh_TW/syntax/03_declaration.md @@ -1,12 +1,12 @@ # 宣言(Declaration) -声明是用于指定要使用的变量类型的语法。 -可以在代码中的任何地方进行声明,但单独的声明并不引用变量。 它们必须被初始化。 -分配后,可以检查声明以确保类型与分配它的对象兼容。 +聲明是用于指定要使用的變量類型的語法。 +可以在代碼中的任何地方進行聲明,但單獨的聲明并不引用變量。 它們必須被初始化。 +分配后,可以檢查聲明以確保類型與分配它的對象兼容。 ```python i: Int -# 可以与赋值同时声明,如 i: Int = 2 +# 可以與賦值同時聲明,如 i: Int = 2 i = 2 i: Num i: Nat @@ -14,24 +14,24 @@ i: -2..2 i: {2} ``` -赋值后的声明类似于`assert`的类型检查,但具有在编译时检查的特点。 -在运行时通过`assert`进行类型检查可以检查“可能是Foo类型”,但是在编译时通过`:`进行类型检查是严格的:如果类型未确定为“类型Foo”,则不会通过 检查会出现错误。 +賦值后的聲明類似于`assert`的類型檢查,但具有在編譯時檢查的特點。 +在運行時通過`assert`進行類型檢查可以檢查“可能是Foo類型”,但是在編譯時通過`:`進行類型檢查是嚴格的:如果類型未確定為“類型Foo”,則不會通過 檢查會出現錯誤。 ```python i = (-1..10).sample! -assert i in Nat # 这可能会通过 -i: Int # 这会通过 -i: Nat # 这不会通过(-1 不是 Nat 的元素) +assert i in Nat # 這可能會通過 +i: Int # 這會通過 +i: Nat # 這不會通過(-1 不是 Nat 的元素) ``` -函数可以用两种不同的方式声明。 +函數可以用兩種不同的方式聲明。 ```python f: (x: Int, y: Int) -> Int f: (Int, Int) -> Int ``` -如果显式声明参数名称,如果在定义时名称不同,则会导致类型错误。 如果你想给参数名称任意命名,你可以用第二种方式声明它们。 在这种情况下,类型检查只会看到方法名称及其类型。 +如果顯式聲明參數名稱,如果在定義時名稱不同,則會導致類型錯誤。 如果你想給參數名稱任意命名,你可以用第二種方式聲明它們。 在這種情況下,類型檢查只會看到方法名稱及其類型。 ```python T = Trait { @@ -39,9 +39,9 @@ T = Trait { } C = Class(U, Impl := T) -C.f(a: Int, b: Int): Int = ... # 类型错误:`.f` 必须是 `(x: Int, y: Int) -> Int` 的类型,而不是 `(a: Int, b: Int) -> Int` +C.f(a: Int, b: Int): Int = ... # 類型錯誤:`.f` 必須是 `(x: Int, y: Int) -> Int` 的類型,而不是 `(a: Int, b: Int) -> Int` ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/04_function.md b/doc/zh_TW/syntax/04_function.md index 3dd6143c..02e4706e 100644 --- a/doc/zh_TW/syntax/04_function.md +++ b/doc/zh_TW/syntax/04_function.md @@ -1,6 +1,6 @@ # 功能 -函数是一个块,它接受一个“参数”,对其进行处理,并将其作为“返回值”返回。 定义如下。 +函數是一個塊,它接受一個“參數”,對其進行處理,并將其作為“返回值”返回。 定義如下。 ```python add x, y = x + y @@ -8,10 +8,10 @@ add x, y = x + y add(x, y) = x + y ``` -在函数名之后指定的名称称为参数。 -相反,传递给函数的对象称为参数。 -函数 `add` 是一个以 `x` 和 `y` 作为参数并返回它们之和的函数,`x + y`。 -可以按如下方式调用(应用/调用)定义的函数。 +在函數名之后指定的名稱稱為參數。 +相反,傳遞給函數的對象稱為參數。 +函數 `add` 是一個以 `x` 和 `y` 作為參數并返回它們之和的函數,`x + y`。 +可以按如下方式調用(應用/調用)定義的函數。 ```python add 1, 2 @@ -19,9 +19,9 @@ add 1, 2 add(1, 2) ``` -## 冒号应用风格 +## 冒號應用風格 -函数像`f x, y, ...`一样被调用,但是如果单行参数太多,可以使用`:`(冒号)来应用它们。 +函數像`f x, y, ...`一樣被調用,但是如果單行參數太多,可以使用`:`(冒號)來應用它們。 ```python f some_long_name_variable_1 + some_long_name_variable_2, some_long_name_variable_3 * some_long_name_variable_4 @@ -38,7 +38,7 @@ f: some_long_name_variable_3 * some_long_name_variable_4 ``` -以上三个代码的含义相同。 例如,这种风格在使用 `if` 函数时也很有用 +以上三個代碼的含義相同。 例如,這種風格在使用 `if` 函數時也很有用 ```python result = if Bool.sample!(): @@ -50,24 +50,24 @@ result = if Bool.sample!(): 0 ``` -在 `:` 之后,除了注释之外,不得编写任何代码,并且必须始终在新行上 +在 `:` 之后,除了注釋之外,不得編寫任何代碼,并且必須始終在新行上 -## 关键字参数 +## 關鍵字參數 -如果使用大量参数定义函数,则存在以错误顺序传递参数的危险。 -在这种情况下,使用关键字参数调用函数是安全的。 +如果使用大量參數定義函數,則存在以錯誤順序傳遞參數的危險。 +在這種情況下,使用關鍵字參數調用函數是安全的。 ```python f x, y, z, w, v, u: Int = ... ``` -上面定义的函数有很多参数,并且排列顺序混乱。 您不应该创建这样的函数,但是在使用别人编写的代码时可能会遇到这样的代码。 因此,我们使用关键字参数。 如果使用关键字参数,则值会从名称传递到正确的参数,即使它们的顺序错误。 +上面定義的函數有很多參數,并且排列順序混亂。 您不應該創建這樣的函數,但是在使用別人編寫的代碼時可能會遇到這樣的代碼。 因此,我們使用關鍵字參數。 如果使用關鍵字參數,則值會從名稱傳遞到正確的參數,即使它們的順序錯誤。 ```python f u: 6, v: 5, w: 4, x: 1, y: 2, z: 3 ``` -请注意,紧跟在 `:` 之后的关键字参数和新行被视为冒号调用样式 +請注意,緊跟在 `:` 之后的關鍵字參數和新行被視為冒號調用樣式 ```python # 意思是 `f(x: y)` @@ -78,11 +78,11 @@ f x: y ``` -## 定义错误参数 +## 定義錯誤參數 -当某些参数大部分是固定的并且您希望能够省略它们时,使用默认参数。 +當某些參數大部分是固定的并且您希望能夠省略它們時,使用默認參數。 -默认参数由`:=`(walrus运算符)指定。 如果未指定 `base`,则将 `math.E` 分配给 `base`。 +默認參數由`:=`(walrus運算符)指定。 如果未指定 `base`,則將 `math.E` 分配給 `base`。 ```python math_log x: Ratio, base := math.E = ... @@ -91,7 +91,7 @@ assert math_log(100, 10) == 2 assert math_log(100) == math_log(100, math.E) ``` -请注意,不指定参数和指定`None`是有区别的 +請注意,不指定參數和指定`None`是有區別的 ```python p! x := 0 = print! @@ -100,34 +100,34 @@ p!() # 0 p!(None) # None ``` -也可以与类型规范和模式一起使用 +也可以與類型規范和模式一起使用 ```python math_log x, base: Ratio := math.E = ... f [x, y] := [1, 2] = ... ``` -但是,在默认参数中,不能调用过程(稍后描述)或分配可变对象 +但是,在默認參數中,不能調用過程(稍后描述)或分配可變對象 ```python f x := p! 1 = ... # NG ``` -此外,刚刚定义的参数不能用作传递给默认参数的值 +此外,剛剛定義的參數不能用作傳遞給默認參數的值 ```python f x := 1, y := x = ... # NG ``` -## 可变长度参数 +## 可變長度參數 -输出其参数的日志(记录)的 `log` 函数可以采用任意数量的参数。 +輸出其參數的日志(記錄)的 `log` 函數可以采用任意數量的參數。 ```蟒蛇 -记录“你好”、“世界”、“!” # 你好世界 ! +記錄“你好”、“世界”、“!” # 你好世界 ! ``` -要定义这样的函数,请将 `...` 添加到参数中。 这样,函数将参数作为可变长度数组接收 +要定義這樣的函數,請將 `...` 添加到參數中。 這樣,函數將參數作為可變長度數組接收 ```python f ...x = @@ -138,7 +138,7 @@ f ...x = f 1, 2, 3, 4, 5 ``` -## 具有多种模式的函数定义 +## 具有多種模式的函數定義 ```python fib n: Nat = @@ -148,7 +148,7 @@ fib n: Nat = n -> fib(n - 1) + fib(n - 2) ``` -像上面这样的函数,其中 `match` 直接出现在定义下,可以重写如下 +像上面這樣的函數,其中 `match` 直接出現在定義下,可以重寫如下 ```python fib 0 = 0 @@ -156,26 +156,26 @@ fib 1 = 1 fib(n: Nat): Nat = fib(n - 1) + fib(n - 2) ``` -注意一个函数定义有多个模式不是所谓的重载(multiple definition); 一个函数只有一个定义。 在上面的示例中,“n”必须与“0”或“1”属于同一类型。 此外,与 `match` 一样,模式匹配是从上到下完成的。 +注意一個函數定義有多個模式不是所謂的重載(multiple definition); 一個函數只有一個定義。 在上面的示例中,“n”必須與“0”或“1”屬于同一類型。 此外,與 `match` 一樣,模式匹配是從上到下完成的。 -如果不同类的实例混合在一起,最后一个定义必须指定函数参数的类型为`Or` +如果不同類的實例混合在一起,最后一個定義必須指定函數參數的類型為`Or` ```python f "aa" = ... f 1 = ... -# `f x = ... ` 无效 +# `f x = ... ` 無效 f x: Int or Str = ... ``` -此外,像 `match` 一样,它也必须是详尽的。 +此外,像 `match` 一樣,它也必須是詳盡的。 ```python fib 0 = 0 fib 1 = 1 -# 模式错误:fib 参数的模式并不详尽 +# 模式錯誤:fib 參數的模式并不詳盡 ``` -但是,可以通过使用稍后描述的 [refinement type](./type/12_refinement.md) 显式指定类型来使其详尽无遗。 +但是,可以通過使用稍后描述的 [refinement type](./type/12_refinement.md) 顯式指定類型來使其詳盡無遺。 ```python fib: 0..1 -> 0..1 @@ -184,12 +184,12 @@ fib 1 = 1 # OK ``` -## 递归函数 +## 遞歸函數 -递归函数是在其定义中包含自身的函数。 +遞歸函數是在其定義中包含自身的函數。 -作为一个简单的例子,让我们定义一个执行阶乘计算的函数`factorial`。 阶乘是“将所有小于或等于的正数相乘”的计算。 -5 的阶乘是 `5*4*3*2*1 == 120`。 +作為一個簡單的例子,讓我們定義一個執行階乘計算的函數`factorial`。 階乘是“將所有小于或等于的正數相乘”的計算。 +5 的階乘是 `5*4*3*2*1 == 120`。 ```python factorial 0 = 1 @@ -197,13 +197,13 @@ factorial 1 = 1 factorial(n: Nat): Nat = n * factorial(n - 1) ``` -首先,从阶乘的定义来看,0和1的阶乘都是1。 -反过来,2的阶乘是`2*1 == 2`,3的阶乘是`3*2*1 == 6`,4的阶乘是`4*3*2*1 == 24 `。 -如果我们仔细观察,我们可以看到一个数 n 的阶乘是前一个数 n-1 乘以 n 的阶乘。 -将其放入代码中,我们得到 `n * factorial(n - 1)`。 -由于 `factorial` 的定义包含自身,`factorial` 是一个递归函数。 +首先,從階乘的定義來看,0和1的階乘都是1。 +反過來,2的階乘是`2*1 == 2`,3的階乘是`3*2*1 == 6`,4的階乘是`4*3*2*1 == 24 `。 +如果我們仔細觀察,我們可以看到一個數 n 的階乘是前一個數 n-1 乘以 n 的階乘。 +將其放入代碼中,我們得到 `n * factorial(n - 1)`。 +由于 `factorial` 的定義包含自身,`factorial` 是一個遞歸函數。 -提醒一下,如果您不添加类型规范,则会这样推断。 +提醒一下,如果您不添加類型規范,則會這樣推斷。 ```python factorial: |T <: Sub(Int, T) and Mul(Int, Int) and Eq(Int)| T -> Int @@ -212,20 +212,20 @@ factorial 1 = 1 factorial n = n * factorial(n - 1) ``` -但是,即使您可以推理,您也应该明确指定递归函数的类型。 在上面的例子中,像“factorial(-1)”这样的代码可以工作,但是 +但是,即使您可以推理,您也應該明確指定遞歸函數的類型。 在上面的例子中,像“factorial(-1)”這樣的代碼可以工作,但是 ```python factorial(-1) == -1 * factorial(-2) == -1 * -2 * factorial(-3) == ... ``` -并且这种计算不会停止。 递归函数必须仔细定义值的范围,否则您可能会陷入无限循环。 -所以类型规范也有助于避免接受意外的值。 +并且這種計算不會停止。 遞歸函數必須仔細定義值的范圍,否則您可能會陷入無限循環。 +所以類型規范也有助于避免接受意外的值。 -## 编译时函数 +## 編譯時函數 -函数名以大写字母开头,表示编译时函数。 用户定义的编译时函数必须将所有参数作为常量,并且必须指定它们的类型。 -编译时函数的功能有限。 在编译时函数中只能使用常量表达式,即只有一些运算符(例如求积、比较和类型构造操作)和编译时函数。 要传递的参数也必须是常量表达式。 -作为回报,优点是计算可以在编译时完成。 +函數名以大寫字母開頭,表示編譯時函數。 用戶定義的編譯時函數必須將所有參數作為常量,并且必須指定它們的類型。 +編譯時函數的功能有限。 在編譯時函數中只能使用常量表達式,即只有一些運算符(例如求積、比較和類型構造操作)和編譯時函數。 要傳遞的參數也必須是常量表達式。 +作為回報,優點是計算可以在編譯時完成。 ```python Add(X, Y: Nat): Nat = X + Y @@ -236,29 +236,29 @@ Factorial(X: Nat): Nat = X * Factorial(X - 1) assert Factorial(10) == 3628800 math = import "math" -Sin X = math.sin X # 常量错误:此函数在编译时不可计算 +Sin X = math.sin X # 常量錯誤:此函數在編譯時不可計算 ``` -编译时函数也用于多态类型定义。 +編譯時函數也用于多態類型定義。 ```python Option T: Type = T or NoneType Option: Type -> Type ``` -## 附录:功能对比 +## 附錄:功能對比 -Erg 没有为函数定义 `==`。 这是因为通常没有函数的结构等价算法。 +Erg 沒有為函數定義 `==`。 這是因為通常沒有函數的結構等價算法。 ```python f = x: Int -> (x + 1)**2 g = x: Int -> x**2 + 2x + 1 -assert f == g # 类型错误:无法比较函数 +assert f == g # 類型錯誤:無法比較函數 ``` -尽管 `f` 和 `g` 总是返回相同的结果,但要做出这样的决定是极其困难的。 我们必须向编译器教授代数。 -所以 Erg 完全放弃了函数比较,并且 `(x -> x) == (x -> x)` 也会导致编译错误。 这是与 Python 不同的规范,应该注意 +盡管 `f` 和 `g` 總是返回相同的結果,但要做出這樣的決定是極其困難的。 我們必須向編譯器教授代數。 +所以 Erg 完全放棄了函數比較,并且 `(x -> x) == (x -> x)` 也會導致編譯錯誤。 這是與 Python 不同的規范,應該注意 ```python # Python,奇怪的例子 @@ -271,20 +271,20 @@ assert (lambda x: x) ! = (lambda x: x) ```python f x: Object = ... -# 将完成到 +# 將完成到 f(x: Object) = ... f a -# 将完成到 +# 將完成到 f(a) -f a, b # 类型错误:f() 接受 1 个位置参数,但给出了 2 个 -f(a, b) # # 类型错误:f() 接受 1 个位置参数,但给出了 2 个 +f a, b # 類型錯誤:f() 接受 1 個位置參數,但給出了 2 個 +f(a, b) # # 類型錯誤:f() 接受 1 個位置參數,但給出了 2 個 f((a, b)) # OK ``` -函数类型`T -> U`实际上是`(T,) -> U`的语法糖。 +函數類型`T -> U`實際上是`(T,) -> U`的語法糖。

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/05_builtin_funcs.md b/doc/zh_TW/syntax/05_builtin_funcs.md index 9a21013c..294ab71e 100644 --- a/doc/zh_TW/syntax/05_builtin_funcs.md +++ b/doc/zh_TW/syntax/05_builtin_funcs.md @@ -1,8 +1,8 @@ -# 内置函数 +# 內置函數 ## 如果 -`if` 是一个根据条件改变处理的函数。 +`if` 是一個根據條件改變處理的函數。 ```python result: Option Int = if! Bool.sample!(), do: @@ -11,8 +11,8 @@ result: Option Int = if! Bool.sample!(), do: print! result # None (or 1) ``` -`.sample!()` 返回一组随机值。 如果返回值为真,`print! “真”`被执行。 -如果条件为假,您还可以指定要执行的操作; 第二个 do 块称为 else 块。 +`.sample!()` 返回一組隨機值。 如果返回值為真,`print! “真”`被執行。 +如果條件為假,您還可以指定要執行的操作; 第二個 do 塊稱為 else 塊。 ```python result: Nat = if Bool.sample!(): @@ -25,7 +25,7 @@ result: Nat = if Bool.sample!(): print! result # 1 (or 0) ``` -如果进程是单行,则可以省略缩进。 +如果進程是單行,則可以省略縮進。 ```python result = if Bool.sample!(): @@ -35,7 +35,7 @@ result = if Bool.sample!(): ## for -你可以使用 `for` 来编写一个重复的过程。 +你可以使用 `for` 來編寫一個重復的過程。 ```python match_s(ss: Iterator(Str), pat: Pattern): Option Str = @@ -45,5 +45,5 @@ match_s(ss: Iterator(Str), pat: Pattern): Option Str = ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/06_operator.md b/doc/zh_TW/syntax/06_operator.md index a7c8955e..ee6f32cf 100644 --- a/doc/zh_TW/syntax/06_operator.md +++ b/doc/zh_TW/syntax/06_operator.md @@ -1,29 +1,29 @@ -# 运算符 +# 運算符 -运算符是表示操作的符号。 操作数是运算符(左)右侧的东西。 +運算符是表示操作的符號。 操作數是運算符(左)右側的東西。 -运算符是一种函数,因此它们本身就是可以绑定到变量的一流对象。 绑定时,需要用```括起来。 -对于`+`(和`-`),有一元和二元运算符,所以必须指定`_+_`(二元运算)/`+_`(一元运算)。 +運算符是一種函數,因此它們本身就是可以綁定到變量的一流對象。 綁定時,需要用```括起來。 +對于`+`(和`-`),有一元和二元運算符,所以必須指定`_+_`(二元運算)/`+_`(一元運算)。 ```python -add = `+` # 语法错误:指定 `_+_` 或 `+_` +add = `+` # 語法錯誤:指定 `_+_` 或 `+_` add=`_+_` assert f(1, 2) == 3 assert f("a", "b") == "ab" -g = `*` # OK, 这只是二进制 +g = `*` # OK, 這只是二進制 assert g(1, 2) == 2 ``` -一些称为特殊形式的基本运算符不能被绑定。 +一些稱為特殊形式的基本運算符不能被綁定。 ```python -def = `=` # 语法错误:无法绑定 `=` 运算符,这是一种特殊形式 +def = `=` # 語法錯誤:無法綁定 `=` 運算符,這是一種特殊形式 # NG: def x, 1 -function = `->` # 语法错误:无法绑定 `->` 运算符,这是一种特殊形式 +function = `->` # 語法錯誤:無法綁定 `->` 運算符,這是一種特殊形式 # NG: function x, x + 1 ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/07_side_effect.md b/doc/zh_TW/syntax/07_side_effect.md index 3b7d414a..d1dada58 100644 --- a/doc/zh_TW/syntax/07_side_effect.md +++ b/doc/zh_TW/syntax/07_side_effect.md @@ -1,44 +1,44 @@ # 副作用和程序 -我们一直忽略了解释“!”的含义,但现在它的含义终于要揭晓了。 这个 `!` 表示这个对象是一个带有“副作用”的“过程”。 过程是具有副作用的函数。 +我們一直忽略了解釋“!”的含義,但現在它的含義終于要揭曉了。 這個 `!` 表示這個對象是一個帶有“副作用”的“過程”。 過程是具有副作用的函數。 ```python -f x = print! x # EffectError: 不能为函数分配有副作用的对象 -# 提示:将名称更改为 'f!' +f x = print! x # EffectError: 不能為函數分配有副作用的對象 +# 提示:將名稱更改為 'f!' ``` -上面的代码会导致编译错误。 这是因为您在函数中使用了过程。 在这种情况下,您必须将其定义为过程。 +上面的代碼會導致編譯錯誤。 這是因為您在函數中使用了過程。 在這種情況下,您必須將其定義為過程。 ```python p! x = print! x ``` -`p!`, `q!`, ... 是过程的典型变量名。 -以这种方式定义的过程也不能在函数中使用,因此副作用是完全隔离的。 +`p!`, `q!`, ... 是過程的典型變量名。 +以這種方式定義的過程也不能在函數中使用,因此副作用是完全隔離的。 ## 方法 -函数和过程中的每一个都可以是方法。 函数式方法只能对`self`进行不可变引用,而程序性方法可以对`self`进行可变引用。 -`self` 是一个特殊的参数,在方法的上下文中是指调用对象本身。 引用 `self` 不能分配给任何其他变量。 +函數和過程中的每一個都可以是方法。 函數式方法只能對`self`進行不可變引用,而程序性方法可以對`self`進行可變引用。 +`self` 是一個特殊的參數,在方法的上下文中是指調用對象本身。 引用 `self` 不能分配給任何其他變量。 ```python C!. method ref self = - x = self # 所有权错误:无法移出`self` + x = self # 所有權錯誤:無法移出`self` x ``` -程序方法也可以采取 `self` 的 [ownership](./18_ownership.md)。 从方法定义中删除 `ref` 或 `ref!` +程序方法也可以采取 `self` 的 [ownership](./18_ownership.md)。 從方法定義中刪除 `ref` 或 `ref!` ```python n = 1 s = n.into(Str) # '1' -n # 值错误:n 被 .into 移动(第 2 行) +n # 值錯誤:n 被 .into 移動(第 2 行) ``` -在任何给定时间,只有一种程序方法可以具有可变引用。 此外,在获取可变引用时,不能从原始对象获取更多可变引用。 从这个意义上说,`ref!` 会对`self` 产生副作用。 +在任何給定時間,只有一種程序方法可以具有可變引用。 此外,在獲取可變引用時,不能從原始對象獲取更多可變引用。 從這個意義上說,`ref!` 會對`self` 產生副作用。 -但是请注意,可以从可变引用创建(不可变/可变)引用。 这允许在程序方法中递归和 `print!` 的`self`。 +但是請注意,可以從可變引用創建(不可變/可變)引用。 這允許在程序方法中遞歸和 `print!` 的`self`。 ```python T -> T # OK (move) @@ -52,23 +52,23 @@ T -> Ref T # OK T => Ref! ``` -## 附录:副作用的严格定义 +## 附錄:副作用的嚴格定義 -代码是否具有副作用的规则无法立即理解。 -直到你能理解它们,我们建议你暂时把它们定义为函数,如果出现错误,添加`!`将它们视为过程。 -但是,对于那些想了解该语言的确切规范的人,以下是对副作用的更详细说明。 +代碼是否具有副作用的規則無法立即理解。 +直到你能理解它們,我們建議你暫時把它們定義為函數,如果出現錯誤,添加`!`將它們視為過程。 +但是,對于那些想了解該語言的確切規范的人,以下是對副作用的更詳細說明。 -首先,必须声明返回值的等价与 Erg 中的副作用无关。 -有些过程对于任何给定的 `x` 都会导致 `p!(x) == p!(x)`(例如,总是返回 `None`),并且有些函数会导致 `f(x) ! = f(x)`。 +首先,必須聲明返回值的等價與 Erg 中的副作用無關。 +有些過程對于任何給定的 `x` 都會導致 `p!(x) == p!(x)`(例如,總是返回 `None`),并且有些函數會導致 `f(x) ! = f(x)`。 -前者的一个例子是`print!`,后者的一个例子是下面的函数。 +前者的一個例子是`print!`,后者的一個例子是下面的函數。 ```python nan _ = Float.NaN assert nan(1) ! = nan(1) ``` -还有一些对象,例如类,等价确定本身是不可能的 +還有一些對象,例如類,等價確定本身是不可能的 ```python T = Structural {i = Int} @@ -77,16 +77,16 @@ assert T == U C = Class {i = Int} D = Class {i = Int} -assert C == D # 类型错误:无法比较类 +assert C == D # 類型錯誤:無法比較類 ``` -言归正传:Erg 中“副作用”的准确定义是 +言歸正傳:Erg 中“副作用”的準確定義是 -* 访问可变的外部信息。 +* 訪問可變的外部信息。 -“外部”一般是指外部范围; Erg 无法触及的计算机资源和执行前/执行后的信息不包含在“外部”中。 “访问”包括阅读和写作。 +“外部”一般是指外部范圍; Erg 無法觸及的計算機資源和執行前/執行后的信息不包含在“外部”中。 “訪問”包括閱讀和寫作。 -例如,考虑 `print!` 过程。 乍一看,`print!` 似乎没有重写任何变量。 但如果它是一个函数,它可以重写外部变量,例如,使用如下代码: +例如,考慮 `print!` 過程。 乍一看,`print!` 似乎沒有重寫任何變量。 但如果它是一個函數,它可以重寫外部變量,例如,使用如下代碼: ```python camera = import "some_camera_module" @@ -94,28 +94,28 @@ ocr = import "some_ocr_module" n = 0 _ = - f x = print x # 假设我们可以使用 print 作为函数 + f x = print x # 假設我們可以使用 print 作為函數 f(3.141592) -cam = camera.new() # 摄像头面向 PC 显示器 +cam = camera.new() # 攝像頭面向 PC 顯示器 image = cam.shot!() n = ocr.read_num(image) # n = 3.141592 ``` -将“camera”模块视为为特定相机产品提供 API 的外部库,将“ocr”视为用于 OCR(光学字符识别)的库。 -直接的副作用是由 `cam.shot!()` 引起的,但显然这些信息是从 `f` 泄露的。 因此,`print!` 本质上不可能是一个函数。 +將“camera”模塊視為為特定相機產品提供 API 的外部庫,將“ocr”視為用于 OCR(光學字符識別)的庫。 +直接的副作用是由 `cam.shot!()` 引起的,但顯然這些信息是從 `f` 泄露的。 因此,`print!` 本質上不可能是一個函數。 -然而,在某些情况下,您可能希望临时检查函数中的值,而不想为此目的在相关函数中添加 `!`。 在这种情况下,可以使用 `log` 函数。 -`log` 打印整个代码执行后的值。 这样,副作用就不会传播。 +然而,在某些情況下,您可能希望臨時檢查函數中的值,而不想為此目的在相關函數中添加 `!`。 在這種情況下,可以使用 `log` 函數。 +`log` 打印整個代碼執行后的值。 這樣,副作用就不會傳播。 ```python log "this will be printed after execution" print! "this will be printed immediately" -# 这将立即打印 -# 这将在执行后打印 +# 這將立即打印 +# 這將在執行后打印 ``` -如果没有反馈给程序,或者换句话说,如果没有外部对象可以使用内部信息,那么信息的“泄漏”是可以允许的。 只需要不“传播”信息。 +如果沒有反饋給程序,或者換句話說,如果沒有外部對象可以使用內部信息,那么信息的“泄漏”是可以允許的。 只需要不“傳播”信息。

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/08_procedure.md b/doc/zh_TW/syntax/08_procedure.md index 3ce9e05a..a381e88f 100644 --- a/doc/zh_TW/syntax/08_procedure.md +++ b/doc/zh_TW/syntax/08_procedure.md @@ -1,12 +1,12 @@ # 程序 -处理可变对象时需要过程,但将可变对象作为参数并不一定使其成为过程。 -这是一个函数接受一个可变对象(不是过程)。 +處理可變對象時需要過程,但將可變對象作為參數并不一定使其成為過程。 +這是一個函數接受一個可變對象(不是過程)。 ```python peek_str s: Str! = log s ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/09_builtin_procs.md b/doc/zh_TW/syntax/09_builtin_procs.md index f2e878c2..25559d98 100644 --- a/doc/zh_TW/syntax/09_builtin_procs.md +++ b/doc/zh_TW/syntax/09_builtin_procs.md @@ -1,14 +1,14 @@ -# 内置程序 +# 內置程序 ## id! -返回对象的唯一标识号。 -尽管在纯 Erg 语义中,结构相同的对象之间没有区别,但实际上对象在内存中具有不同的位置。 -`id!` 返回一个代表这个位置的数字。 +返回對象的唯一標識號。 +盡管在純 Erg 語義中,結構相同的對象之間沒有區別,但實際上對象在內存中具有不同的位置。 +`id!` 返回一個代表這個位置的數字。 ```python ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/10_array.md b/doc/zh_TW/syntax/10_array.md index c77cc7cd..892ad80a 100644 --- a/doc/zh_TW/syntax/10_array.md +++ b/doc/zh_TW/syntax/10_array.md @@ -1,12 +1,12 @@ # Array -数组是最基本的__collection(聚合)__。 -集合是一个可以在其中包含多个对象的对象。 +數組是最基本的__collection(聚合)__。 +集合是一個可以在其中包含多個對象的對象。 ```python a = [1, 2, 3] -a: [Int; 3] # 类型说明:分号后的数字为元素个数 -# 如果元素个数未知,可以省略 +a: [Int; 3] # 類型說明:分號后的數字為元素個數 +# 如果元素個數未知,可以省略 a: [Int] mut_a = [!1, !2, !3] @@ -14,13 +14,13 @@ mut_a[0].inc!() assert mut_a == [2, 2, 3] ``` -通常,数组不能包含不同类型的对象。 +通常,數組不能包含不同類型的對象。 ```python. -[1, "a"] # 类型错误:第一个元素是 Int,但第二个元素是 Str +[1, "a"] # 類型錯誤:第一個元素是 Int,但第二個元素是 Str ``` -但是,您可以通过像这样显式指定类型来绕过限制。 +但是,您可以通過像這樣顯式指定類型來繞過限制。 ```python [1, "a"]: [Int or Str]. @@ -28,25 +28,25 @@ assert mut_a == [2, 2, 3] ## 切片 -一个数组也可以同时取出多个值。 这称为切片。 +一個數組也可以同時取出多個值。 這稱為切片。 ```python l = [1, 2, 3, 4] -# 与 Python 中的 l[1:3] 相同 +# 與 Python 中的 l[1:3] 相同 assert l[1.. <3] == [2, 3] assert l[1..2] == [2, 3] -# 与 l[1] 相同 +# 與 l[1] 相同 assert l[1..1] == [2] -# 与 Python 中的 l[::2] 相同 +# 與 Python 中的 l[::2] 相同 assert l[..].step(2) == [2, 4] ``` -通过切片获得的对象是数组的(不可变的)副本 +通過切片獲得的對象是數組的(不可變的)副本 ```python print! Typeof l[1..2] # [Int; 4] ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/11_tuple.md b/doc/zh_TW/syntax/11_tuple.md index 95f2502a..7c62c2f4 100644 --- a/doc/zh_TW/syntax/11_tuple.md +++ b/doc/zh_TW/syntax/11_tuple.md @@ -1,7 +1,7 @@ -# 元组 +# 元組 -元组类似于数组,但可以保存不同类型的对象。 -这样的集合称为不等集合。 相比之下,同构集合包括数组、集合等。 +元組類似于數組,但可以保存不同類型的對象。 +這樣的集合稱為不等集合。 相比之下,同構集合包括數組、集合等。 ```python t = (1, True, "a") @@ -9,8 +9,8 @@ t = (1, True, "a") assert(i == 1 and b == True and s == "a") ``` -元组`t`可以以`t.n`的形式检索第n个元素; 请注意,与 Python 不同,它不是 `t[n]`。 -这是因为访问元组元素更像是一个属性(在编译时检查元素的存在,并且类型可以根据 `n` 改变)而不是方法(数组的 `[]` 是一种方法)。 +元組`t`可以以`t.n`的形式檢索第n個元素; 請注意,與 Python 不同,它不是 `t[n]`。 +這是因為訪問元組元素更像是一個屬性(在編譯時檢查元素的存在,并且類型可以根據 `n` 改變)而不是方法(數組的 `[]` 是一種方法)。 ```python assert t.0 == 1 @@ -18,55 +18,55 @@ assert t.1 == True assert t.2 == "a" ``` -括号 `()` 在不嵌套时是可选的。 +括號 `()` 在不嵌套時是可選的。 ```python t = 1, True, "a" i, b, s = t ``` -元组可以保存不同类型的对象,因此它们不能像数组一样被迭代。 +元組可以保存不同類型的對象,因此它們不能像數組一樣被迭代。 ```python t: ({1}, {2}, {3}) = (1, 2, 3) -(1, 2, 3).iter().map(x -> x + 1) # 类型错误:类型 ({1}, {2}, {3}) 没有方法 `.iter()` -# 如果所有类型都相同,则可以像数组一样用`(T; n)`表示,但这仍然不允许迭代 +(1, 2, 3).iter().map(x -> x + 1) # 類型錯誤:類型 ({1}, {2}, {3}) 沒有方法 `.iter()` +# 如果所有類型都相同,則可以像數組一樣用`(T; n)`表示,但這仍然不允許迭代 t: (Int; 3) = (1, 2, 3) assert (Int; 3) == (Int, Int, Int) ``` -但是,非同质集合(如元组)可以通过向上转换、相交等方式转换为同质集合(如数组)。 -这称为均衡。 +但是,非同質集合(如元組)可以通過向上轉換、相交等方式轉換為同質集合(如數組)。 +這稱為均衡。 ```python (Int, Bool, Str) can be [T; 3] where T :> Int, T :> Bool, T :> Str ``` ```python -t: (Int, Bool, Str) = (1, True, "a") # 非同质 -a: [Int or Bool or Str; 3] = [1, True, "a"] # 同质的 -_a: [Show; 3] = [1, True, "a"] # 同质的 +t: (Int, Bool, Str) = (1, True, "a") # 非同質 +a: [Int or Bool or Str; 3] = [1, True, "a"] # 同質的 +_a: [Show; 3] = [1, True, "a"] # 同質的 _a.iter().map(x -> log x) # OK t.try_into([Show; 3])? .iter().map(x -> log x) # OK ``` -## 单元 +## 單元 -零元素的元组称为 __unit__。 一个单元是一个值,但也指它自己的类型。 +零元素的元組稱為 __unit__。 一個單元是一個值,但也指它自己的類型。 ```python unit = () (): () ``` -Unit 是所有元素 0 元组的父类。 +Unit 是所有元素 0 元組的父類。 ```python () > (Int; 0) () > (Str; 0) ``` -该对象的用途是用于没有参数和没有返回值的过程等。Erg 子例程必须有参数和返回值。 但是,在某些情况下,例如过程,可能没有有意义的参数或返回值,只有副作用。 在这种情况下,我们将单位用作“无意义的正式值” +該對象的用途是用于沒有參數和沒有返回值的過程等。Erg 子例程必須有參數和返回值。 但是,在某些情況下,例如過程,可能沒有有意義的參數或返回值,只有副作用。 在這種情況下,我們將單位用作“無意義的正式值” ```python # ↓ Actually, this parenthesis is a unit @@ -76,30 +76,30 @@ p!() =. p!: () => () ``` -但是,在这种情况下,Python 倾向于使用“无”而不是单位。 -在 Erg 中,当您从一开始就确定操作不会返回有意义的值(例如在过程中)时,您应该使用 `()`,并且当操作可能失败并且您可能会返回 `None` 将一无所获,例如在检索元素时。 +但是,在這種情況下,Python 傾向于使用“無”而不是單位。 +在 Erg 中,當您從一開始就確定操作不會返回有意義的值(例如在過程中)時,您應該使用 `()`,并且當操作可能失敗并且您可能會返回 `None` 將一無所獲,例如在檢索元素時。 -## 参数和元组 +## 參數和元組 -实际上,Erg 的所有 `Callable` 对象都是一个参数和一个返回值; 一个接受 N 个参数的子例程只是接收“一个具有 N 个元素的元组”作为参数。 +實際上,Erg 的所有 `Callable` 對象都是一個參數和一個返回值; 一個接受 N 個參數的子例程只是接收“一個具有 N 個元素的元組”作為參數。 ```python -# f x = ... 被隐式假设为 f(x) = ... 被认为是 +# f x = ... 被隱式假設為 f(x) = ... 被認為是 f x = x assert f(1) == 1 -f(1, 2, 3) # 参数错误:f 接受 1 个位置参数,但给出了 3 个 +f(1, 2, 3) # 參數錯誤:f 接受 1 個位置參數,但給出了 3 個 g x: Int, . . y: Int = y assert (2, 3) == g 1, 2, 3 ``` -这也解释了函数类型。 +這也解釋了函數類型。 ```python assert f in T: {(T,) -> T | T} assert g in {(Int, ... (Int; N)) -> (Int; N) | N: Nat} ``` -准确地说,函数的输入不是元组,而是“具有默认属性的命名元组”。 这是一个特殊的元组,只能在函数参数中使用,可以像记录一样命名,并且可以有默认值。 +準確地說,函數的輸入不是元組,而是“具有默認屬性的命名元組”。 這是一個特殊的元組,只能在函數參數中使用,可以像記錄一樣命名,并且可以有默認值。 ```python f(x: Int, y=0) = x + y @@ -112,5 +112,5 @@ f(0) ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/12_dict.md b/doc/zh_TW/syntax/12_dict.md index 08938fcd..235071d9 100644 --- a/doc/zh_TW/syntax/12_dict.md +++ b/doc/zh_TW/syntax/12_dict.md @@ -1,37 +1,37 @@ # 字典 -Dict 是键/值对的集合。 +Dict 是鍵/值對的集合。 ```python ids = {"Alice": 145, "Bob": 214, "Charlie": 301} assert ids["Alice"] == 145 ``` -如果键是“哈希”对象,则键不必是字符串。 +如果鍵是“哈希”對象,則鍵不必是字符串。 ```python -# 不推荐使用范围对象作为键(与切片混淆) +# 不推薦使用范圍對象作為鍵(與切片混淆) r = {1..3: "1~3", 4..6: "4~6", 7..9: "7~9"} assert r[1..3] == "1~3" l = {[]: "empty", [1]: "1"} assert l[[]] == "empty" ``` -对于字典来说,顺序无关紧要。 它也不能有重复的元素。 在这方面,Dict 与 Set 类似。 -您可以说 Dict 是具有值的 Set。 +對于字典來說,順序無關緊要。 它也不能有重復的元素。 在這方面,Dict 與 Set 類似。 +您可以說 Dict 是具有值的 Set。 ```python {"Alice": 145, "Bob": 214, "Charlie": 301} == {"Alice": 145, "Charlie": 301, "Bob": 214} ``` -从 dict 文字生成 dict 时,会检查重复键。 -任何重复都会导致编译错误。 +從 dict 文字生成 dict 時,會檢查重復鍵。 +任何重復都會導致編譯錯誤。 ```python -{"Alice": 145, "Alice": 1} # Key错误:重复键`Alice` +{"Alice": 145, "Alice": 1} # Key錯誤:重復鍵`Alice` ``` -空字典是用 `{:}` 创建的。 请注意,`{}` 表示一个空集。 +空字典是用 `{:}` 創建的。 請注意,`{}` 表示一個空集。 ```python mut_dict = !{:} @@ -40,9 +40,9 @@ mut_dict.insert! "Bob", 214 assert mut_dict["Alice"] == 145 ``` -## 异构字典 +## 異構字典 -不需要有单一的键/值类型。 这样的字典称为 __heterogenous dict_。 +不需要有單一的鍵/值類型。 這樣的字典稱為 __heterogenous dict_。 ```python d: {Str: Int, Int: Str} = {"a": 1, 1: "a"} @@ -50,18 +50,18 @@ assert d["a"] == 1 assert d[1] == "a" ``` -但是,不能将相同类型的值分配给不同类型的键,或者将不同类型的值分配给相同类型的键。 -在这种情况下,请改用 Or 类型。 +但是,不能將相同類型的值分配給不同類型的鍵,或者將不同類型的值分配給相同類型的鍵。 +在這種情況下,請改用 Or 類型。 ```python invalid1 = {1: "a", "a": "b"} invalid2 = {1: "a", 2: 2} -# Erg 类型推断不推断 Or 类型,因此需要类型说明 +# Erg 類型推斷不推斷 Or 類型,因此需要類型說明 valid1: {Int or Str: Str} = {1: "a", "a": "b"} valid2: {Int: Int or Str} = {1: "a", 2: 2} ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/13_record.md b/doc/zh_TW/syntax/13_record.md index 2990ed55..19e4252d 100644 --- a/doc/zh_TW/syntax/13_record.md +++ b/doc/zh_TW/syntax/13_record.md @@ -1,7 +1,7 @@ -# 记录(Record) +# 記錄(Record) -记录是一个集合,它结合了通过键访问的 Dict 和在编译时检查其访问的元组的属性。 -如果您了解 JavaScript,请将其视为一种(更增强的)对象字面量表示法。 +記錄是一個集合,它結合了通過鍵訪問的 Dict 和在編譯時檢查其訪問的元組的屬性。 +如果您了解 JavaScript,請將其視為一種(更增強的)對象字面量表示法。 ```python john = {.name = "John"; .age = 21} @@ -9,27 +9,27 @@ john = {.name = "John"; .age = 21} assert john.name == "John" assert john.age == 21 assert john in {.name = Str; .age = Nat} -john["name"] # 错误:john 不可订阅 +john["name"] # 錯誤:john 不可訂閱 ``` -`.name` 和 `.age` 部分称为属性,而 `"John"` 和 `21` 部分称为属性值。 +`.name` 和 `.age` 部分稱為屬性,而 `"John"` 和 `21` 部分稱為屬性值。 -与 JavaScript 对象字面量的区别在于它们不能作为字符串访问。 也就是说,属性不仅仅是字符串。 -这是因为对值的访问是在编译时确定的,而且字典和记录是不同的东西。 换句话说,`{"name": "John"}` 是一个字典,`{name = "John"}` 是一个记录。 -那么我们应该如何使用字典和记录呢? -一般来说,我们建议使用记录。 记录具有在编译时检查元素是否存在以及能够指定 __visibility_ 的优点。 -指定可见性等同于在 Java 和其他语言中指定公共/私有。 有关详细信息,请参阅 [可见性](./15_visibility.md) 了解详细信息。 +與 JavaScript 對象字面量的區別在于它們不能作為字符串訪問。 也就是說,屬性不僅僅是字符串。 +這是因為對值的訪問是在編譯時確定的,而且字典和記錄是不同的東西。 換句話說,`{"name": "John"}` 是一個字典,`{name = "John"}` 是一個記錄。 +那么我們應該如何使用字典和記錄呢? +一般來說,我們建議使用記錄。 記錄具有在編譯時檢查元素是否存在以及能夠指定 __visibility_ 的優點。 +指定可見性等同于在 Java 和其他語言中指定公共/私有。 有關詳細信息,請參閱 [可見性](./15_visibility.md) 了解詳細信息。 ```python a = {x = 1; .y = x + 1} -a.x # 属性错误:x 是私有的 -# 提示:声明为 `.x`。 +a.x # 屬性錯誤:x 是私有的 +# 提示:聲明為 `.x`。 assert a.y == 2 ``` -对于熟悉 JavaScript 的人来说,上面的示例可能看起来很奇怪,但简单地声明 `x` 会使其无法从外部访问 +對于熟悉 JavaScript 的人來說,上面的示例可能看起來很奇怪,但簡單地聲明 `x` 會使其無法從外部訪問 -您还可以显式指定属性的类型 +您還可以顯式指定屬性的類型 ```python anonymous = { @@ -39,7 +39,7 @@ anonymous = { anonymous.name.set! "John" ``` -一个记录也可以有方法。 +一個記錄也可以有方法。 ```python o = { @@ -52,27 +52,27 @@ o.inc!() assert o.i == 1 ``` -关于记录有一个值得注意的语法。 当记录的所有属性值都是类(不是结构类型)时,记录本身表现为一个类型,其自身的属性作为必需属性。 -这种类型称为记录类型。 有关详细信息,请参阅 [记录] 部分。 +關于記錄有一個值得注意的語法。 當記錄的所有屬性值都是類(不是結構類型)時,記錄本身表現為一個類型,其自身的屬性作為必需屬性。 +這種類型稱為記錄類型。 有關詳細信息,請參閱 [記錄] 部分。 ```python -# 记录 +# 記錄 john = {.name = "John"} -# 记录 type +# 記錄 type john: {.name = Str} Named = {.name = Str} john: Named greet! n: Named = print! "Hello, I am {n.name}" -john # “你好,我是约翰 print! +john # “你好,我是約翰 print! Named.name # Str ``` -## 解构记录 +## 解構記錄 -记录可以按如下方式解构。 +記錄可以按如下方式解構。 ```python record = {x = 1; y = 2} @@ -88,8 +88,8 @@ match point: {x = x; y = y; z = z} -> "({x}, {y}, {z})" ``` -当存在与属性同名的变量时,`x = ...`也可以缩写为`x`,例如`x = x`或`x = .x`到`x`,和` .x = .x` 或 `.x = x` 到 `.x`。 -但是,当只有一个属性时,必须在其后加上`;`以与集合区分开来。 +當存在與屬性同名的變量時,`x = ...`也可以縮寫為`x`,例如`x = x`或`x = .x`到`x`,和` .x = .x` 或 `.x = x` 到 `.x`。 +但是,當只有一個屬性時,必須在其后加上`;`以與集合區分開來。 ```python x = 1 @@ -106,22 +106,22 @@ tuple = {x} assert tuple.1 == 1 ``` -此语法可用于解构记录并将其分配给变量 +此語法可用于解構記錄并將其分配給變量 ```python -# 一样 `{x = x; y = y} = xy` +# 一樣 `{x = x; y = y} = xy` {x; y} = xy assert x == 1 assert y == 2 -# 一样 `{.a = a; .b = b} = ab` +# 一樣 `{.a = a; .b = b} = ab` {a; b} = ab assert a == 1 assert b == 2 ``` -## 空记录 +## 空記錄 -空记录由`{=}`表示。 空记录也是它自己的类,如 Unit +空記錄由`{=}`表示。 空記錄也是它自己的類,如 Unit ```python empty_record = {=} @@ -132,10 +132,10 @@ empty_record: Structural {=} {x = 3; y = 5}: Structural {=} ``` -空记录不同于空 Dict `{:}` 或空集 `{}`。 特别要注意的是,它与 `{}` 的含义相反(在 Python 中,`{}` 是一个空字典,而在 Erg 中它是 Erg 中的 `!{:}`)。 -作为枚举类型,`{}` 是一个空类型,其元素中不包含任何内容。 `Never` 类型是这种类型的一个分类。 -相反,记录类 `{=}` 没有必需的实例属性,因此所有对象都是它的元素。 `Object` 是 this 的别名。 -一个`Object`(`Object`的一个补丁)是`的一个元素。 __sizeof__` 和其他非常基本的提供方法。 +空記錄不同于空 Dict `{:}` 或空集 `{}`。 特別要注意的是,它與 `{}` 的含義相反(在 Python 中,`{}` 是一個空字典,而在 Erg 中它是 Erg 中的 `!{:}`)。 +作為枚舉類型,`{}` 是一個空類型,其元素中不包含任何內容。 `Never` 類型是這種類型的一個分類。 +相反,記錄類 `{=}` 沒有必需的實例屬性,因此所有對象都是它的元素。 `Object` 是 this 的別名。 +一個`Object`(`Object`的一個補丁)是`的一個元素。 __sizeof__` 和其他非常基本的提供方法。 ```python AnyPatch = Patch Structural {=} @@ -145,13 +145,13 @@ AnyPatch = Patch Structural {=} Never = Class {} ``` -请注意,没有其他类型或类在结构上与 `{}`、`Never` 类型等效,如果用户在右侧使用 `{}`、`Class {}` 定义类型,则会出错。 -这意味着,例如,`1..10 或 -10。 -1`,但 `1..10 和 -10... -1`。 例如,当它应该是 1..10 或 -10...-1 时是 `-1`。 -此外,如果您定义的类型(例如 `Int 和 Str`)会导致组合 `Object`,则会警告您只需将其设置为 `Object`。 +請注意,沒有其他類型或類在結構上與 `{}`、`Never` 類型等效,如果用戶在右側使用 `{}`、`Class {}` 定義類型,則會出錯。 +這意味著,例如,`1..10 或 -10。 -1`,但 `1..10 和 -10... -1`。 例如,當它應該是 1..10 或 -10...-1 時是 `-1`。 +此外,如果您定義的類型(例如 `Int 和 Str`)會導致組合 `Object`,則會警告您只需將其設置為 `Object`。 -## 即时封锁 +## 即時封鎖 -Erg 有另一种语法 Instant 块,它只返回最后评估的值。 不能保留属性。 +Erg 有另一種語法 Instant 塊,它只返回最后評估的值。 不能保留屬性。 ```python x = @@ -161,13 +161,13 @@ x = assert x == 8 y = - .x = 1 # 语法错误:无法在实体块中定义属性 + .x = 1 # 語法錯誤:無法在實體塊中定義屬性 ``` -## 数据类 +## 數據類 -如果您尝试自己实现方法,则必须直接在实例中定义裸记录(由记录文字生成的记录)。 -这是低效的,并且随着属性数量的增加,错误消息等变得难以查看和使用。 +如果您嘗試自己實現方法,則必須直接在實例中定義裸記錄(由記錄文字生成的記錄)。 +這是低效的,并且隨著屬性數量的增加,錯誤消息等變得難以查看和使用。 ```python john = { @@ -177,11 +177,11 @@ john = { .inc_age! ref! self = self::age.update! x -> x + 1 } john + 1 -# 类型错误:{name = Str; 没有实现 + 年龄=诠释; 。迎接! =参考(自我)。 () => 无; inc_age! =参考! () => 无}, 整数 +# 類型錯誤:{name = Str; 沒有實現 + 年齡=詮釋; 。迎接! =參考(自我)。 () => 無; inc_age! =參考! () => 無}, 整數 ``` -因此,在这种情况下,您可以继承一个记录类。 这样的类称为数据类。 -这在 [class](./type/04_class.md) 中有描述。 +因此,在這種情況下,您可以繼承一個記錄類。 這樣的類稱為數據類。 +這在 [class](./type/04_class.md) 中有描述。 ```python Person = Inherit {name = Str; age = Nat} @@ -191,9 +191,9 @@ Person. john = Person.new {name = "John Smith"; age = 20} john + 1 -# 类型错误:Person、Int 没有实现 + +# 類型錯誤:Person、Int 沒有實現 + ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/14_set.md b/doc/zh_TW/syntax/14_set.md index e209411d..304b5cc0 100644 --- a/doc/zh_TW/syntax/14_set.md +++ b/doc/zh_TW/syntax/14_set.md @@ -1,14 +1,14 @@ # Set -一个Set代表一个集合,它在结构上是一个重复的无序数组。 +一個Set代表一個集合,它在結構上是一個重復的無序數組。 ```python assert Set.from([1, 2, 3, 2, 1]) == {1, 2, 3} -assert {1, 2} == {1, 1, 2} # 重复的被自动删除 +assert {1, 2} == {1, 1, 2} # 重復的被自動刪除 assert {1, 2} == {2, 1} ``` -Set可以执行集合操作。 +Set可以執行集合操作。 ```python assert 1 in {1, 2, 3} @@ -18,22 +18,22 @@ assert {1, 2} and {2, 3} == {2} assert {1, 2} not {2} == {1} ``` -Set是同质集合。 为了使不同类的对象共存,它们必须同质化 +Set是同質集合。 為了使不同類的對象共存,它們必須同質化 ```python s: {Int or Str} = {"a", 1, "b", -1} ``` -## Sets为类型 -Sets也可以被视为类型。 这种类型称为 _枚举类型_。 +## Sets為類型 +Sets也可以被視為類型。 這種類型稱為 _枚舉類型_。 ```python i: {1, 2, 3} = 1 assert i in {1, 2, 3} ``` -Set的元素直接是类型的元素。 -请注意,这些Set本身是不同的。 +Set的元素直接是類型的元素。 +請注意,這些Set本身是不同的。 ```python mut_set = {1, 2, 3}.into {Int; !3} @@ -41,5 +41,5 @@ mut_set.insert!(4) ```

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/15_type.md b/doc/zh_TW/syntax/15_type.md index 37dd77c6..9d39a89d 100644 --- a/doc/zh_TW/syntax/15_type.md +++ b/doc/zh_TW/syntax/15_type.md @@ -1,7 +1,7 @@ -# 类型 +# 類型 -类型是 Erg 中一个非常重要的特性,所以我们有一个 [dedicated section](./type/01_type_system.md)。 请看那里。 +類型是 Erg 中一個非常重要的特性,所以我們有一個 [dedicated section](./type/01_type_system.md)。 請看那里。

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/16_iterator.md b/doc/zh_TW/syntax/16_iterator.md index a2733c5c..be023422 100644 --- a/doc/zh_TW/syntax/16_iterator.md +++ b/doc/zh_TW/syntax/16_iterator.md @@ -1,24 +1,24 @@ # 迭代器 -迭代器是用于检索容器元素的对象。 +迭代器是用于檢索容器元素的對象。 ```python for! 0..9, i => print! i ``` -此代码打印数字 0 到 9。 -每个数字(=Int 对象)都分配给`i`,并执行以下操作(=`print!i`)。 这种重复执行称为__iteration__。 +此代碼打印數字 0 到 9。 +每個數字(=Int 對象)都分配給`i`,并執行以下操作(=`print!i`)。 這種重復執行稱為__iteration__。 -现在让我们看看 `for!` 过程的类型签名。 +現在讓我們看看 `for!` 過程的類型簽名。 ```python for!: |T: Type, I <: Iterable T| (I, T => None) => None ``` -第一个参数似乎接受“Iterable”类型的对象。 +第一個參數似乎接受“Iterable”類型的對象。 -`Iterable` 是一个具有`.Iterator` 属性的类型,`.iter` 方法在request 方法中。 +`Iterable` 是一個具有`.Iterator` 屬性的類型,`.iter` 方法在request 方法中。 ```python Iterable T = Trait { @@ -27,7 +27,7 @@ Iterable T = Trait { } ``` -`.Iterator` 属性的类型 `{Iterator}` 是所谓的 set-kind(kind 在 [here](./type/advanced/kind.md) 中描述) +`.Iterator` 屬性的類型 `{Iterator}` 是所謂的 set-kind(kind 在 [here](./type/advanced/kind.md) 中描述) ```python assert [1, 2, 3] in Iterable(Int) @@ -35,13 +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..3).iter() # +log [1, 2, 3].iter() # <數組迭代器對象> +log (1..3).iter() # ``` -`ArrayIterator` 和 `RangeIterator` 都是实现 `Iterator` 的类,它们的存在只是为了提供 `Array` 和 `Range` 迭代函数。 -这种设计模式称为伴生类 [1](#1)。 -而“IteratorImpl”补丁是迭代功能的核心。 `Iterator` 只需要一个`.next` 方法,`IteratorImpl` 确实提供了几十种方法。 `ArrayIterator`和`RangeIterator`只需实现`.next`方法就可以使用`IteratorImpl`的实现方法。 为了方便起见,标准库实现了许多迭代器。 +`ArrayIterator` 和 `RangeIterator` 都是實現 `Iterator` 的類,它們的存在只是為了提供 `Array` 和 `Range` 迭代函數。 +這種設計模式稱為伴生類 [1](#1)。 +而“IteratorImpl”補丁是迭代功能的核心。 `Iterator` 只需要一個`.next` 方法,`IteratorImpl` 確實提供了幾十種方法。 `ArrayIterator`和`RangeIterator`只需實現`.next`方法就可以使用`IteratorImpl`的實現方法。 為了方便起見,標準庫實現了許多迭代器。 ```mermaid classDiagram @@ -78,12 +78,12 @@ classDiagram Range <-- RangeIterator ``` -诸如 `Iterable` 之类的以静态分派但统一的方式提供用于处理特征(在本例中为 `Iterator`)的接口的类型称为伴生类适配器。 +諸如 `Iterable` 之類的以靜態分派但統一的方式提供用于處理特征(在本例中為 `Iterator`)的接口的類型稱為伴生類適配器。 --- -1 这个模式似乎没有统一的名称,但是在 Rust 中,有 [companion struct 模式]( https://gist.github.com/qnighy/be99c2ece6f3f4b1248608a04e104b38#:~:text=%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82 %8B%E3%80%82-,companion%20struct,-%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A8%E3%80% 81%E3 %81%9D%E3%81%AE),并以此命名。 [↩](#f1) +1 這個模式似乎沒有統一的名稱,但是在 Rust 中,有 [companion struct 模式]( https://gist.github.com/qnighy/be99c2ece6f3f4b1248608a04e104b38#:~:text=%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82 %8B%E3%80%82-,companion%20struct,-%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A8%E3%80% 81%E3 %81%9D%E3%81%AE),并以此命名。 [?](#f1)

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/17_mutability.md b/doc/zh_TW/syntax/17_mutability.md index 3d89fad4..41988a44 100644 --- a/doc/zh_TW/syntax/17_mutability.md +++ b/doc/zh_TW/syntax/17_mutability.md @@ -1,7 +1,7 @@ -# 可变性 +# 可變性 -正如我们已经看到的,所有 Erg 变量都是不可变的。 但是,Erg 对象具有可变性的概念。 -以下面的代码为例。 +正如我們已經看到的,所有 Erg 變量都是不可變的。 但是,Erg 對象具有可變性的概念。 +以下面的代碼為例。 ```python a = [1, 2, 3] @@ -9,9 +9,9 @@ a = a + [4, 5, 6] print! a # [1, 2, 3, 4, 5, 6] ``` -上面的代码实际上不能被 Erg 执行。 这是因为它不可重新分配。 +上面的代碼實際上不能被 Erg 執行。 這是因為它不可重新分配。 -可以执行此代码。 +可以執行此代碼。 ```python b = ![1, 2, 3] @@ -19,8 +19,8 @@ b.concat! [4, 5, 6] print! b # [1, 2, 3, 4, 5, 6] ``` -`a, b` 的最终结果看起来一样,但它们的含义却大不相同。 -虽然 `a` 是表示 `Nat` 数组的变量,但第一行和第二行指向的对象是不同的。 名称`a`相同,但内容不同。 +`a, b` 的最終結果看起來一樣,但它們的含義卻大不相同。 +雖然 `a` 是表示 `Nat` 數組的變量,但第一行和第二行指向的對象是不同的。 名稱`a`相同,但內容不同。 ```python a = [1, 2, 3] @@ -29,9 +29,9 @@ _a = a + [4, 5, 6] print! id! _a # 0x000002A798DFE980 ``` -`id!` 过程返回对象驻留的内存地址。 +`id!` 過程返回對象駐留的內存地址。 -`b` 是一个 `Nat` “动态” 数组。 对象的内容发生了变化,但变量指向的是同一个东西 +`b` 是一個 `Nat` “動態” 數組。 對象的內容發生了變化,但變量指向的是同一個東西 ```python b = ![1, 2, 3] @@ -48,13 +48,13 @@ if! True. do! print! i # 1 ``` -`!` 是一个特殊的运算符,称为 __mutation 运算符__。 它使不可变对象可变。 -标有“!”的对象的行为可以自定义。 +`!` 是一個特殊的運算符,稱為 __mutation 運算符__。 它使不可變對象可變。 +標有“!”的對象的行為可以自定義。 ```python Point = Class {.x = Int; .y = Int} -# 在这种情况下 .x 是可变的,而 .y 保持不变 +# 在這種情況下 .x 是可變的,而 .y 保持不變 Point! = Class {.x = Int!; .y = Int} Point!. inc_x! ref!(self) = self.x.update! x -> x + 1 @@ -66,8 +66,8 @@ print! p.x # 1 ## 常量 -与变量不同,常量在所有范围内都指向同一事物。 -常量使用 `=` 运算符声明。 +與變量不同,常量在所有范圍內都指向同一事物。 +常量使用 `=` 運算符聲明。 ```python PI = 3.141592653589 @@ -75,29 +75,29 @@ match! x: PI => print! "this is pi" ``` -常量在全局以下的所有范围内都是相同的,并且不能被覆盖。因此,它们不能被 ``=`` 重新定义。此限制允许它用于模式匹配。 -`True` 和 `False` 可以用于模式匹配的原因是因为它们是常量。 -此外,常量总是指向不可变对象。诸如 `Str!` 之类的类型不能是常量。 -所有内置类型都是常量,因为它们应该在编译时确定。可以生成非常量的类型,但不能用于指定类型,只能像简单记录一样使用。相反,类型是其内容在编译时确定的记录。 +常量在全局以下的所有范圍內都是相同的,并且不能被覆蓋。因此,它們不能被 ``=`` 重新定義。此限制允許它用于模式匹配。 +`True` 和 `False` 可以用于模式匹配的原因是因為它們是常量。 +此外,常量總是指向不可變對象。諸如 `Str!` 之類的類型不能是常量。 +所有內置類型都是常量,因為它們應該在編譯時確定。可以生成非常量的類型,但不能用于指定類型,只能像簡單記錄一樣使用。相反,類型是其內容在編譯時確定的記錄。 -## 变量、名称、标识符、符号 +## 變量、名稱、標識符、符號 -让我们理清一些与 Erg 中的变量相关的术语。 +讓我們理清一些與 Erg 中的變量相關的術語。 -变量是一种为对象赋予名称以便可以重用(或指向该名称)的机制。 -标识符是指定变量的语法元素。 -符号是表示名称的语法元素、记号。 +變量是一種為對象賦予名稱以便可以重用(或指向該名稱)的機制。 +標識符是指定變量的語法元素。 +符號是表示名稱的語法元素、記號。 -只有非符号字符是符号,符号不称为符号,尽管它们可以作为运算符的标识符。 -例如,`x` 是一个标识符和一个符号。 `x.y` 也是一个标识符,但它不是一个符号。 `x` 和 `y` 是符号。 -即使 `x` 没有绑定到任何对象,`x` 仍然是一个符号和一个标识符,但它不会被称为变量。 -`x.y` 形式的标识符称为字段访问器。 -`x[y]` 形式的标识符称为下标访问器。 +只有非符號字符是符號,符號不稱為符號,盡管它們可以作為運算符的標識符。 +例如,`x` 是一個標識符和一個符號。 `x.y` 也是一個標識符,但它不是一個符號。 `x` 和 `y` 是符號。 +即使 `x` 沒有綁定到任何對象,`x` 仍然是一個符號和一個標識符,但它不會被稱為變量。 +`x.y` 形式的標識符稱為字段訪問器。 +`x[y]` 形式的標識符稱為下標訪問器。 -变量和标识符之间的区别在于,如果我们在 Erg 的语法理论意义上谈论变量,则两者实际上是相同的。 -在 C 中,类型和函数不能分配给变量; int 和 main 是标识符,而不是变量(严格来说可以赋值,但有限制)。 -然而,在Erg语中,“一切都是对象”。不仅函数和类型,甚至运算符都可以分配给变量。 +變量和標識符之間的區別在于,如果我們在 Erg 的語法理論意義上談論變量,則兩者實際上是相同的。 +在 C 中,類型和函數不能分配給變量; int 和 main 是標識符,而不是變量(嚴格來說可以賦值,但有限制)。 +然而,在Erg語中,“一切都是對象”。不僅函數和類型,甚至運算符都可以分配給變量。

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/18_ownership.md b/doc/zh_TW/syntax/18_ownership.md index 0f473a8f..8bbdf86a 100644 --- a/doc/zh_TW/syntax/18_ownership.md +++ b/doc/zh_TW/syntax/18_ownership.md @@ -1,13 +1,13 @@ -#所有权制度 +#所有權制度 -由于 Erg 是一种使用 Python 作为宿主语言的语言,因此内存管理的方法取决于 Python 的实现。 -但语义上 Erg 的内存管理与 Python 的不同。 一个显着的区别在于所有权制度和禁止循环引用。 +由于 Erg 是一種使用 Python 作為宿主語言的語言,因此內存管理的方法取決于 Python 的實現。 +但語義上 Erg 的內存管理與 Python 的不同。 一個顯著的區別在于所有權制度和禁止循環引用。 -## 所有权 +## 所有權 -Erg 有一个受 Rust 启发的所有权系统。 -Rust 的所有权系统通常被认为是深奥的,但 Erg 的所有权系统被简化为直观。 -在 Erg 中,__mutable objects__ 是拥有的,并且在所有权丢失后无法引用。 +Erg 有一個受 Rust 啟發的所有權系統。 +Rust 的所有權系統通常被認為是深奧的,但 Erg 的所有權系統被簡化為直觀。 +在 Erg 中,__mutable objects__ 是擁有的,并且在所有權丟失后無法引用。 ```python v = [1, 2, 3].into [Int; !3] @@ -16,23 +16,23 @@ push! vec, x = vec.push!(x) vec -# v ([1, 2, 3])的内容归w所有 +# v ([1, 2, 3])的內容歸w所有 w = push! v, 4 -print! v # 错误:v 被移动了 +print! v # 錯誤:v 被移動了 print!w # [1, 2, 3, 4] ``` -例如,当一个对象被传递给一个子程序时,就会发生所有权转移。 -如果您想在赠送后仍然拥有所有权,则需要克隆、冻结或借用。 -但是,如后所述,可以借用的情况有限。 +例如,當一個對象被傳遞給一個子程序時,就會發生所有權轉移。 +如果您想在贈送后仍然擁有所有權,則需要克隆、凍結或借用。 +但是,如后所述,可以借用的情況有限。 -## 复制 +## 復制 -复制一个对象并转移其所有权。 它通过将 `.clone` 方法应用于实际参数来做到这一点。 -复制的对象与原始对象完全相同,但相互独立,不受更改影响。 +復制一個對象并轉移其所有權。 它通過將 `.clone` 方法應用于實際參數來做到這一點。 +復制的對象與原始對象完全相同,但相互獨立,不受更改影響。 -复制相当于 Python 的深拷贝,由于它完全重新创建相同的对象,因此计算和内存成本通常高于冻结和借用。 -需要复制对象的子例程被称为“参数消耗”子例程。 +復制相當于 Python 的深拷貝,由于它完全重新創建相同的對象,因此計算和內存成本通常高于凍結和借用。 +需要復制對象的子例程被稱為“參數消耗”子例程。 ```python capitalize s: Str!= @@ -44,30 +44,30 @@ s2 = capitalize s1.clone() log s2, s1 # !"HELLO hello" ``` -## 冻结 +## 凍結 -我们利用了不可变对象可以从多个位置引用的事实,并将可变对象转换为不可变对象。 -这称为冻结。 例如,在从可变数组创建迭代器时会使用冻结。 -由于您不能直接从可变数组创建迭代器,请将其转换为不可变数组。 -如果您不想破坏数组,请使用 [`.freeze_map` 方法](./type/mut.md)。 +我們利用了不可變對象可以從多個位置引用的事實,并將可變對象轉換為不可變對象。 +這稱為凍結。 例如,在從可變數組創建迭代器時會使用凍結。 +由于您不能直接從可變數組創建迭代器,請將其轉換為不可變數組。 +如果您不想破壞數組,請使用 [`.freeze_map` 方法](./type/mut.md)。 ```python -# 计算迭代器产生的值的总和 +# 計算迭代器產生的值的總和 sum|T <: Add + HasUnit| i: Iterator T = ... x = [1, 2, 3].into [Int; !3] x.push!(4) -i = x.iter() # 类型错误:[Int; !4] 没有方法 `iter` +i = x.iter() # 類型錯誤:[Int; !4] 沒有方法 `iter` y = x.freeze() i = y.iter() assert sum(i) == 10 -y # y 仍然可以被触摸 +y # y 仍然可以被觸摸 ``` ## 借 -借用比复制或冻结便宜。 -可以在以下简单情况下进行借款: +借用比復制或凍結便宜。 +可以在以下簡單情況下進行借款: ```python peek_str ref(s: Str!) = @@ -77,34 +77,34 @@ s = !"hello" peek_str s ``` -借来的值称为原始对象的 __reference__。 -您可以“转租”对另一个子例程的引用,但您不能使用它,因为您只是借用它。 +借來的值稱為原始對象的 __reference__。 +您可以“轉租”對另一個子例程的引用,但您不能使用它,因為您只是借用它。 ```python steal_str ref(s: Str!) = - # 由于日志函数只借用参数,所以可以转租 + # 由于日志函數只借用參數,所以可以轉租 log s - # 错误,因为丢弃函数消耗了参数 - discard s # OwnershipError: 不能消费借来的值 + # 錯誤,因為丟棄函數消耗了參數 + discard s # OwnershipError: 不能消費借來的值 # 提示:使用 `clone` 方法 ``` ```python steal_str ref(s: Str!) = - # 这也不好(=消耗右边) - x = s # OwnershipError: 不能消费借来的值 + # 這也不好(=消耗右邊) + x = s # OwnershipError: 不能消費借來的值 x ``` -Erg 的引用比 Rust 的更严格。 引用是语言中的一等对象,但不能显式创建,它们只能指定为通过 `ref`/`ref!` 传递的参数。 -这意味着您不能将引用填充到数组中或创建将引用作为属性的类。 +Erg 的引用比 Rust 的更嚴格。 引用是語言中的一等對象,但不能顯式創建,它們只能指定為通過 `ref`/`ref!` 傳遞的參數。 +這意味著您不能將引用填充到數組中或創建將引用作為屬性的類。 -但是,这样的限制是语言中的自然规范,一开始就没有引用,而且它们并没有那么不方便。 +但是,這樣的限制是語言中的自然規范,一開始就沒有引用,而且它們并沒有那么不方便。 -## 循环引用 +## 循環引用 -Erg 旨在防止无意的内存泄漏,如果内存检查器检测到循环引用,则会发出错误。 在大多数情况下,这个错误可以通过弱引用 `Weak` 来解决。 但是,由于无法生成循环图等具有循环结构的对象,因此我们计划实现一个 API,可以将循环引用作为不安全操作生成。 +Erg 旨在防止無意的內存泄漏,如果內存檢查器檢測到循環引用,則會發出錯誤。 在大多數情況下,這個錯誤可以通過弱引用 `Weak` 來解決。 但是,由于無法生成循環圖等具有循環結構的對象,因此我們計劃實現一個 API,可以將循環引用作為不安全操作生成。

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/19_visibility.md b/doc/zh_TW/syntax/19_visibility.md index 0e79c0e0..2bec3898 100644 --- a/doc/zh_TW/syntax/19_visibility.md +++ b/doc/zh_TW/syntax/19_visibility.md @@ -1,8 +1,8 @@ -# 可见性 +# 可見性 -Erg 变量具有 __visibility__ 的概念。 -到目前为止,我们看到的所有变量都称为 __private variables__。 这是一个外部不可见的变量。 -例如,`foo` 模块中定义的私有变量不能被另一个模块引用。 +Erg 變量具有 __visibility__ 的概念。 +到目前為止,我們看到的所有變量都稱為 __private variables__。 這是一個外部不可見的變量。 +例如,`foo` 模塊中定義的私有變量不能被另一個模塊引用。 ```python # foo.er @@ -12,11 +12,11 @@ x = "this is an invisible variable" ```python #bar.er foo = import "foo" -foo.x # AttributeError: 模块 'foo' 没有属性 'x' ('x' 是私有的) +foo.x # AttributeError: 模塊 'foo' 沒有屬性 'x' ('x' 是私有的) ``` -另一方面,也有__public variables__,可以从外部引用。 -公共变量用`.`定义。 +另一方面,也有__public variables__,可以從外部引用。 +公共變量用`.`定義。 ```python # foo.er @@ -29,7 +29,7 @@ foo = import "foo" assert foo.x == "this is a visible variable" ``` -您不需要向私有变量添加任何内容,但您也可以添加 `::` 或 `self::`(用于类型等的`Self::`)以表明它们是私有的。 增加。 如果它是一个模块,它也可以是 `module::` +您不需要向私有變量添加任何內容,但您也可以添加 `::` 或 `self::`(用于類型等的`Self::`)以表明它們是私有的。 增加。 如果它是一個模塊,它也可以是 `module::` ```python ::x = "this is an invisible variable" @@ -46,9 +46,9 @@ y = x + 1 # 完全是 module::x ``` -通过使用`::`,可以区分作用域内同名的变量。 -在左侧指定要引用的变量的范围。 为顶层指定 `module`。 -如果未指定,则照常引用最里面的变量。 +通過使用`::`,可以區分作用域內同名的變量。 +在左側指定要引用的變量的范圍。 為頂層指定 `module`。 +如果未指定,則照常引用最里面的變量。 ```python ::x = 0 @@ -73,21 +73,21 @@ f = x -> f1# 0 1 ``` -`::` 还负责访问私有实例属性。 +`::` 還負責訪問私有實例屬性。 ```python x = 0 C = Class {x = Int} C. - # 顶级 x 被引用(警告使用 module::x) + # 頂級 x 被引用(警告使用 module::x) f1 self = x - # 实例属性 x 被引用 + # 實例屬性 x 被引用 f2 self = self::x ``` -## 外部模块中的可见性 +## 外部模塊中的可見性 -在一个模块中定义的类实际上可以定义来自外部模块的方法。 +在一個模塊中定義的類實際上可以定義來自外部模塊的方法。 ```python # foo.er @@ -106,35 +106,35 @@ Foo. .f() = foo = Foo.new() foo.public() - foo::private() # 属性错误 + foo::private() # 屬性錯誤 ``` -但是,这两种方法都只在该模块中可用。 -外部定义的私有方法对 Foo 类的方法仅在定义模块内可见。 -公共方法暴露在类之外,但不在模块之外。 +但是,這兩種方法都只在該模塊中可用。 +外部定義的私有方法對 Foo 類的方法僅在定義模塊內可見。 +公共方法暴露在類之外,但不在模塊之外。 ```python # baz.er {Foo; ...} = import "foo" foo = Foo.new() -foo.public() # 属性错误:“Foo”没有属性“public”(“public”在模块“bar”中定义) +foo.public() # 屬性錯誤:“Foo”沒有屬性“public”(“public”在模塊“bar”中定義) ``` -此外,方法不能在要重新导出的类型中定义。 -这是为了避免混淆方法是否找到,具体取决于导入方法的模块。 +此外,方法不能在要重新導出的類型中定義。 +這是為了避免混淆方法是否找到,具體取決于導入方法的模塊。 ```python #bar.er {.Foo; ...} = import "foo" .Foo:: - private self = pass # 错误 + private self = pass # 錯誤 Foo. - public self = self::private() # 错误 + public self = self::private() # 錯誤 ``` -如果你想做这样的事情,定义一个 [patch](./type/07_patch.md)。 +如果你想做這樣的事情,定義一個 [patch](./type/07_patch.md)。 ```python #bar.er @@ -156,10 +156,10 @@ foo = Foo.new() foo.public() ``` -## 受限公共变量 +## 受限公共變量 -可变可见性不限于完全公共/私有。 -您也可以有限制地发布。 +可變可見性不限于完全公共/私有。 +您也可以有限制地發布。 ```python # foo.er @@ -174,18 +174,18 @@ foo.public() _ = .a.z # OK } -_ = .record.a.x # 可见性错误 +_ = .record.a.x # 可見性錯誤 _ = .record.a.y # OK _ = .record.a.z # OK ``` ```python foo = import "foo" -_ = foo.record.a.x # 可见性错误 -_ = foo.record.a.y # 可见性错误 +_ = foo.record.a.x # 可見性錯誤 +_ = foo.record.a.y # 可見性錯誤 _ = foo.record.a.z # OK ```

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/20_naming_rule.md b/doc/zh_TW/syntax/20_naming_rule.md index 7847b7ce..7c946340 100644 --- a/doc/zh_TW/syntax/20_naming_rule.md +++ b/doc/zh_TW/syntax/20_naming_rule.md @@ -1,6 +1,6 @@ -# 命名约定 +# 命名約定 -如果要将变量用作常量表达式,请确保它以大写字母开头。 两个或多个字母可能是小写的。 +如果要將變量用作常量表達式,請確保它以大寫字母開頭。 兩個或多個字母可能是小寫的。 ```python i: Option Type = Int @@ -9,42 +9,42 @@ match i: None -> log "None" ``` -具有副作用的对象总是以 `!` 结尾。 程序和程序方法,以及可变类型。 -然而,`Proc` 类型本身是不可变的。 +具有副作用的對象總是以 `!` 結尾。 程序和程序方法,以及可變類型。 +然而,`Proc` 類型本身是不可變的。 ```python # Callable == Func or Proc c: Callable = print! match c: - p! -> log "proc" # `: Proc` 可以省略,因为它是不言自明的 + p! -> log "proc" # `: Proc` 可以省略,因為它是不言自明的 f -> log "func" ``` -如果您想向外界公开一个属性,请在开头使用 `.` 定义它。 如果你不把`.`放在开头,它将是私有的。 为避免混淆,它们不能在同一范围内共存。 +如果您想向外界公開一個屬性,請在開頭使用 `.` 定義它。 如果你不把`.`放在開頭,它將是私有的。 為避免混淆,它們不能在同一范圍內共存。 ```python -o = {x = 1; .x = 2} # 语法错误:同名的私有变量和公共变量不能共存 +o = {x = 1; .x = 2} # 語法錯誤:同名的私有變量和公共變量不能共存 ``` -## 文字标识符 +## 文字標識符 -可以通过将字符串括在单引号 ('') 中来规避上述规则。 也就是说,程序对象也可以在没有 `!` 的情况下分配。 但是,在这种情况下,即使该值是常量表达式,也不会被视为常量。 -像这样用单引号括起来的字符串称为文字标识符。 -这在调用Python等其他语言的API(FFI)时使用。 +可以通過將字符串括在單引號 ('') 中來規避上述規則。 也就是說,程序對象也可以在沒有 `!` 的情況下分配。 但是,在這種情況下,即使該值是常量表達式,也不會被視為常量。 +像這樣用單引號括起來的字符串稱為文字標識符。 +這在調用Python等其他語言的API(FFI)時使用。 ```python bar! = pyimport("foo").'bar' ``` -在 Erg 中也有效的标识符不需要用 '' 括起来。 +在 Erg 中也有效的標識符不需要用 '' 括起來。 -此外,文字标识符可以包含符号和空格,因此通常不能用作标识符的字符串可以用作标识符。 +此外,文字標識符可以包含符號和空格,因此通常不能用作標識符的字符串可以用作標識符。 ```python -'∂/∂t' y +'?/?t' y 'test 1: pass x to y'() ```

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/21_lambda.md b/doc/zh_TW/syntax/21_lambda.md index c7252620..bb8e00dc 100644 --- a/doc/zh_TW/syntax/21_lambda.md +++ b/doc/zh_TW/syntax/21_lambda.md @@ -1,50 +1,50 @@ -# 匿名函数 +# 匿名函數 -匿名函数是一种无需命名即可动态创建函数对象的语法。 +匿名函數是一種無需命名即可動態創建函數對象的語法。 ```python -# `->` 是匿名函数操作符 +# `->` 是匿名函數操作符 # 同 `f x, y = x + y` f = (x, y) -> x + y # same as `g(x, y: Int): Int = x + y` g = (x, y: Int): Int -> x + y ``` -如果只有一个参数,您可以省略 `()`。 +如果只有一個參數,您可以省略 `()`。 ```python assert [1, 2, 3].map_collect(i -> i + 1) == [2, 3, 4] assert ((i, j) -> [i, j])(1, 2) == [1, 2] ``` -在下面的情况下,它是 `0..9, (i -> ...)` 而不是 `(0..9, i) -> ...` -`->` 在左侧只接受一个参数。 多个参数作为单个元组接收 +在下面的情況下,它是 `0..9, (i -> ...)` 而不是 `(0..9, i) -> ...` +`->` 在左側只接受一個參數。 多個參數作為單個元組接收 ```python for 0..9, i: Int -> ... ``` -在匿名函数中,由于空格,解析存在差异 +在匿名函數中,由于空格,解析存在差異 ```python -# 在这种情况下,解释为 `T(() -> Int)` +# 在這種情況下,解釋為 `T(() -> Int)` i: T() -> Int -# 在这种情况下,它被解释为 (U()) -> Int +# 在這種情況下,它被解釋為 (U()) -> Int k: U() -> Int ``` -匿名函数可以不带参数使用。 +匿名函數可以不帶參數使用。 ```python -# `=>` 是一个匿名过程操作符 -p! = () => print! # `p!` 被调用 -# `() ->`, `() =>` 有语法糖 `do`, `do!` -# p! = do! print! "`p!` 被调用 -p!() # `p!` 被调用 +# `=>` 是一個匿名過程操作符 +p! = () => print! # `p!` 被調用 +# `() ->`, `() =>` 有語法糖 `do`, `do!` +# p! = do! print! "`p!` 被調用 +p!() # `p!` 被調用 ``` -无参数函数可用于延迟初始化 +無參數函數可用于延遲初始化 ```python time = import "time" @@ -56,21 +56,21 @@ now = if! True: do date.new("1970", "1", "1", "00", "00") ``` -您还可以键入和模式匹配。 正因为如此,`match` 函数大多是借助匿名函数的力量来实现的。 -作为 `match` 函数的参数给出的匿名函数从顶部开始按顺序尝试。 因此,您应该在顶部描述特殊情况,在底部描述更一般的情况。 如果你弄错了顺序,编译器会发出警告(如果可能的话) +您還可以鍵入和模式匹配。 正因為如此,`match` 函數大多是借助匿名函數的力量來實現的。 +作為 `match` 函數的參數給出的匿名函數從頂部開始按順序嘗試。 因此,您應該在頂部描述特殊情況,在底部描述更一般的情況。 如果你弄錯了順序,編譯器會發出警告(如果可能的話) ```python n = (Complex or Ratio or Int).sample!() i = matchn: - PI -> PI # 如果等于常数 PI - For (i: 1..10) -> i # 整数从 1 到 10 + PI -> PI # 如果等于常數 PI + For (i: 1..10) -> i # 整數從 1 到 10 (i: Int) -> i # Int - (c: Complex) -> c.real() # 对于复杂。 Int < Complex,但可以回退 - _ -> panic "cannot convert to Int" # 如果以上都不适用。 match 必须涵盖所有模式 + (c: Complex) -> c.real() # 對于復雜。 Int < Complex,但可以回退 + _ -> panic "cannot convert to Int" # 如果以上都不適用。 match 必須涵蓋所有模式 ``` -错误处理通常也使用 `?` 或 `match` 完成。 +錯誤處理通常也使用 `?` 或 `match` 完成。 ```python res: ParseResult Int @@ -84,13 +84,13 @@ match res2: err: Error -> panic err.msg ``` -## 匿名多相关系数 +## 匿名多相關系數 ```python -# 与此相同 id|T|x:T = x +# 與此相同 id|T|x:T = x id = |T| x: T -> x ```

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/22_subroutine.md b/doc/zh_TW/syntax/22_subroutine.md index 38fafc51..da449e98 100644 --- a/doc/zh_TW/syntax/22_subroutine.md +++ b/doc/zh_TW/syntax/22_subroutine.md @@ -1,43 +1,43 @@ -# 子程序签名 +# 子程序簽名 -## 函数 +## 函數 ```python some_func(x: T, y: U) -> V some_func: (T, U) -> V ``` -## 过程 +## 過程 ```python some_proc!(x: T, y: U) => V some_proc!: (T, U) => V ``` -## 函数方法 +## 函數方法 -方法类型不能用`Self`在外部指定 +方法類型不能用`Self`在外部指定 ```python .some_method(self, x: T, y: U) => () -# Self.(T, U) => () 拥有 self 的所有权 +# Self.(T, U) => () 擁有 self 的所有權 .some_method: Ref(Self). (T, U) => () ``` -## 过程方法(依赖) +## 過程方法(依賴) -在下文中,假设类型 `T!` 采用类型参数 `N: Nat`。 要在外部指定它,请使用类型变量 +在下文中,假設類型 `T!` 采用類型參數 `N: Nat`。 要在外部指定它,請使用類型變量 ```python T!: Nat -> Type -# ~> 表示应用前后类型参数的状态(此时self必须是变量引用) +# ~> 表示應用前后類型參數的狀態(此時self必須是變量引用) T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => () ``` -注意,`.some_method` 的类型是 `Ref!(T(N ~> N+X))。 ({X}) => () | N,X:Nat`。 -对于没有 `ref!` 的方法,即在应用后被剥夺所有权,不能使用类型参数转换(`~>`)。 +注意,`.some_method` 的類型是 `Ref!(T(N ~> N+X))。 ({X}) => () | N,X:Nat`。 +對于沒有 `ref!` 的方法,即在應用后被剝奪所有權,不能使用類型參數轉換(`~>`)。 -如果取得所有权,则如下所示。 +如果取得所有權,則如下所示。 ```python # 如果不使用N,可以用_省略。 @@ -45,11 +45,11 @@ T!(N).some_method!: (Ref! T!(N ~> N+X), X: Nat) => () .some_method!|N, X: Nat|(self(N), X: Nat) => T!(N+X) ``` -## 运算符 +## 運算符 -可以通过用 ` 括起来将其定义为普通函数。 +可以通過用 ` 括起來將其定義為普通函數。 -中性字母运算符,例如 `and` 和 `or` 可以通过用 ` 括起来定义为中性运算符。 +中性字母運算符,例如 `and` 和 `or` 可以通過用 ` 括起來定義為中性運算符。 ```python and(x, y, z) = x and y and z @@ -58,5 +58,5 @@ and(x, y, z) = x and y and z ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/23_closure.md b/doc/zh_TW/syntax/23_closure.md index eb3122ac..67e9b0c1 100644 --- a/doc/zh_TW/syntax/23_closure.md +++ b/doc/zh_TW/syntax/23_closure.md @@ -1,6 +1,6 @@ -# 关闭 +# 關閉 -Erg 子例程有一个称为“闭包”的功能,可以捕获外部变量。 +Erg 子例程有一個稱為“閉包”的功能,可以捕獲外部變量。 ```python outer = 1 @@ -8,7 +8,7 @@ f x = outer + x assert f(1) == 2 ``` -与不可变对象一样,可变对象也可以被捕获。 +與不可變對象一樣,可變對象也可以被捕獲。 ```python sum = !0 @@ -22,11 +22,11 @@ p!(1) assert sum == 46 ``` -但是请注意,函数不能捕获可变对象。 -如果可以在函数中引用可变对象,则可以编写如下代码。 +但是請注意,函數不能捕獲可變對象。 +如果可以在函數中引用可變對象,則可以編寫如下代碼。 ```python -# !!! 这段代码实际上给出了一个错误!!! +# !!! 這段代碼實際上給出了一個錯誤!!! i = !0 f x = i + x assert f 1 == 1 @@ -34,10 +34,10 @@ i.add! 1 assert f 1 == 2 ``` -该函数应该为相同的参数返回相同的值,但假设被打破了。 -请注意,`i` 仅在调用时进行评估。 +該函數應該為相同的參數返回相同的值,但假設被打破了。 +請注意,`i` 僅在調用時進行評估。 -如果您想在定义函数时获取可变对象的内容,请调用`.clone` +如果您想在定義函數時獲取可變對象的內容,請調用`.clone` ```python i = !0 @@ -58,7 +58,7 @@ for! 1..10, i => assert sum == 45 ``` -上面的等效程序可以用 Python 编写如下: +上面的等效程序可以用 Python 編寫如下: ```python # Python @@ -68,29 +68,29 @@ for i in range(1, 10): assert sum == 45 ``` -但是,Erg 建议使用更简单的表示法。 -与其使用子例程和可变对象来传递状态,不如使用一种使用函数来定位状态的风格。这称为函数式编程 +但是,Erg 建議使用更簡單的表示法。 +與其使用子例程和可變對象來傳遞狀態,不如使用一種使用函數來定位狀態的風格。這稱為函數式編程 ```python -# 功能风格 +# 功能風格 sum = (1..10).sum() assert sum == 45 ``` -上面的代码给出了与之前完全相同的结果,但是您可以看到这个代码要简单得多。 +上面的代碼給出了與之前完全相同的結果,但是您可以看到這個代碼要簡單得多。 -`fold` 函数可以用来做比 sum 更多的事情。 -`fold` 是一个迭代器方法,它为每次迭代执行参数 `f`。 -累加结果的计数器的初始值在 `init` 中指定,并在 `acc` 中累加。 +`fold` 函數可以用來做比 sum 更多的事情。 +`fold` 是一個迭代器方法,它為每次迭代執行參數 `f`。 +累加結果的計數器的初始值在 `init` 中指定,并在 `acc` 中累加。 ```python -# 从0开始,结果会 +# 從0開始,結果會 sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i) assert sum == 45 ``` -Erg 被设计为对使用不可变对象进行编程的自然简洁描述。 +Erg 被設計為對使用不可變對象進行編程的自然簡潔描述。

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/24_module.md b/doc/zh_TW/syntax/24_module.md index eee8832e..eff76cdd 100644 --- a/doc/zh_TW/syntax/24_module.md +++ b/doc/zh_TW/syntax/24_module.md @@ -8,7 +8,7 @@ Erg allows you to think of the file itself as a single record. This is called a ``` ```python -# 定义 foo 模块与定义这条记录几乎相同 +# 定義 foo 模塊與定義這條記錄幾乎相同 foo = {.i = 1} ``` @@ -19,13 +19,13 @@ print! foo # assert foo.i == 1 ``` -由于模块类型也是记录类型,因此可以进行解构赋值 +由于模塊類型也是記錄類型,因此可以進行解構賦值 ```python {sin; cos; ...} = import "math" ``` -## 模块可见性 +## 模塊可見性 ```console └─┬ ./src @@ -38,5 +38,5 @@ assert foo.i == 1 ```

- 上一页 | 下一页 + 上一頁 | 下一頁

\ 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 index 116cd662..ce089cc3 100644 --- a/doc/zh_TW/syntax/25_object_system.md +++ b/doc/zh_TW/syntax/25_object_system.md @@ -1,19 +1,19 @@ # 目的 -可以分配给变量的所有数据。 `Object` 类的属性如下。 +可以分配給變量的所有數據。 `Object` 類的屬性如下。 -* `.__repr__`:返回对象的(非丰富)字符串表示 -* `.__sizeof__`:返回对象的大小(包括堆分配) -* `.__dir__`: 返回对象属性列表 -* `.__hash__`:返回对象的哈希值 -* `.__getattribute__`: 获取并返回对象的属性 -* `.clone`:创建并返回一个对象的克隆(在内存中有一个独立的实体) -* `.copy`:返回对象的副本(指向内存中的同一事物) +* `.__repr__`:返回對象的(非豐富)字符串表示 +* `.__sizeof__`:返回對象的大小(包括堆分配) +* `.__dir__`: 返回對象屬性列表 +* `.__hash__`:返回對象的哈希值 +* `.__getattribute__`: 獲取并返回對象的屬性 +* `.clone`:創建并返回一個對象的克隆(在內存中有一個獨立的實體) +* `.copy`:返回對象的副本(指向內存中的同一事物) -## 记录 +## 記錄 -由记录文字(`{attr = value; ...}`)生成的对象。 -这个对象有基本的方法,比如`.clone`和`.__sizeof__`。 +由記錄文字(`{attr = value; ...}`)生成的對象。 +這個對象有基本的方法,比如`.clone`和`.__sizeof__`。 ```python obj = {.x = 1} @@ -23,12 +23,12 @@ obj2 = {...x; .y = 2} assert obj2.x == 1 and obj2.y == 2 ``` -## 属性 +## 屬性 -与对象关联的对象。 特别是,将 self (`self`) 作为其隐式第一个参数的子例程属性称为方法。 +與對象關聯的對象。 特別是,將 self (`self`) 作為其隱式第一個參數的子例程屬性稱為方法。 ```python -# 请注意,private_attr 中没有`.` +# 請注意,private_attr 中沒有`.` record = {.public_attr = j; private_attr = 2; .method = self -> self.i + 1} record. public_attr == 2 record.private_attr # AttributeError: private_attr 是私有的 @@ -37,46 +37,46 @@ assert record.method() == 3 ## 元素 -属于特定类型的对象(例如,“1”是“Int”类型的元素)。所有对象至少是`{=}`类型的元素。 -类的元素有时称为实例。 +屬于特定類型的對象(例如,“1”是“Int”類型的元素)。所有對象至少是`{=}`類型的元素。 +類的元素有時稱為實例。 ## 子程序 -表示作为函数或过程(包括方法)实例的对象。代表子程序的类是“子程序”。 -实现 `.__call__` 的对象通常称为 `Callable`。 +表示作為函數或過程(包括方法)實例的對象。代表子程序的類是“子程序”。 +實現 `.__call__` 的對象通常稱為 `Callable`。 -## 可调用 +## 可調用 -一个实现`.__call__`的对象。它也是 `Subroutine` 的超类。 +一個實現`.__call__`的對象。它也是 `Subroutine` 的超類。 -## 类型 +## 類型 -定义需求属性并使对象通用化的对象。 -主要有两种类型:多态类型和单态类型。典型的单态类型有`Int`、`Str`等,多态类型有`Option Int`、`[Int; 3]`等 -此外,定义改变对象状态的方法的类型称为 Mutable 类型,需要在变量属性中添加 `!`(例如动态数组:`[T; !_]`)。 +定義需求屬性并使對象通用化的對象。 +主要有兩種類型:多態類型和單態類型。典型的單態類型有`Int`、`Str`等,多態類型有`Option Int`、`[Int; 3]`等 +此外,定義改變對象狀態的方法的類型稱為 Mutable 類型,需要在變量屬性中添加 `!`(例如動態數組:`[T; !_]`)。 -## 班级 +## 班級 -具有 `.__new__`、`.__init__` 方法等的类型。实现基于类的面向对象。 +具有 `.__new__`、`.__init__` 方法等的類型。實現基于類的面向對象。 ## 功能 -对外部变量(不包括静态变量)有读权限但对外部变量没有读/写权限的子程序。换句话说,它没有外部副作用。 -Erg 函数的定义与 Python 的不同,因为它们不允许副作用。 +對外部變量(不包括靜態變量)有讀權限但對外部變量沒有讀/寫權限的子程序。換句話說,它沒有外部副作用。 +Erg 函數的定義與 Python 的不同,因為它們不允許副作用。 ## 程序 -它对外部变量具有读取和“自我”权限,对静态变量具有读/写权限,并允许使用所有子例程。它可能有外部副作用。 +它對外部變量具有讀取和“自我”權限,對靜態變量具有讀/寫權限,并允許使用所有子例程。它可能有外部副作用。 ## 方法 -隐式将“self”作为第一个参数的子例程。它与简单的函数/过程是不同的类型。 +隱式將“self”作為第一個參數的子例程。它與簡單的函數/過程是不同的類型。 -## 实体 +## 實體 -不是子例程和类型的对象。 -单态实体(`1`、`"a"` 等)也称为值对象,多态实体(`[1, 2, 3], {"a": 1}`)也称为容器对象。 +不是子例程和類型的對象。 +單態實體(`1`、`"a"` 等)也稱為值對象,多態實體(`[1, 2, 3], {"a": 1}`)也稱為容器對象。

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/26_pattern_matching.md b/doc/zh_TW/syntax/26_pattern_matching.md index 047fc29d..9c4cdbd5 100644 --- a/doc/zh_TW/syntax/26_pattern_matching.md +++ b/doc/zh_TW/syntax/26_pattern_matching.md @@ -1,26 +1,26 @@ -# 模式匹配,可反驳 +# 模式匹配,可反駁 ## Erg 中可用的模式 -### 变量模式 +### 變量模式 ```python -# 基本任务 +# 基本任務 i = 1 -# 有类型 +# 有類型 i: Int = 1 -# 匿名类型 +# 匿名類型 i: {1, 2, 3} = 2 # 功能 fn x = x + 1 # 等于 fn x: Add(Int) = x + 1 -# (匿名)函数 +# (匿名)函數 fn = x -> x + 1 fn: Int -> Int = x -> x + 1 -# 高阶类型 +# 高階類型 a: [Int; 4] = [0, 1, 2, 3] # or a: Array Int, 4 = [0, 1, 2, 3] @@ -29,17 +29,17 @@ a: Array Int, 4 = [0, 1, 2, 3] ### 文字字面量 ```python -# 如果在编译时无法确定 `i` 为 1,则引发 TypeError。 +# 如果在編譯時無法確定 `i` 為 1,則引發 TypeError。 # 省略 `_: {1} = i` 1 = i -# 简单的模式匹配 +# 簡單的模式匹配 match x: 1 -> "1" 2 -> "2" _ -> "other" -# 斐波那契函数 +# 斐波那契函數 fib0 = 0 fib1 = 1 fibn: Nat = fibn-1 + fibn-2 @@ -62,18 +62,18 @@ name = match num: _ -> "unnamed" ``` -### 筛子图案 +### 篩子圖案 ```python -# 这两个是一样的 +# 這兩個是一樣的 Array(T, N: {N | N >= 3}) Array(T, N | N >= 3) f M, N | M >= 0, N >= 1 = ... -f(1, 0) # 类型错误:N(第二个参数)必须为 1 或更多 +f(1, 0) # 類型錯誤:N(第二個參數)必須為 1 或更多 ``` -### 丢弃(通配符)模式 +### 丟棄(通配符)模式 ```python _ = 1 @@ -82,9 +82,9 @@ zero_ = 0 right(_, r) = r ``` -### 可变长度模式 +### 可變長度模式 -它与稍后描述的元组/数组/记录模式结合使用。 +它與稍后描述的元組/數組/記錄模式結合使用。 ```python [i,...j] = [1, 2, 3, 4] @@ -93,18 +93,18 @@ first|T|(fst: T, ...rest: T) = fst assert first(1, 2, 3) == 1 ``` -### 元组模式 +### 元組模式 ```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) -# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) +# 如果不嵌套,() 可以省略(1, 2 被視為(1, 2)) m, n = 1, 2 f(x, y) = ... ``` -### 数组模式 +### 數組模式 ```python [i, j] = [1, 2] @@ -118,7 +118,7 @@ length[_, ...rest] = 1 + lengthrest ```python record = {i = 1; j = 2; k = 3} -{j; ...} = record # i, k 将被释放 +{j; ...} = record # i, k 將被釋放 {sin; cos; tan; ...} = import "math" {*} = import "math" # import all @@ -131,7 +131,7 @@ age = match person: f {x: Int; y: Int} = ... ``` -### 数据类模式 +### 數據類模式 ```python Point = Inherit {x = Int; y = Int} @@ -152,9 +152,9 @@ List T. _ -> ... ``` -### 枚举模式 +### 枚舉模式 -* 其实只是枚举类型 +* 其實只是枚舉類型 ```python match x: @@ -164,7 +164,7 @@ match x: ### Range 模式 -* 实际上,它只是一个区间类型。 +* 實際上,它只是一個區間類型。 ```python # 0 < i < 1 @@ -176,18 +176,18 @@ match i i: 1..5 -> ... ``` -### 不是模式的东西,不能被模式化的东西 +### 不是模式的東西,不能被模式化的東西 -模式是可以唯一指定的东西。 在这方面,模式匹配不同于普通的条件分支。 +模式是可以唯一指定的東西。 在這方面,模式匹配不同于普通的條件分支。 -条件规格不是唯一的。 例如,要检查数字 `n` 是否为偶数,正统是 `n % 2 == 0`,但也可以写成 `(n / 2).round() == n / 2`。 -非唯一形式无论是正常工作还是等效于另一个条件都不是微不足道的。 +條件規格不是唯一的。 例如,要檢查數字 `n` 是否為偶數,正統是 `n % 2 == 0`,但也可以寫成 `(n / 2).round() == n / 2`。 +非唯一形式無論是正常工作還是等效于另一個條件都不是微不足道的。 #### Set -没有固定的模式。 因为集合没有办法唯一地检索元素。 -您可以通过迭代器检索它们,但不能保证顺序。 +沒有固定的模式。 因為集合沒有辦法唯一地檢索元素。 +您可以通過迭代器檢索它們,但不能保證順序。

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/27_comprehension.md b/doc/zh_TW/syntax/27_comprehension.md index 6e301665..1aae05b8 100644 --- a/doc/zh_TW/syntax/27_comprehension.md +++ b/doc/zh_TW/syntax/27_comprehension.md @@ -2,33 +2,33 @@ Array 和 `[expr | (name <- iterable)+ (predicate)*]`, set 和 `{expr | (name <- iterable)+ (predicate)*}`, -你可以创建一个字典 `{key: value | (name <- iterable)+ (predicate)*}`. +你可以創建一個字典 `{key: value | (name <- iterable)+ (predicate)*}`. -由`|`分隔的子句的第一部分称为布局子句(位置子句),第二部分称为绑定子句(绑定子句),第三部分称为保护子句(条件子句)。 -保护子句可以省略,但绑定子句不能省略,保护子句不能在绑定子句之前。 +由`|`分隔的子句的第一部分稱為布局子句(位置子句),第二部分稱為綁定子句(綁定子句),第三部分稱為保護子句(條件子句)。 +保護子句可以省略,但綁定子句不能省略,保護子句不能在綁定子句之前。 理解示例 ```python # 布局子句是 i -# 绑定子句是 i <- [0, 1, 2] +# 綁定子句是 i <- [0, 1, 2] assert [i | i <- [0, 1, 2]] == [0, 1, 2] # 布局子句是 i / 2 -# 绑定子句是 i <- 0..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 +# 綁定子句 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 中这并不重要。 +Erg推導式受到 Haskell 的啟發,但有一些不同。 +對于 Haskell 列表推導,變量的順序會對結果產生影響,但在 Erg 中這并不重要。 ``` haskell -- Haskell @@ -41,25 +41,25 @@ Erg推导式受到 Haskell 的启发,但有一些不同。 assert [(i, j) | i <- 1..<3; j <- 3..<5] == [(i, j) | j <- 3..<5; i <- 1.. <3] ``` -该规范与 Python 的规范相同。 +該規范與 Python 的規范相同。 ```python # Python assert [(i, j) for i in range(1, 3) for j in range(3, 5)] == [(i, j) for j in range(3, 5) for i in range(1, 3)] ``` -## 筛子类型 +## 篩子類型 -与推导类似的是筛类型。 筛子类型是以`{Name: Type | Predicate}`创建的(枚举类型) -sieve类型的情况下,只能指定一个Name,不能指定布局(但是如果是tuple类型可以处理多个值),Predicate可以在编译时计算,即 ,只能指定一个常量表达式。 +與推導類似的是篩類型。 篩子類型是以`{Name: Type | Predicate}`創建的(枚舉類型) +sieve類型的情況下,只能指定一個Name,不能指定布局(但是如果是tuple類型可以處理多個值),Predicate可以在編譯時計算,即 ,只能指定一個常量表達式。 ```python Nat = {I: Int | I >= 0} -# 如果谓词表达式只有and,可以替换为: +# 如果謂詞表達式只有and,可以替換為: # Nat2D = {(I, J): (Int, Int) | I >= 0; J >= 0} Nat2D = {(I, J): (Int, Int) | I >= 0 and J >= 0} ```

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/28_spread_syntax.md b/doc/zh_TW/syntax/28_spread_syntax.md index 81b98343..ab3c96fd 100644 --- a/doc/zh_TW/syntax/28_spread_syntax.md +++ b/doc/zh_TW/syntax/28_spread_syntax.md @@ -1,6 +1,6 @@ -# 传播赋值 +# 傳播賦值 -在分解赋值中,将 `...` 放在变量前面会将所有剩余元素展开到该变量中。 这称为扩展赋值。 +在分解賦值中,將 `...` 放在變量前面會將所有剩余元素展開到該變量中。 這稱為擴展賦值。 ```python [x,...y] = [1, 2, 3] @@ -11,10 +11,10 @@ assert x == 1 assert y == (2, 3) ``` -## 提取赋值 +## 提取賦值 -如果在 `...` 之后没有写入任何内容,则忽略并分配剩余的元素。 这种类型的扩展赋值具体称为抽取赋值。 -提取分配是一种方便的语法,用于本地化模块或记录中的特定属性。 +如果在 `...` 之后沒有寫入任何內容,則忽略并分配剩余的元素。 這種類型的擴展賦值具體稱為抽取賦值。 +提取分配是一種方便的語法,用于本地化模塊或記錄中的特定屬性。 ```python {sin; cos; tan; ..} = import "math" @@ -38,5 +38,5 @@ assert x == 1 and y == 2 ```

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/29_decorator.md b/doc/zh_TW/syntax/29_decorator.md index 9046f20c..c419cd4a 100644 --- a/doc/zh_TW/syntax/29_decorator.md +++ b/doc/zh_TW/syntax/29_decorator.md @@ -1,24 +1,24 @@ -# 装饰器(修饰符) +# 裝飾器(修飾符) -装饰器用于向类型或函数添加或演示特定状态或行为。 -装饰器的语法如下。 +裝飾器用于向類型或函數添加或演示特定狀態或行為。 +裝飾器的語法如下。 ```python @deco X=... ``` -你可以有多个装饰器,只要它们不冲突。 +你可以有多個裝飾器,只要它們不沖突。 -装饰器不是一个特殊的对象,它只是一个单参数函数。 装饰器等价于下面的伪代码。 +裝飾器不是一個特殊的對象,它只是一個單參數函數。 裝飾器等價于下面的偽代碼。 ```python X=... X = deco(X) ``` -Erg 不允许重新分配变量,因此上面的代码不起作用。 -对于简单的变量,它与`X = deco(...)` 相同,但对于即时块和子例程,你不能这样做,所以你需要一个装饰器。 +Erg 不允許重新分配變量,因此上面的代碼不起作用。 +對于簡單的變量,它與`X = deco(...)` 相同,但對于即時塊和子例程,你不能這樣做,所以你需要一個裝飾器。 ```python @deco @@ -26,29 +26,29 @@ f x = y = ... x + y -# 还可以防止代码变成水平的 +# 還可以防止代碼變成水平的 @LongNameDeco1 @LongNameDeco2 C = Class... ``` -下面是一些常用的内置装饰器。 +下面是一些常用的內置裝飾器。 -## 可继承 +## 可繼承 -指示定义类型是可继承的类。 如果为参数 `scope` 指定 `"public"`,甚至可以继承外部模块的类。 默认情况下它是`"private"`,不能被外部继承。 +指示定義類型是可繼承的類。 如果為參數 `scope` 指定 `"public"`,甚至可以繼承外部模塊的類。 默認情況下它是`"private"`,不能被外部繼承。 ## 最后 -使该方法不可覆盖。 将它添加到类中使其成为不可继承的类,但由于它是默认值,因此没有意义。 +使該方法不可覆蓋。 將它添加到類中使其成為不可繼承的類,但由于它是默認值,因此沒有意義。 -## 覆盖 +## 覆蓋 -覆盖属性时使用。 默认情况下,如果您尝试定义与基类相同的属性,Erg 将抛出错误。 +覆蓋屬性時使用。 默認情況下,如果您嘗試定義與基類相同的屬性,Erg 將拋出錯誤。 -## 实现 +## 實現 -表示参数 trait 已实现。 +表示參數 trait 已實現。 ```python Add = Trait { @@ -68,8 +68,8 @@ C. ## 附 -指定默认情况下随 trait 附带的附件补丁。 -这允许您重现与 Rust 特征相同的行为。 +指定默認情況下隨 trait 附帶的附件補丁。 +這允許您重現與 Rust 特征相同的行為。 ```python # foo.er @@ -86,17 +86,17 @@ AddForOdd = Patch(Odd, Impl := ClosedAdd) AddForOdd.AddO = Even ``` -当从其他模块导入特征时,这将自动应用附件补丁。 +當從其他模塊導入特征時,這將自動應用附件補丁。 ```Python -# 本来应该同时导入IntIsBinAdd和OddIsBinAdd,但是如果是附件补丁可以省略 +# 本來應該同時導入IntIsBinAdd和OddIsBinAdd,但是如果是附件補丁可以省略 {BinAdd; ...} = import "foo" assert Int. AddO == Int assert Odd.AddO == Even ``` -在内部,它只是使用 trait 的 .attach 方法附加的。 可以使用 trait 的 `.detach` 方法消除冲突。 +在內部,它只是使用 trait 的 .attach 方法附加的。 可以使用 trait 的 `.detach` 方法消除沖突。 ```python @Attach X @@ -107,14 +107,14 @@ assert X not in U. attaches assert Y in U. attaches ``` -## 已弃用 +## 已棄用 -指示变量规范已过时且不推荐使用。 +指示變量規范已過時且不推薦使用。 -## 测试 +## 測試 -表示这是一个测试子例程。 测试子程序使用 `erg test` 命令运行。 +表示這是一個測試子例程。 測試子程序使用 `erg test` 命令運行。

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/30_error_handling.md b/doc/zh_TW/syntax/30_error_handling.md index 5b64a6f8..3c549435 100644 --- a/doc/zh_TW/syntax/30_error_handling.md +++ b/doc/zh_TW/syntax/30_error_handling.md @@ -1,22 +1,22 @@ -# 错误处理系统 +# 錯誤處理系統 -主要使用Result类型。 -在 Erg 中,如果您丢弃 Error 类型的对象(顶层不支持),则会发生错误。 +主要使用Result類型。 +在 Erg 中,如果您丟棄 Error 類型的對象(頂層不支持),則會發生錯誤。 -## 异常,与 Python 互操作 +## 異常,與 Python 互操作 -Erg 没有异常机制(Exception)。 导入 Python 函数时 +Erg 沒有異常機制(Exception)。 導入 Python 函數時 -* 将返回值设置为 `T 或 Error` 类型 -* `T or Panic` 类型(可能导致运行时错误) +* 將返回值設置為 `T 或 Error` 類型 +* `T or Panic` 類型(可能導致運行時錯誤) -有两个选项,`pyimport` 默认为后者。 如果要作为前者导入,请使用 +有兩個選項,`pyimport` 默認為后者。 如果要作為前者導入,請使用 在 `pyimport` `exception_type` 中指定 `Error` (`exception_type: {Error, Panic}`)。 -## 异常和结果类型 +## 異常和結果類型 -`Result` 类型表示可能是错误的值。 `Result` 的错误处理在几个方面优于异常机制。 -首先,从类型定义中可以看出子程序可能会报错,实际使用时也很明显。 +`Result` 類型表示可能是錯誤的值。 `Result` 的錯誤處理在幾個方面優于異常機制。 +首先,從類型定義中可以看出子程序可能會報錯,實際使用時也很明顯。 ```python # Python @@ -28,7 +28,7 @@ except e: print(e) ``` -在上面的示例中,仅凭此代码无法判断哪个函数引发了异常。 即使回到函数定义,也很难判断函数是否抛出异常。 +在上面的示例中,僅憑此代碼無法判斷哪個函數引發了異常。 即使回到函數定義,也很難判斷函數是否拋出異常。 ```python # Erg @@ -41,14 +41,14 @@ try!: print! e ``` -另一方面,在这个例子中,我们可以看到 `foo!` 和 `qux!` 会引发错误。 -确切地说,`y` 也可能是 `Result` 类型,但您最终必须处理它才能使用里面的值。 +另一方面,在這個例子中,我們可以看到 `foo!` 和 `qux!` 會引發錯誤。 +確切地說,`y` 也可能是 `Result` 類型,但您最終必須處理它才能使用里面的值。 -使用 `Result` 类型的好处不止于此。 `Result` 类型也是线程安全的。 这意味着错误信息可以(轻松)在并行执行之间传递。 +使用 `Result` 類型的好處不止于此。 `Result` 類型也是線程安全的。 這意味著錯誤信息可以(輕松)在并行執行之間傳遞。 -## 语境 +## 語境 -由于 `Error`/`Result` 类型本身不会产生副作用,不像异常,它不能有发送位置(Context)等信息,但是如果使用 `.context` 方法,可以将信息放在 `错误`对象。 可以添加。 `.context` 方法是一种使用 `Error` 对象本身并创建新的 `Error` 对象的方法。 它们是可链接的,并且可以包含多个上下文。 +由于 `Error`/`Result` 類型本身不會產生副作用,不像異常,它不能有發送位置(Context)等信息,但是如果使用 `.context` 方法,可以將信息放在 `錯誤`對象。 可以添加。 `.context` 方法是一種使用 `Error` 對象本身并創建新的 `Error` 對象的方法。 它們是可鏈接的,并且可以包含多個上下文。 ```python f() = todo() \ @@ -61,14 +61,14 @@ f() # hint: and more hints ... ``` -请注意,诸如 `.msg` 和 `.kind` 之类的 `Error` 属性不是次要的,因此它们不是上下文,并且不能像最初创建时那样被覆盖。 +請注意,諸如 `.msg` 和 `.kind` 之類的 `Error` 屬性不是次要的,因此它們不是上下文,并且不能像最初創建時那樣被覆蓋。 -## 堆栈跟踪 +## 堆棧跟蹤 -`Result` 类型由于其方便性在其他语言中经常使用,但与异常机制相比,它的缺点是难以理解错误的来源。 -因此,在 Erg 中,`Error` 对象具有名为 `.stack` 的属性,并再现了类似伪异常机制的堆栈跟踪。 -`.stack` 是调用者对象的数组。 每次 Error 对象被`return`(包括通过`?`)时,它都会将它的调用子例程推送到`.stack`。 -如果它是 `?`ed 或 `.unwrap`ed 在一个不可能 `return` 的上下文中,它会因为回溯而恐慌。 +`Result` 類型由于其方便性在其他語言中經常使用,但與異常機制相比,它的缺點是難以理解錯誤的來源。 +因此,在 Erg 中,`Error` 對象具有名為 `.stack` 的屬性,并再現了類似偽異常機制的堆棧跟蹤。 +`.stack` 是調用者對象的數組。 每次 Error 對象被`return`(包括通過`?`)時,它都會將它的調用子例程推送到`.stack`。 +如果它是 `?`ed 或 `.unwrap`ed 在一個不可能 `return` 的上下文中,它會因為回溯而恐慌。 ```python f x = @@ -94,15 +94,15 @@ i = g(1)? ## 恐慌 -Erg 还有一种处理不可恢复错误的机制,称为 __panicing__。 -不可恢复的错误是由外部因素引起的错误,例如软件/硬件故障、严重到无法继续执行代码的错误或程序员未预料到的错误。 等如果发生这种情况,程序将立即终止,因为程序员的努力无法恢复正常运行。 这被称为“恐慌”。 +Erg 還有一種處理不可恢復錯誤的機制,稱為 __panicing__。 +不可恢復的錯誤是由外部因素引起的錯誤,例如軟件/硬件故障、嚴重到無法繼續執行代碼的錯誤或程序員未預料到的錯誤。 等如果發生這種情況,程序將立即終止,因為程序員的努力無法恢復正常運行。 這被稱為“恐慌”。 -恐慌是通过 `panic` 功能完成的。 +恐慌是通過 `panic` 功能完成的。 ```python panic "something went wrong!" ```

- 上一页 | 下一页 + 上一頁 | 下一頁

\ No newline at end of file diff --git a/doc/zh_TW/syntax/31_pipeline.md b/doc/zh_TW/syntax/31_pipeline.md index acaeef49..b8de0cf1 100644 --- a/doc/zh_TW/syntax/31_pipeline.md +++ b/doc/zh_TW/syntax/31_pipeline.md @@ -1,15 +1,15 @@ -# 管道运算符 +# 管道運算符 -管道运算符的使用方式如下: +管道運算符的使用方式如下: ```python assert f(g(x)) == (x |> g |> f) assert f(g(x, y)) == ((x, y) |> g |> f) ``` -换句话说,`Callable(object)` 的顺序可以更改为 `object |> Callable`。 -管道运算符也可用于方法。 对于方法,`object.method(args)` 更改为 `object |>.method(args)`。 -它看起来只是更多的`|>`,但由于粘合强度较低,您可以减少`()`的数量。 +換句話說,`Callable(object)` 的順序可以更改為 `object |> Callable`。 +管道運算符也可用于方法。 對于方法,`object.method(args)` 更改為 `object |>.method(args)`。 +它看起來只是更多的`|>`,但由于粘合強度較低,您可以減少`()`的數量。 ```python rand = -1.0..1.0 |>.sample!() @@ -18,7 +18,7 @@ log rand # 0.2597... 1+1*2 |>.times do log("a", end := "") # aaa evens = 1..100 |>.iter |>.filter i -> i % 2 == 0 |>.collect Array -# 在没有管道操作符的情况下实现, +# 在沒有管道操作符的情況下實現, _evens = (1..100).iter().filter(i -> i % 2 == 0).collect(Array) # or __evens = 1..100 \ @@ -28,5 +28,5 @@ __evens = 1..100 \ ```

- 上一页 | 下一页 + 上一頁 | 下一頁

\ 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 index d18ac194..6f2c4d56 100644 --- a/doc/zh_TW/syntax/32_integration_with_Python.md +++ b/doc/zh_TW/syntax/32_integration_with_Python.md @@ -1,9 +1,9 @@ -# 与 Python 集成 +# 與 Python 集成 -## 导出到 Python +## 導出到 Python -编译 Erg 脚本时,会生成一个 .pyc 文件,可以简单地将其作为 Python 模块导入。 -但是,无法从 Python 访问在 Erg 端设置为私有的变量。 +編譯 Erg 腳本時,會生成一個 .pyc 文件,可以簡單地將其作為 Python 模塊導入。 +但是,無法從 Python 訪問在 Erg 端設置為私有的變量。 ```python # foo.er @@ -19,26 +19,26 @@ erg --compile foo.er import foo print(foo.public) -print(foo.private) # 属性错误: +print(foo.private) # 屬性錯誤: ``` -## 从 Python 导入 +## 從 Python 導入 -默认情况下,从 Python 导入的所有对象都是“Object”类型。 由于此时无法进行比较,因此有必要细化类型。 +默認情況下,從 Python 導入的所有對象都是“Object”類型。 由于此時無法進行比較,因此有必要細化類型。 -## 标准库中的类型规范 +## 標準庫中的類型規范 -Python 标准库中的所有 API 都是由 Erg 开发团队指定的类型。 +Python 標準庫中的所有 API 都是由 Erg 開發團隊指定的類型。 ```python time = pyimport "time" time.sleep! 1 ``` -## 用户脚本的类型规范 +## 用戶腳本的類型規范 -创建一个类型为 Python `foo` 模块的 `foo.d.er` 文件。 -Python 端的类型提示被忽略,因为它们不是 100% 保证的。 +創建一個類型為 Python `foo` 模塊的 `foo.d.er` 文件。 +Python 端的類型提示被忽略,因為它們不是 100% 保證的。 ```python # foo.py @@ -63,12 +63,12 @@ foo = pyimport "foo" assert foo.bar(1) in Int ``` -这通过在运行时执行类型检查来确保类型安全。 ``declare`` 函数大致如下工作 +這通過在運行時執行類型檢查來確保類型安全。 ``declare`` 函數大致如下工作 ```python declare|S: Subroutine| sub!: S, T = - # 实际上,=> 可以强制转换为没有块副作用的函数 + # 實際上,=> 可以強制轉換為沒有塊副作用的函數 x => assert x in T.Input y = sub!(x) @@ -76,8 +76,8 @@ declare|S: Subroutine| sub!: S, T = y ``` -由于这是运行时开销,因此计划使用 Erg 的类型系统对 Python 脚本进行静态类型分析 +由于這是運行時開銷,因此計劃使用 Erg 的類型系統對 Python 腳本進行靜態類型分析

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/33_package_system.md b/doc/zh_TW/syntax/33_package_system.md index a2a817fd..db6a9367 100644 --- a/doc/zh_TW/syntax/33_package_system.md +++ b/doc/zh_TW/syntax/33_package_system.md @@ -1,15 +1,15 @@ -# 打包系统 +# 打包系統 -Erg包大致可以分为app包,即应用程序,以及lib包,即库。 -应用包的入口点是`src/app.er`。 `app.er` 中定义的`main` 函数被执行。 -lib 包的入口点是`src/lib.er`。导入包相当于导入 `lib.er`。 +Erg包大致可以分為app包,即應用程序,以及lib包,即庫。 +應用包的入口點是`src/app.er`。 `app.er` 中定義的`main` 函數被執行。 +lib 包的入口點是`src/lib.er`。導入包相當于導入 `lib.er`。 -一个包有一个称为模块的子结构,在 Erg 中是一个 Erg 文件或由 Erg 文件组成的目录。外部 Erg 文件/目录是作为模块对象的可操作对象。 +一個包有一個稱為模塊的子結構,在 Erg 中是一個 Erg 文件或由 Erg 文件組成的目錄。外部 Erg 文件/目錄是作為模塊對象的可操作對象。 -为了将目录识别为模块,有必要在目录中放置一个“(目录名称).er”文件。 -这类似于 Python 的 `__init__.py`,但与 `__init__.py` 不同的是,它放在目录之外。 +為了將目錄識別為模塊,有必要在目錄中放置一個“(目錄名稱).er”文件。 +這類似于 Python 的 `__init__.py`,但與 `__init__.py` 不同的是,它放在目錄之外。 -例如,考虑以下目录结构。 +例如,考慮以下目錄結構。 ```console └─┬ ./src @@ -21,9 +21,9 @@ lib 包的入口点是`src/lib.er`。导入包相当于导入 `lib.er`。 └─ qux.er ``` -您可以在 `app.er` 中导入 `foo` 和 `bar` 模块。由于 `bar.er` 文件,`bar` 目录可以被识别为一个模块。 -`foo` 模块是由文件组成的模块,`bar` 模块是由目录组成的模块。 `bar` 模块还包含 `baz` 和 `qux` 模块。 -该模块只是 `bar` 模块的一个属性,可以从 `app.er` 访问,如下所示。 +您可以在 `app.er` 中導入 `foo` 和 `bar` 模塊。由于 `bar.er` 文件,`bar` 目錄可以被識別為一個模塊。 +`foo` 模塊是由文件組成的模塊,`bar` 模塊是由目錄組成的模塊。 `bar` 模塊還包含 `baz` 和 `qux` 模塊。 +該模塊只是 `bar` 模塊的一個屬性,可以從 `app.er` 訪問,如下所示。 ```python # app.er @@ -36,9 +36,9 @@ main args = ... ``` -请注意用于访问子模块的 `/` 分隔符。 这是因为可以有诸如 `bar.baz.er` 之类的文件名。 -不鼓励使用此类文件名,因为 `.er` 前缀在 Erg 中是有意义的。 -例如,用于测试的模块。 以 `.test.er` 结尾的文件是一个(白盒)测试模块,它在运行测试时执行一个用 `@Test` 修饰的子例程。 +請注意用于訪問子模塊的 `/` 分隔符。 這是因為可以有諸如 `bar.baz.er` 之類的文件名。 +不鼓勵使用此類文件名,因為 `.er` 前綴在 Erg 中是有意義的。 +例如,用于測試的模塊。 以 `.test.er` 結尾的文件是一個(白盒)測試模塊,它在運行測試時執行一個用 `@Test` 修飾的子例程。 ```console └─┬ ./src @@ -55,7 +55,7 @@ main args = ... ``` -此外,以 .private.er 结尾的文件是私有模块,只能由同一目录中的模块访问。 +此外,以 .private.er 結尾的文件是私有模塊,只能由同一目錄中的模塊訪問。 ```console └─┬ @@ -79,5 +79,5 @@ baz = import "baz" ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/34_generator.md b/doc/zh_TW/syntax/34_generator.md index 8d260ba1..34c3fceb 100644 --- a/doc/zh_TW/syntax/34_generator.md +++ b/doc/zh_TW/syntax/34_generator.md @@ -1,6 +1,6 @@ # 生成器 -生成器是在块中使用 `yield!` 过程的特殊过程。 +生成器是在塊中使用 `yield!` 過程的特殊過程。 ```python g!() = @@ -9,8 +9,8 @@ g!() = yield! 3 ``` -`yield!` 是在调用`self!.yield!` 的子程序块中定义的过程。 和`return`一样,它把传递给它的值作为返回值返回,但它具有保存block当前执行状态,再次调用时从头开始执行的特性。 -生成器既是过程又是迭代器; Python 生成器是一个创建迭代器的函数,而 Erg 直接迭代。 过程本身通常不是可变对象(没有`!`),但生成器是可变对象,因为它自己的内容可以随着每次执行而改变。 +`yield!` 是在調用`self!.yield!` 的子程序塊中定義的過程。 和`return`一樣,它把傳遞給它的值作為返回值返回,但它具有保存block當前執行狀態,再次調用時從頭開始執行的特性。 +生成器既是過程又是迭代器; Python 生成器是一個創建迭代器的函數,而 Erg 直接迭代。 過程本身通常不是可變對象(沒有`!`),但生成器是可變對象,因為它自己的內容可以隨著每次執行而改變。 ```python # Generator! @@ -20,7 +20,7 @@ assert g!() == 2 assert g!() == 3 ``` -Python 风格的生成器可以定义如下。 +Python 風格的生成器可以定義如下。 ```python make_g() = () => @@ -31,5 +31,5 @@ make_g: () => Generator! ```

- 上一页 | Next + 上一頁 | Next

diff --git a/doc/zh_TW/syntax/SUMMARY.md b/doc/zh_TW/syntax/SUMMARY.md index f9486625..55ad61ad 100644 --- a/doc/zh_TW/syntax/SUMMARY.md +++ b/doc/zh_TW/syntax/SUMMARY.md @@ -1,69 +1,69 @@ # 概括 -- [基础](./00_basic.md) +- [基礎](./00_basic.md) - [文字](./01_literal.md) -- [名称](02_name.md) -- [声明](./03_declaration.md) -- [函数](./04_function.md) -- [内置函数](./05_builtin_funcs.md) -- [操作员](./06_operator.md) +- [名稱](02_name.md) +- [聲明](./03_declaration.md) +- [函數](./04_function.md) +- [內置函數](./05_builtin_funcs.md) +- [操作員](./06_operator.md) - [副作用](./07_side_effect.md) - [程序](./08_procedure.md) -- [内置程序](./09_builtin_procs.md) -- [数组](./10_array.md) -- [元组](./11_tuple.md) +- [內置程序](./09_builtin_procs.md) +- [數組](./10_array.md) +- [元組](./11_tuple.md) - [字典](./12_dict.md) -- [记录](./13_record.md) -- [设置](./14_set.md) -- [类型](./15_type.md) - - [类型系统](./type/01_type_system.md) - - [基础](./type/02_basic.md) - - [特质](./type/03_trait.md) - - [类](./type/04_class.md) - - [继承](./type/05_inheritance.md) - - [NST 与 SST](./type/06_nst_vs_sst.md) - - [补丁](./type/07_patch.md) - - [值类型](./type/08_value.md) - - [属性类型](./type/09_attributive.md) - - [间隔类型](./type/10_interval.md) - - [枚举类型](./type/11_enum.md) - - [细化类型](./type/12_refinement.md) - - [代数类型](./type/13_algebraic.md) - - [依赖类型](./type/14_dependent.md) - - [量化类型](./type/15_quantified.md) - - [子类型](./type/16_subtyping.md) - - [类型转换](./type/17_type_casting.md) - - [可变类型](./type/18_mut.md) - - [高级](./type/advanced.md) - - [默认参数](./type/advanced/default_param.md) - - [类型擦除](./type/advanced/erasure.md) +- [記錄](./13_record.md) +- [設置](./14_set.md) +- [類型](./15_type.md) + - [類型系統](./type/01_type_system.md) + - [基礎](./type/02_basic.md) + - [特質](./type/03_trait.md) + - [類](./type/04_class.md) + - [繼承](./type/05_inheritance.md) + - [NST 與 SST](./type/06_nst_vs_sst.md) + - [補丁](./type/07_patch.md) + - [值類型](./type/08_value.md) + - [屬性類型](./type/09_attributive.md) + - [間隔類型](./type/10_interval.md) + - [枚舉類型](./type/11_enum.md) + - [細化類型](./type/12_refinement.md) + - [代數類型](./type/13_algebraic.md) + - [依賴類型](./type/14_dependent.md) + - [量化類型](./type/15_quantified.md) + - [子類型](./type/16_subtyping.md) + - [類型轉換](./type/17_type_casting.md) + - [可變類型](./type/18_mut.md) + - [高級](./type/advanced.md) + - [默認參數](./type/advanced/default_param.md) + - [類型擦除](./type/advanced/erasure.md) - [存在](./type/advanced/existential.md) - [GADTs](./type/advanced/GADTs.md) - - [关键字参数](./type/advanced/keyword_param.md) - - [种类](./type/advanced/kind.md) - - [标记特征](./type/advanced/marker_trait.md) - - [可变结构](./type/advanced/mut_struct.md) - - [幻象类型](./type/advanced/phantom.md) - - [投影类型](./type/advanced/projection.md) - - [量化依赖类型](./type/advanced/quantified_dependent.md) + - [關鍵字參數](./type/advanced/keyword_param.md) + - [種類](./type/advanced/kind.md) + - [標記特征](./type/advanced/marker_trait.md) + - [可變結構](./type/advanced/mut_struct.md) + - [幻象類型](./type/advanced/phantom.md) + - [投影類型](./type/advanced/projection.md) + - [量化依賴類型](./type/advanced/quantified_dependent.md) - [共享](./type/advanced/shared.md) - [迭代器](./16_iterator.md) -- [可变性](./17_mutability.md) -- [所有权](./18_ownership.md) -- [可见性](./19_visibility.md) -- [命名规则](20_naming_rule.md) +- [可變性](./17_mutability.md) +- [所有權](./18_ownership.md) +- [可見性](./19_visibility.md) +- [命名規則](20_naming_rule.md) - [Lambda](./21_lambda.md) - [子程序](./22_subroutine.md) -- [关闭](./23_closure.md) -- [模块](./24_module.md) -- [对象系统](./25_object_system.md) +- [關閉](./23_closure.md) +- [模塊](./24_module.md) +- [對象系統](./25_object_system.md) - [模式匹配](./26_pattern_matching.md) - [理解](./27_comprehension.md) -- [扩展语法](./28_spread_syntax.md) -- [装饰器](./29_decorator.md) -- [错误处理](./30_error_handling.md) +- [擴展語法](./28_spread_syntax.md) +- [裝飾器](./29_decorator.md) +- [錯誤處理](./30_error_handling.md) - [管道](./31_pipeline.md) -- [与 Python 集成](./32_integration_with_python.md) -- [包系统](./33_package_system.md) -- [发电机](./34_generator.md) +- [與 Python 集成](./32_integration_with_python.md) +- [包系統](./33_package_system.md) +- [發電機](./34_generator.md) - [索引](./indexes.md) \ No newline at end of file diff --git a/doc/zh_TW/syntax/container_ownership.md b/doc/zh_TW/syntax/container_ownership.md index 09bbfb3c..283eb5d3 100644 --- a/doc/zh_TW/syntax/container_ownership.md +++ b/doc/zh_TW/syntax/container_ownership.md @@ -1,4 +1,4 @@ -# 下标(索引访问) +# 下標(索引訪問) `[]` 不同于普通的方法。 @@ -9,19 +9,19 @@ assert a == [2, 2] ``` 回想一下,子例程的返回值不能是引用。 -这里的 `a[0]` 的类型显然应该是 `Ref!(Int!)`(`a[0]` 的类型取决于上下文)。 -所以 `[]` 实际上是特殊语法的一部分,就像 `.` 一样。 与 Python 不同,它不能被重载。 -也无法在方法中重现 `[]` 的行为。 +這里的 `a[0]` 的類型顯然應該是 `Ref!(Int!)`(`a[0]` 的類型取決于上下文)。 +所以 `[]` 實際上是特殊語法的一部分,就像 `.` 一樣。 與 Python 不同,它不能被重載。 +也無法在方法中重現 `[]` 的行為。 ```python C = Class {i = Int!} C. get(ref self) = - self::i # 类型错误:`self::i` 是 `Int!`(需要所有权)但 `get` 不拥有 `self` + self::i # 類型錯誤:`self::i` 是 `Int!`(需要所有權)但 `get` 不擁有 `self` C.steal(self) = self::i #NG -C.new({i = 1}).steal().inc!() # 所有权警告:`C.new({i = 1}).steal()` 不属于任何人 -# 提示:分配给变量或使用 `uwn_do!` +C.new({i = 1}).steal().inc!() # 所有權警告:`C.new({i = 1}).steal()` 不屬于任何人 +# 提示:分配給變量或使用 `uwn_do!` # OK (分配) c = C.new({i = 1}) i = c.steal() @@ -31,12 +31,12 @@ assert i == 2 own_do! C.new({i = 1}).steal(), i => i.inc!() ``` -此外,`[]` 可以不承认,但元素不会移动 +此外,`[]` 可以不承認,但元素不會移動 ```python a = [!1, !2] i = a[0] i.inc!() assert a[1] == 2 -a[0] # 所有权错误:`a[0]` 被移动到 `i` +a[0] # 所有權錯誤:`a[0]` 被移動到 `i` ``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/grammar.md b/doc/zh_TW/syntax/grammar.md index 8e4e8a06..27a9388d 100644 --- a/doc/zh_TW/syntax/grammar.md +++ b/doc/zh_TW/syntax/grammar.md @@ -1,4 +1,4 @@ -# Erg 的语法(版本 0.1.0, 临时) +# Erg 的語法(版本 0.1.0, 臨時) ``` special_op ::= '=' | '->' | '=>' | '.' | ',' | ':' | '::' | '|>' | '&' separator ::= ';' | '\n' diff --git a/doc/zh_TW/syntax/indexes.md b/doc/zh_TW/syntax/indexes.md index b60d9945..1ff34807 100644 --- a/doc/zh_TW/syntax/indexes.md +++ b/doc/zh_TW/syntax/indexes.md @@ -1,12 +1,12 @@ -# 指数 +# 指數 -有关不在此索引中的 API,请参阅 [此处](../API/index.md)。 -有关术语,请参见 [此处](../dev_guide/terms.md)。 +有關不在此索引中的 API,請參閱 [此處](../API/index.md)。 +有關術語,請參見 [此處](../dev_guide/terms.md)。 -## 符号 +## 符號 * ! - * !-type → [可变性](./type/mut.md) + * !-type → [可變性](./type/mut.md) * [#](./00_basic.md/#comment) * $ * % @@ -24,10 +24,10 @@ * −_ → − (前置) * − (中置) * −> -* . → [可见性] +* . → [可見性] * / * : - * :: → [可见性] + * :: → [可見性] * ; * < * <: diff --git a/doc/zh_TW/syntax/quick_tour.md b/doc/zh_TW/syntax/quick_tour.md index e891c70f..e91bef22 100644 --- a/doc/zh_TW/syntax/quick_tour.md +++ b/doc/zh_TW/syntax/quick_tour.md @@ -1,14 +1,14 @@ -# 快速浏览 +# 快速瀏覽 -`syntax` 下面的文档是为了让编程初学者也能理解而编写的。 -对于已经掌握 Python、Rust、Haskell 等语言的人来说,可能有点啰嗦。 +`syntax` 下面的文檔是為了讓編程初學者也能理解而編寫的。 +對于已經掌握 Python、Rust、Haskell 等語言的人來說,可能有點啰嗦。 -所以,这里是 Erg 语法的概述。 -请认为未提及的部分与 Python 相同。 +所以,這里是 Erg 語法的概述。 +請認為未提及的部分與 Python 相同。 -## 变量,常量 +## 變量,常量 -变量用 `=` 定义。 与 Haskell 一样,变量一旦定义就不能更改。 但是,它可以在另一个范围内被遮蔽。 +變量用 `=` 定義。 與 Haskell 一樣,變量一旦定義就不能更改。 但是,它可以在另一個范圍內被遮蔽。 ```python i = 0 @@ -17,8 +17,8 @@ if True: assert i == 0 ``` -任何以大写字母开头的都是常数。 只有可以在编译时计算的东西才能是常量。 -此外,自定义以来,常量在所有范围内都是相同的。 +任何以大寫字母開頭的都是常數。 只有可以在編譯時計算的東西才能是常量。 +此外,自定義以來,常量在所有范圍內都是相同的。 ```python PI = 3.141592653589793 @@ -27,19 +27,19 @@ match random.random!(0..10): log "You get PI, it's a miracle!" ``` -## 类型声明 +## 類型聲明 -与 Python 不同的是,只能先声明变量类型。 -当然,声明的类型和实际分配的对象的类型必须兼容。 +與 Python 不同的是,只能先聲明變量類型。 +當然,聲明的類型和實際分配的對象的類型必須兼容。 ```python i: Int i = 10 ``` -## 函数 +## 函數 -你可以像在 Haskell 中一样定义它。 +你可以像在 Haskell 中一樣定義它。 ```python fib0 = 0 @@ -47,20 +47,20 @@ fib1 = 1 fibn = fib(n - 1) + fib(n - 2) ``` -匿名函数可以这样定义: +匿名函數可以這樣定義: ```python i -> i + 1 assert [1, 2, 3].map(i -> i + 1).to_arr() == [2, 3, 4] ``` -## 运算符 +## 運算符 -特定于 Erg 的运算符是: +特定于 Erg 的運算符是: -### 变异运算符 (!) +### 變異運算符 (!) -这就像 Ocaml 中的`ref`。 +這就像 Ocaml 中的`ref`。 ```python i = !0 @@ -70,13 +70,13 @@ assert i == 1 ## 程序 -具有副作用的子例程称为过程,并标有`!`。 +具有副作用的子例程稱為過程,并標有`!`。 ```python print! 1 # 1 ``` -## 泛型函数(多相关) +## 泛型函數(多相關) ```python id|T|(x: T): T = x @@ -84,30 +84,30 @@ id(1): Int id("a"): Str ``` -## 记录 +## 記錄 -您可以使用类似 ML 的语言中的记录等价物(或 JS 中的对象字面量)。 +您可以使用類似 ML 的語言中的記錄等價物(或 JS 中的對象字面量)。 ```python p = {x = 1; y = 2} ``` -## 所有权 +## 所有權 -Ergs 由可变对象(使用 `!` 运算符突变的对象)拥有,并且不能从多个位置重写。 +Ergs 由可變對象(使用 `!` 運算符突變的對象)擁有,并且不能從多個位置重寫。 ```python i = !0 j = i assert j == 0 -i#移动错误 +i#移動錯誤 ``` -另一方面,不可变对象可以从多个位置引用。 +另一方面,不可變對象可以從多個位置引用。 -## 可见性 +## 可見性 -使用 `.` 前缀变量使其成为公共变量并允许从外部模块引用它。 +使用 `.` 前綴變量使其成為公共變量并允許從外部模塊引用它。 ```python # foo.er @@ -118,19 +118,19 @@ y = 1 ```python foo = import "foo" assert foo.x == 1 -foo.y # 可见性错误 +foo.y # 可見性錯誤 ``` ## 模式匹配 -### 变量模式 +### 變量模式 ```python -# 基本任务 +# 基本任務 i = 1 -# with 类型 +# with 類型 i: Int = 1 -# 函数 +# 函數 fn x = x + 1 fn: Int -> Int = x -> x + 1 ``` @@ -138,15 +138,15 @@ fn: Int -> Int = x -> x + 1 ### 文字模式 ```python -# 如果 `i` 在编译时无法确定为 1,则发生 类型错误 -# 简写:`_ {1} = i` +# 如果 `i` 在編譯時無法確定為 1,則發生 類型錯誤 +# 簡寫:`_ {1} = i` 1 = i -# 简单的模式匹配 +# 簡單的模式匹配 match x: 1 -> "1" 2 -> "2" _ -> "other" -# 斐波那契函数 +# 斐波那契函數 fib0 = 0 fib1 = 1 fibn: Nat = fibn-1 + fibn-2 @@ -164,7 +164,7 @@ name = match num: _ -> "unnamed" ``` -### 丢弃(通配符)模式 +### 丟棄(通配符)模式 ```python _ = 1 @@ -172,9 +172,9 @@ _: Int = 1 right(_, r) = r ``` -### 可变长度模式 +### 可變長度模式 -与稍后描述的元组/数组/记录模式结合使用。 +與稍后描述的元組/數組/記錄模式結合使用。 ```python [i,...j] = [1, 2, 3, 4] @@ -183,27 +183,27 @@ first|T|(fst: T, ...rest: T) = fst assert first(1, 2, 3) == 1 ``` -### 元组模式 +### 元組模式 ```python (i, j) = (1, 2) ((k, l), _) = ((1, 2), (3, 4)) -# 如果不嵌套,() 可以省略(1, 2 被视为(1, 2)) +# 如果不嵌套,() 可以省略(1, 2 被視為(1, 2)) m, n = 1, 2 ``` -### 数组模式 +### 數組模式 ```python length[] = 0 length[_, ...rest] = 1 + lengthrest ``` -#### 记录模式 +#### 記錄模式 ```python {sin; cos; tan; ...} = import "math" -{*} = import "math" # 全部导入 +{*} = import "math" # 全部導入 person = {name = "John Smith"; age = 20} age = match person: @@ -211,7 +211,7 @@ age = match person: {_; age} -> age ``` -### 数据类模式 +### 數據類模式 ```python Point = Inherit {x = Int; y = Int} @@ -225,14 +225,14 @@ Point::{x; y} = p odds = [i | i <- 1..100; i % 2 == 0] ``` -## 班级 +## 班級 -Erg 不支持多级/多级继承。 +Erg 不支持多級/多級繼承。 -## 特质 +## 特質 -它们类似于 Rust 特征,但在更字面意义上,允许组合和解耦,并将属性和方法视为平等。 -此外,它不涉及实施。 +它們類似于 Rust 特征,但在更字面意義上,允許組合和解耦,并將屬性和方法視為平等。 +此外,它不涉及實施。 ```python XY = Trait {x = Int; y = Int} @@ -246,19 +246,19 @@ Point. ... ``` -## 修补 +## 修補 -您可以为类和特征提供实现。 +您可以為類和特征提供實現。 -## 筛子类型 +## 篩子類型 -谓词表达式可以是类型限制的。 +謂詞表達式可以是類型限制的。 ```python Nat = {I: Int | I >= 0} ``` -## 带值的参数类型(依赖类型) +## 帶值的參數類型(依賴類型) ```python a: [Int; 3] diff --git a/doc/zh_TW/syntax/type/01_type_system.md b/doc/zh_TW/syntax/type/01_type_system.md index 7ed2b019..9dabb102 100644 --- a/doc/zh_TW/syntax/type/01_type_system.md +++ b/doc/zh_TW/syntax/type/01_type_system.md @@ -1,68 +1,68 @@ -# Erg 的类型系统 +# Erg 的類型系統 -下面简单介绍一下 Erg 的类型系统。 详细信息在其他部分进行说明。 +下面簡單介紹一下 Erg 的類型系統。 詳細信息在其他部分進行說明。 -## 如何定义 +## 如何定義 -Erg 的独特功能之一是(普通)变量、函数(子例程)和类型(Kind)定义之间的语法没有太大区别。 所有都是根据普通变量和函数定义的语法定义的。 +Erg 的獨特功能之一是(普通)變量、函數(子例程)和類型(Kind)定義之間的語法沒有太大區別。 所有都是根據普通變量和函數定義的語法定義的。 ```python f i: Int = i + 1 -f # <函数 f> +f # <函數 f> f(1) # 2 -f.method self = ... # 语法错误:无法为子例程定义方法 +f.method self = ... # 語法錯誤:無法為子例程定義方法 T I: Int = {...} T # -T(1) # 类型 T(1) +T(1) # 類型 T(1) T.method self = ... D = Class {private = Int; .public = Int} -D # <类 'D'> -o1 = {private = 1; .public = 2} # o1 是一个不属于任何类的对象 -o2 = D.new {private = 1; .public = 2} # o2 是 D 的一个实例 -o2 = D.new {.public = 2} # 初始化错误:类 'D' 需要属性 'private'(: Int) 但未定义 +D # <類 'D'> +o1 = {private = 1; .public = 2} # o1 是一個不屬于任何類的對象 +o2 = D.new {private = 1; .public = 2} # o2 是 D 的一個實例 +o2 = D.new {.public = 2} # 初始化錯誤:類 'D' 需要屬性 'private'(: Int) 但未定義 ``` ## Classification -Erg 中的所有对象都是强类型的。 -顶层类型是`{=}`,实现了`__repr__`、`__hash__`、`clone`等(不是必须的方法,这些属性不能被覆盖)。 -Erg 的类型系统包含结构子类型 (SST)。 该系统类型化的类型称为结构类型。 -结构类型主要分为三种:Attributive(属性类型)、Refinement(细化类型)和Algebraic(代数类型)。 +Erg 中的所有對象都是強類型的。 +頂層類型是`{=}`,實現了`__repr__`、`__hash__`、`clone`等(不是必須的方法,這些屬性不能被覆蓋)。 +Erg 的類型系統包含結構子類型 (SST)。 該系統類型化的類型稱為結構類型。 +結構類型主要分為三種:Attributive(屬性類型)、Refinement(細化類型)和Algebraic(代數類型)。 | | Record | Enum | Interval | Union | Intersection | Diff | | --------- | ----------- | ---------- | -------------- | ----------- | ------------ | ------------ | | kind | Attributive | Refinement | Refinement | Algebraic | Algebraic | Algebraic | | generator | record | set | range operator | or operator | and operator | not operator | -也可以使用名义子类型(NST),将 SST 类型转换为 NST 类型称为类型的名义化。 结果类型称为名义类型。 -在 Erg 中,名义类型是类和特征。 当我们简单地说类/特征时,我们通常指的是记录类/特征。 +也可以使用名義子類型(NST),將 SST 類型轉換為 NST 類型稱為類型的名義化。 結果類型稱為名義類型。 +在 Erg 中,名義類型是類和特征。 當我們簡單地說類/特征時,我們通常指的是記錄類/特征。 | | Type | Abstraction | Subtyping procedure | | --- | -------------- | ---------------- | ------------------- | | NST | NominalType | Trait | Inheritance | | SST | StructuralType | Structural Trait | (Implicit) | -整个名义类型的类型(`NominalType`)和整个结构类型的类型(`StructuralType`)是整个类型(`Type`)的类型的子类型。 +整個名義類型的類型(`NominalType`)和整個結構類型的類型(`StructuralType`)是整個類型(`Type`)的類型的子類型。 -Erg 可以将参数(类型参数)传递给类型定义。带有类型参数的 `Option`、`Array` 等称为多项式类型。这些本身不是类型,但它们通过应用参数成为类型。诸如 `Int`、`Str` 等没有参数的类型称为简单类型(标量类型)。 +Erg 可以將參數(類型參數)傳遞給類型定義。帶有類型參數的 `Option`、`Array` 等稱為多項式類型。這些本身不是類型,但它們通過應用參數成為類型。諸如 `Int`、`Str` 等沒有參數的類型稱為簡單類型(標量類型)。 -一个类型可以看成一个集合,并且存在包含关系。例如,“Num”包含“Add”、“Sub”等,“Int”包含“Nat”。 -所有类的上类是`Object == Class {:}`,所有类型的下类是`Never == Class {}`。这在下面描述。 +一個類型可以看成一個集合,并且存在包含關系。例如,“Num”包含“Add”、“Sub”等,“Int”包含“Nat”。 +所有類的上類是`Object == Class {:}`,所有類型的下類是`Never == Class {}`。這在下面描述。 -## 类型 +## 類型 -像 `Array T` 这样的类型可以看作是 `Type -> Type` 类型的函数,它以 `T` 类型为参数并返回 `Array T` 类型(在类型论中也称为 Kind)。像 `Array T` 这样的类型专门称为多态类型,而 `Array` 本身称为一元 Kind。 +像 `Array T` 這樣的類型可以看作是 `Type -> Type` 類型的函數,它以 `T` 類型為參數并返回 `Array T` 類型(在類型論中也稱為 Kind)。像 `Array T` 這樣的類型專門稱為多態類型,而 `Array` 本身稱為一元 Kind。 -已知参数和返回类型的函数的类型表示为`(T, U) -> V`。如果要指定同一类型的整个双参数函数,可以使用 `|T| (T, T) -> T`,如果要指定整个 N 参数函数,可以使用 `Func N`。但是,`Func N` 类型没有关于参数数量或其类型的信息,因此所有返回值在调用时都是`Obj` 类型。 +已知參數和返回類型的函數的類型表示為`(T, U) -> V`。如果要指定同一類型的整個雙參數函數,可以使用 `|T| (T, T) -> T`,如果要指定整個 N 參數函數,可以使用 `Func N`。但是,`Func N` 類型沒有關于參數數量或其類型的信息,因此所有返回值在調用時都是`Obj` 類型。 -`Proc` 类型表示为 `() => Int` 等等。此外,`Proc` 类型实例的名称必须以 `!` 结尾。 +`Proc` 類型表示為 `() => Int` 等等。此外,`Proc` 類型實例的名稱必須以 `!` 結尾。 -`Method` 类型是一个函数/过程,其第一个参数是它所属的对象 `self`(通过引用)。对于依赖类型,也可以在应用方法后指定自己的类型。这是 `T!(!N)` 类型和 `T!(N ~> N-1)。 () => Int` 等等。 +`Method` 類型是一個函數/過程,其第一個參數是它所屬的對象 `self`(通過引用)。對于依賴類型,也可以在應用方法后指定自己的類型。這是 `T!(!N)` 類型和 `T!(N ~> N-1)。 () => Int` 等等。 -Erg 的数组(Array)就是 Python 所说的列表。 `[诠释; 3]`是一个数组类,包含三个`Int`类型的对象。 +Erg 的數組(Array)就是 Python 所說的列表。 `[詮釋; 3]`是一個數組類,包含三個`Int`類型的對象。 -> __Note__: `(Type; N)` 既是类型又是值,所以可以这样使用。 +> __Note__: `(Type; N)` 既是類型又是值,所以可以這樣使用。 > > ```python. > Types = (Int, Str, Bool) @@ -83,37 +83,37 @@ lpop|T, N|(l: [T; N]): (T, [T; N-1]) = (first, l) ``` -以 `!` 结尾的类型可以重写内部结构。 例如,`[T; !N]` 类是一个动态数组。 -要从“T”类型的对象创建“T!”类型的对象,请使用一元运算符“!”。 +以 `!` 結尾的類型可以重寫內部結構。 例如,`[T; !N]` 類是一個動態數組。 +要從“T”類型的對象創建“T!”類型的對象,請使用一元運算符“!”。 ```python i: Int! = !1 i.update! i -> i + 1 assert i == 2 arr = [1, 2, 3] -arr.push! 4 # 导入错误 +arr.push! 4 # 導入錯誤 mut_arr = [1, 2, 3].into [Int; !3] mut_arr.push4 assert mut_arr == [1, 2, 3, 4]. ``` -## 类型定义 +## 類型定義 -类型定义如下。 +類型定義如下。 ```python Point2D = {.x = Int; .y = Int} ``` -请注意,如果从变量中省略 `.`,它将成为类型中使用的私有变量。 但是,这也是必需的属性。 -由于类型也是对象,因此类型本身也有属性。 这样的属性称为类型属性。 在类的情况下,它们也称为类属性。 +請注意,如果從變量中省略 `.`,它將成為類型中使用的私有變量。 但是,這也是必需的屬性。 +由于類型也是對象,因此類型本身也有屬性。 這樣的屬性稱為類型屬性。 在類的情況下,它們也稱為類屬性。 -## 数据类型 +## 數據類型 -如前所述,Erg 中的“类型”大致表示一组对象。 +如前所述,Erg 中的“類型”大致表示一組對象。 -下面是 `Add` 类型的定义,需要 `+`(中间运算符)。 `R, O` 是所谓的类型参数,可以是真正的类型(类),例如 `Int` 或 `Str`。 在其他语言中,类型参数被赋予特殊的符号(泛型、模板等),但在 Erg 中,它们可以像普通参数一样定义。 -类型参数也可以用于类型对象以外的类型。 例如数组类型`[Int; 3]` 是 `Array Int, 3` 的语法糖。 如果类型实现重叠,用户必须明确选择一个。 +下面是 `Add` 類型的定義,需要 `+`(中間運算符)。 `R, O` 是所謂的類型參數,可以是真正的類型(類),例如 `Int` 或 `Str`。 在其他語言中,類型參數被賦予特殊的符號(泛型、模板等),但在 Erg 中,它們可以像普通參數一樣定義。 +類型參數也可以用于類型對象以外的類型。 例如數組類型`[Int; 3]` 是 `Array Int, 3` 的語法糖。 如果類型實現重疊,用戶必須明確選擇一個。 ```python Add R = Trait { @@ -122,7 +122,7 @@ Add R = Trait { } ``` -.`_+_`是Add.`_+_`的缩写。 前缀运算符 .`+_` 是 `Num` 类型的方法。 +.`_+_`是Add.`_+_`的縮寫。 前綴運算符 .`+_` 是 `Num` 類型的方法。 ```python Num = Add and Sub and Mul and Eq @@ -132,7 +132,7 @@ NumImpl. ... ``` -多态类型可以像函数一样对待。 通过将它们指定为 `Mul Int、Str` 等,它们可以是单态的(在许多情况下,它们是用实际参数推断出来的,而没有指定它们)。 +多態類型可以像函數一樣對待。 通過將它們指定為 `Mul Int、Str` 等,它們可以是單態的(在許多情況下,它們是用實際參數推斷出來的,而沒有指定它們)。 ```python 1 + 1 @@ -141,38 +141,38 @@ Nat.`_+_` 1, 1 Int.`_+_` 1, 1 ``` -前四行返回相同的结果(准确地说,底部的返回 `Int`),但通常使用顶部的。 -`Ratio.`_+_`(1, 1)` 将返回 `2.0` 而不会出错。 -这是因为 `Int <: Ratio`,所以 `1` 向下转换为 `Ratio`。 -但这不是演员。 +前四行返回相同的結果(準確地說,底部的返回 `Int`),但通常使用頂部的。 +`Ratio.`_+_`(1, 1)` 將返回 `2.0` 而不會出錯。 +這是因為 `Int <: Ratio`,所以 `1` 向下轉換為 `Ratio`。 +但這不是演員。 ```python i = 1 -if i: # 类型错误:i:Int 不能转换为 Bool,请改用 Int.is_zero()。 +if i: # 類型錯誤:i:Int 不能轉換為 Bool,請改用 Int.is_zero()。 log "a" log "b" ``` -这是因为 `Bool <: Int` (`True == 1`, `False == 0`)。转换为子类型通常需要验证。 +這是因為 `Bool <: Int` (`True == 1`, `False == 0`)。轉換為子類型通常需要驗證。 -## 类型推理系统 +## 類型推理系統 -Erg 使用静态鸭子类型,因此几乎不需要显式指定类型。 +Erg 使用靜態鴨子類型,因此幾乎不需要顯式指定類型。 ```python f x, y = x + y ``` -在上面的代码中,带有 `+` 的类型,即 `Add` 是自动推断的; Erg 首先推断出最小的类型。如果`f 0, 1`,它将推断`f x:{0},y:{1}`,如果`n:Nat; f n, 1`,它会推断`f x: Nat, y: {1}`。最小化之后,增加类型直到找到实现。在 `{0}, {1}` 的情况下,`Nat` 与 `Nat` 是单态的,因为 `Nat` 是具有 `+` 实现的最小类型。 -如果是 `{0}, {-1}`,它与 `Int` 是单态的,因为它不匹配 `Nat`。如果子类型和超类型之间没有关系,则首先尝试具有最低浓度(实例数)(或者在多态类型的情况下参数更少)的那个。 -`{0}` 和 `{1}` 是枚举类型,它们是部分类型,例如 `Int` 和 `Nat`。 -例如,可以为枚举类型指定名称和请求/实现方法。在有权访问该类型的命名空间中,满足请求的对象可以使用实现方法。 +在上面的代碼中,帶有 `+` 的類型,即 `Add` 是自動推斷的; Erg 首先推斷出最小的類型。如果`f 0, 1`,它將推斷`f x:{0},y:{1}`,如果`n:Nat; f n, 1`,它會推斷`f x: Nat, y: {1}`。最小化之后,增加類型直到找到實現。在 `{0}, {1}` 的情況下,`Nat` 與 `Nat` 是單態的,因為 `Nat` 是具有 `+` 實現的最小類型。 +如果是 `{0}, {-1}`,它與 `Int` 是單態的,因為它不匹配 `Nat`。如果子類型和超類型之間沒有關系,則首先嘗試具有最低濃度(實例數)(或者在多態類型的情況下參數更少)的那個。 +`{0}` 和 `{1}` 是枚舉類型,它們是部分類型,例如 `Int` 和 `Nat`。 +例如,可以為枚舉類型指定名稱和請求/實現方法。在有權訪問該類型的命名空間中,滿足請求的對象可以使用實現方法。 ```python Binary = Patch {0, 1} Binary. - # self 包含一个实例。 在此示例中,为 0 或 1。 - # 如果你想重写self,你必须追加! 必须添加到类型名称和方法名称。 + # self 包含一個實例。 在此示例中,為 0 或 1。 + # 如果你想重寫self,你必須追加! 必須添加到類型名稱和方法名稱。 is_zero(self) = match self: 0 -> True 1 -> False # 你也可以使用 _ -> False @@ -182,8 +182,8 @@ Binary. 1 -> True ``` -此后,代码“0.to_bool()”是可能的(尽管“0 as Bool == False”是内置定义的)。 -这是一个实际上可以重写 `self` 的类型的示例,如代码所示。 +此后,代碼“0.to_bool()”是可能的(盡管“0 as Bool == False”是內置定義的)。 +這是一個實際上可以重寫 `self` 的類型的示例,如代碼所示。 ```python Binary! = Patch {0, 1}! @@ -197,32 +197,32 @@ b.switch!() print! b # => 0 ``` -## 结构类型(匿名类型) +## 結構類型(匿名類型) ```python Binary = {0, 1} ``` -上面代码中的 `Binary` 是一个类型,其元素是 `0` 和 `1`。 它也是 `Int` 类型的子类型,它同时具有 `0` 和 `1`。 -像 `{}` 这样的对象本身就是一种类型,可以在分配或不分配给上述变量的情况下使用。 -这样的类型称为结构类型。 当我们想强调它作为后者而不是类(命名类型)的用途时,它也被称为未命名类型。 `{0, 1}`这样的结构类型称为枚举类型,还有区间类型、记录类型等。 +上面代碼中的 `Binary` 是一個類型,其元素是 `0` 和 `1`。 它也是 `Int` 類型的子類型,它同時具有 `0` 和 `1`。 +像 `{}` 這樣的對象本身就是一種類型,可以在分配或不分配給上述變量的情況下使用。 +這樣的類型稱為結構類型。 當我們想強調它作為后者而不是類(命名類型)的用途時,它也被稱為未命名類型。 `{0, 1}`這樣的結構類型稱為枚舉類型,還有區間類型、記錄類型等。 -### 类型标识 +### 類型標識 -无法指定以下内容。 例如,您不能指定 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int`。 +無法指定以下內容。 例如,您不能指定 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int` 和 `Int`。 例如,`Int`和`Str`都是`Add`,但是`Int`和`Str`不能相加。 ```python add l: Add, r: Add = - l + r # 类型错误: `_+_` 没有实现: |T, U <: Add| (T, U) -> <失败> + l + r # 類型錯誤: `_+_` 沒有實現: |T, U <: Add| (T, U) -> <失敗> ``` -此外,下面的类型 `A` 和 `B` 不被认为是同一类型。 但是,类型“O”被认为是匹配的 +此外,下面的類型 `A` 和 `B` 不被認為是同一類型。 但是,類型“O”被認為是匹配的 ```python ... |R1; R2; O; A <: Add(R1, O); B <: Add(R2, O)| ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/type/02_basic.md b/doc/zh_TW/syntax/type/02_basic.md index adca8428..addbf3a7 100644 --- a/doc/zh_TW/syntax/type/02_basic.md +++ b/doc/zh_TW/syntax/type/02_basic.md @@ -1,62 +1,62 @@ -# 类型的基本语法 +# 類型的基本語法 -## 类型规范 +## 類型規范 -在 Erg 中,可以在 `:` 之后指定变量的类型,如下所示。这可以与作业同时完成。 +在 Erg 中,可以在 `:` 之后指定變量的類型,如下所示。這可以與作業同時完成。 ```python -i: Int # 将变量 i 声明为 Int 类型 +i: Int # 將變量 i 聲明為 Int 類型 i: Int = 1 -j = 1 # 类型说明可以省略 +j = 1 # 類型說明可以省略 ``` -您还可以指定普通表达式的类型。 +您還可以指定普通表達式的類型。 ```python i = 1: Int f([1, "a"]: [Int or Str]) ``` -对于简单的变量赋值,大多数类型说明可以省略。 -在定义子例程和类型时,类型规范更有用。 +對于簡單的變量賦值,大多數類型說明可以省略。 +在定義子例程和類型時,類型規范更有用。 ```python -# 参数的类型规范 +# 參數的類型規范 f x, y: Array Int = ... T X, Y: Array Int = ... ``` -请注意,在上述情况下,`x, y` 都是 `Array Int`。 +請注意,在上述情況下,`x, y` 都是 `Array Int`。 ```python -# 大写变量的值必须是常量表达式 +# 大寫變量的值必須是常量表達式 f X: Int = X ``` -或者,如果你不需要关于类型参数的完整信息,你可以用 `_` 省略它 +或者,如果你不需要關于類型參數的完整信息,你可以用 `_` 省略它 ```python g v: [T; _] = ... ``` -但是请注意,类型规范中的 `_` 意味着 `Object`。 +但是請注意,類型規范中的 `_` 意味著 `Object`。 ```python -f x: _, y: Int = x + y # 类型错误:Object 和 Int 之间没有实现 + +f x: _, y: Int = x + y # 類型錯誤:Object 和 Int 之間沒有實現 + ``` -## 子类型规范 +## 子類型規范 -除了 `:`(类型声明运算符),Erg 还允许您使用 `<:`(部分类型声明运算符)来指定类型之间的关系。 -`<:` 的左边只能指定一个类。 使用 `Subtypeof` 或类似的运算符来比较结构类型。 +除了 `:`(類型聲明運算符),Erg 還允許您使用 `<:`(部分類型聲明運算符)來指定類型之間的關系。 +`<:` 的左邊只能指定一個類。 使用 `Subtypeof` 或類似的運算符來比較結構類型。 -这也经常在定义子例程或类型时使用,而不是简单地指定变量。 +這也經常在定義子例程或類型時使用,而不是簡單地指定變量。 ```python -# 参数的子类型规范 +# 參數的子類型規范 f X <: T = ... -# 所需属性的子类型规范(.Iterator 属性必须是 Iterator 类型的子类型) +# 所需屬性的子類型規范(.Iterator 屬性必須是 Iterator 類型的子類型) Iterable T = Trait { .Iterator = {Iterator} # {Iterator} == {I: Type | I <: Iterator} .iter = Self.() -> Self.Iterator T @@ -64,15 +64,15 @@ Iterable T = Trait { } ``` -也可以在定义类时使用子类型规范来静态检查该类是否是指定类型的子类型。 +也可以在定義類時使用子類型規范來靜態檢查該類是否是指定類型的子類型。 ```python -# C 类是 Show 的子类型 +# C 類是 Show 的子類型 C = Class Object, Impl := Show -C.show self = ... # 显示所需的属性。 +C.show self = ... # 顯示所需的屬性。 ``` -您也可以仅在特定情况下指定子类型 +您也可以僅在特定情況下指定子類型 ```python K T: Eq @@ -84,17 +84,17 @@ K(Int). show self = ... ``` -实现结构类型时建议使用子类型规范。 -这是因为,由于结构子类型的性质,拼写错误或类型规范错误在实现所需属性时不会导致错误 +實現結構類型時建議使用子類型規范。 +這是因為,由于結構子類型的性質,拼寫錯誤或類型規范錯誤在實現所需屬性時不會導致錯誤 ```python C = Class Object -C.shoe self = ... # Show 由于 Typo 没有实现(它被认为只是一种独特的方法) +C.shoe self = ... # Show 由于 Typo 沒有實現(它被認為只是一種獨特的方法) ``` -## 属性定义 +## 屬性定義 -只能在模块中为特征和类定义属性 +只能在模塊中為特征和類定義屬性 ```python C = Class() @@ -105,7 +105,7 @@ c = C.new() assert c.pub_attr == "this is public" ``` -定义批处理定义的语法称为批处理定义,其中在 `C.` 或 `C::` 之后添加换行符,并且定义在缩进下方组合在一起 +定義批處理定義的語法稱為批處理定義,其中在 `C.` 或 `C::` 之后添加換行符,并且定義在縮進下方組合在一起 ```python C = Class() @@ -113,7 +113,7 @@ C.pub1 = ... C.pub2 = ... C::priv1 = ... C::priv2 = ... -# 相当于 +# 相當于 C = Class() C. pub1 = ... @@ -123,9 +123,9 @@ C:: priv2 = ... ``` -## 别名 +## 別名 -类型可以有别名。 这允许缩短长类型,例如记录类型 +類型可以有別名。 這允許縮短長類型,例如記錄類型 ```python Id = Int @@ -134,28 +134,28 @@ IorS = Int or Str Vector = Array Int ``` -此外,当显示错误时,如果定义了复合类型(在上面的示例中,右侧类型不是第一个类型),编译器将为它们使用别名。 +此外,當顯示錯誤時,如果定義了復合類型(在上面的示例中,右側類型不是第一個類型),編譯器將為它們使用別名。 -但是,每个模块只允许一个相同类型的别名,多个别名将导致警告。 -这意味着应将具有不同用途的类型定义为单独的类型。 -目的还在于防止在已经具有别名的类型之上添加别名。 +但是,每個模塊只允許一個相同類型的別名,多個別名將導致警告。 +這意味著應將具有不同用途的類型定義為單獨的類型。 +目的還在于防止在已經具有別名的類型之上添加別名。 ```python Id = Int -UserId = Int # 类型警告:重复别名:Id 和 UserId +UserId = Int # 類型警告:重復別名:Id 和 UserId Ids = Array Id -Ints = Array Int # 类型警告:重复别名:Isd 和 Ints +Ints = Array Int # 類型警告:重復別名:Isd 和 Ints IorS = Int or Str IorSorB = IorS or Bool -IorSorB_ = Int or Str or Bool # 类型警告:重复别名:IorSorB 和 IorSorB_ +IorSorB_ = Int or Str or Bool # 類型警告:重復別名:IorSorB 和 IorSorB_ Point2D = {x = Int; y = Int} Point3D = {.... Point2D; z = Int} -Point = {x = Int; y = Int; z = Int} # 类型警告:重复别名:Point3D 和 Point +Point = {x = Int; y = Int; z = Int} # 類型警告:重復別名:Point3D 和 Point ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/type/03_trait.md b/doc/zh_TW/syntax/type/03_trait.md index 0fbca1ef..4059f479 100644 --- a/doc/zh_TW/syntax/type/03_trait.md +++ b/doc/zh_TW/syntax/type/03_trait.md @@ -1,16 +1,16 @@ -# 特质 +# 特質 -Trait 是一种名义类型,它将类型属性要求添加到记录类型。 -它类似于 Python 中的抽象基类 (ABC),但区别在于能够执行代数运算。 +Trait 是一種名義類型,它將類型屬性要求添加到記錄類型。 +它類似于 Python 中的抽象基類 (ABC),但區別在于能夠執行代數運算。 ```python Norm = Trait {.x = Int; .y = Int; .norm = Self.() -> Int} ``` -特质不区分属性和方法。 +特質不區分屬性和方法。 -注意,trait 只能声明,不能实现(实现是通过一个叫做 patching 的特性来实现的,后面会讨论)。 -可以通过指定部分类型来检查特征在类中的实现。 +注意,trait 只能聲明,不能實現(實現是通過一個叫做 patching 的特性來實現的,后面會討論)。 +可以通過指定部分類型來檢查特征在類中的實現。 ```python Point2D <: Norm @@ -21,11 +21,11 @@ Point2D.norm self = self.x**2 + self.y**2 Error if the required attributes are not implemented. ```python -Point2D <: Norm # 类型错误:Point2D 不是 Norm 的子类型 +Point2D <: Norm # 類型錯誤:Point2D 不是 Norm 的子類型 Point2D = Class {.x = Int; .y = Int} ``` -特征与结构类型一样,可以应用组合、替换和消除等操作(例如“T 和 U”)。 由此产生的特征称为即时特征。 +特征與結構類型一樣,可以應用組合、替換和消除等操作(例如“T 和 U”)。 由此產生的特征稱為即時特征。 ```python T = Trait {.x = Int} @@ -38,7 +38,7 @@ assert Structural(W) ! = Structural(T) assert Structural(W) == Structural(T.replace {.x = Ratio}) ``` -Trait 也是一种类型,因此可以用于普通类型规范 +Trait 也是一種類型,因此可以用于普通類型規范 ```python points: [Norm; 2] = [Point2D::new(1, 2), Point2D::new(3, 4)] @@ -47,9 +47,9 @@ assert points.iter().map(x -> x.norm()).collect(Array) == [5, 25]. ## 特征包含 -扩展运算符 `...` 允许您将包含某个特征的特征定义为超类型。 这称为特征的 __subsumption__。 +擴展運算符 `...` 允許您將包含某個特征的特征定義為超類型。 這稱為特征的 __subsumption__。 在下面的示例中,`BinAddSub` 包含 `BinAdd` 和 `BinSub`。 -这对应于类中的继承,但与继承不同的是,可以使用“和”组合多个基类型。 也允许被 `not` 部分排除的特征。 +這對應于類中的繼承,但與繼承不同的是,可以使用“和”組合多個基類型。 也允許被 `not` 部分排除的特征。 ```python Add R = Trait { @@ -65,9 +65,9 @@ Sub R = Trait { BinAddSub = Subsume Add(Self) and Sub(Self) ``` -## 结构特征 +## 結構特征 -特征可以结构化 +特征可以結構化 ```python SAdd = Structural Trait { @@ -84,8 +84,8 @@ C. assert add(C.new(1), C.new(2)) == C.new(3) ``` -名义特征不能简单地通过实现请求方法来使用,而必须明确声明已实现。 -在以下示例中,`add`不能与`C`类型的参数一起使用,因为没有明确的实现声明。 它必须是`C = Class {i = Int}, Impl := Add`。 +名義特征不能簡單地通過實現請求方法來使用,而必須明確聲明已實現。 +在以下示例中,`add`不能與`C`類型的參數一起使用,因為沒有明確的實現聲明。 它必須是`C = Class {i = Int}, Impl := Add`。 ```python Add = Trait { @@ -99,15 +99,15 @@ C. new i = Self.__new__ {i;} `_+_` self, other: Self = Self.new {i = self::i + other::i} -add C.new(1), C.new(2) # 类型错误:C 不是 Add 的子类 -# 提示:继承或修补“添加” +add C.new(1), C.new(2) # 類型錯誤:C 不是 Add 的子類 +# 提示:繼承或修補“添加” ``` -不需要为此实现声明结构特征,但类型推断不起作用。 使用时需要指定类型。 +不需要為此實現聲明結構特征,但類型推斷不起作用。 使用時需要指定類型。 -## 多态特征 +## 多態特征 -特征可以带参数。 这与多态类型相同。 +特征可以帶參數。 這與多態類型相同。 ```python Mapper T: Type = Trait { @@ -124,8 +124,8 @@ assert [1, 2, 3].iter().map(x -> "{x}").collect(Array) == ["1", "2", "3"]. ## Override特征 -派生特征可以Override基本特征的类型定义。 -在这种情况下,Override方法的类型必须是基方法类型的子类型。 +派生特征可以Override基本特征的類型定義。 +在這種情況下,Override方法的類型必須是基方法類型的子類型。 ```python # `Self.(R) -> O` is a subtype of ``Self.(R) -> O or Panic @@ -138,9 +138,9 @@ SafeDiv R, O = Subsume Div, { } ``` -## 在 API 中实现和解决重复的特征 +## 在 API 中實現和解決重復的特征 -`Add`、`Sub` 和 `Mul` 的实际定义如下所示。 +`Add`、`Sub` 和 `Mul` 的實際定義如下所示。 ```python Add R = Trait { @@ -157,11 +157,11 @@ Mul R = Trait { } ``` -`.Output` 重复。 如果要同时实现这些多个特征,请指定以下内容 +`.Output` 重復。 如果要同時實現這些多個特征,請指定以下內容 ```python P = Class {.x = Int; .y = Int} -# P|Self <: Add(P)|可简写为 P|<: Add(P)| +# 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} @@ -170,18 +170,18 @@ P|Self <: Mul(Int)|. `*` self, other = P.new {.x = self.x * other; .y = self.y * other} ``` -以这种方式实现的重复 API 在使用时几乎总是类型推断,但也可以通过使用 `||` 显式指定类型来解决。 +以這種方式實現的重復 API 在使用時幾乎總是類型推斷,但也可以通過使用 `||` 顯式指定類型來解決。 ```python -print! P.Output # 类型错误:不明确的类型 +print! P.Output # 類型錯誤:不明確的類型 print! P|<: Mul(Int)|.Output # ``` -## 附录:与 Rust 特征的区别 +## 附錄:與 Rust 特征的區別 -Erg 的特征忠实于 [Schärli 等人] (https://www.ptidej.net/courses/ift6251/fall06/presentations/061122/061122.doc.pdf) 提出的特征。 -为了允许代数运算,特征被设计为不能有方法实现目录,但可以在必要时进行修补。 +Erg 的特征忠實于 [Sch?rli 等人] (https://www.ptidej.net/courses/ift6251/fall06/presentations/061122/061122.doc.pdf) 提出的特征。 +為了允許代數運算,特征被設計為不能有方法實現目錄,但可以在必要時進行修補。 -

- 上一页 | 下一步 +

+ 上一頁 | 下一步

\ No newline at end of file diff --git a/doc/zh_TW/syntax/type/04_class.md b/doc/zh_TW/syntax/type/04_class.md index a95fabe5..02c17321 100644 --- a/doc/zh_TW/syntax/type/04_class.md +++ b/doc/zh_TW/syntax/type/04_class.md @@ -1,11 +1,11 @@ # Class -Erg 中的类大致是一种可以创建自己的元素(实例)的类型。 -这是一个简单类的示例。 +Erg 中的類大致是一種可以創建自己的元素(實例)的類型。 +這是一個簡單類的示例。 ```python Person = Class {.name = Str; .age = Nat} -# 如果 `.new` 没有定义,那么 Erg 将创建 `Person.new = Person::__new__` +# 如果 `.new` 沒有定義,那么 Erg 將創建 `Person.new = Person::__new__` Person. new name, age = Self::__new__ {.name = name; .age = age} @@ -14,23 +14,23 @@ print! john # print! classof(john) # Person ``` -赋予“Class”的类型(通常是记录类型)称为需求类型(在本例中为“{.name = Str; .age = Nat}”)。 -可以使用 `::__new__ { = ; 创建实例 ...}` 可以创建。 -`{.name = "约翰·史密斯"; .age = 25}` 只是一条记录,但它通过传递 `Person.new` 转换为 `Person` 实例。 -创建此类实例的子例程称为构造函数。 -在上面的类中,`.new` 方法被定义为可以省略字段名等。 +賦予“Class”的類型(通常是記錄類型)稱為需求類型(在本例中為“{.name = Str; .age = Nat}”)。 +可以使用 `::__new__ { = ; 創建實例 ...}` 可以創建。 +`{.name = "約翰·史密斯"; .age = 25}` 只是一條記錄,但它通過傳遞 `Person.new` 轉換為 `Person` 實例。 +創建此類實例的子例程稱為構造函數。 +在上面的類中,`.new` 方法被定義為可以省略字段名等。 -请注意,以下不带换行符的定义将导致语法错误。 +請注意,以下不帶換行符的定義將導致語法錯誤。 ```python -Person.new name, age = ... # 语法错误:不能直接在对象上定义属性 +Person.new name, age = ... # 語法錯誤:不能直接在對象上定義屬性 ``` -> __Warning__:这是最近添加的规范,后续文档中可能不会遵循。 如果你发现它,请报告它。 +> __Warning__:這是最近添加的規范,后續文檔中可能不會遵循。 如果你發現它,請報告它。 -## 实例和类属性 +## 實例和類屬性 -在 Python 和其他语言中,实例属性通常在块侧定义如下,但请注意,这样的写法在 Erg 中具有不同的含义。 +在 Python 和其他語言中,實例屬性通常在塊側定義如下,但請注意,這樣的寫法在 Erg 中具有不同的含義。 ```python # Python @@ -40,7 +40,7 @@ class Person: ``` ```python -# 在Erg中,这个符号意味着类属性的声明(不是实例属性) +# 在Erg中,這個符號意味著類屬性的聲明(不是實例屬性) Person = Class() Person. name: Str @@ -48,18 +48,18 @@ Person. ``` ```python -# 以上 Python 代码的 Erg 代码 +# 以上 Python 代碼的 Erg 代碼 Person = Class { .name = Str .age = Nat } ``` -元素属性(在记录中定义的属性)和类型属性(也称为实例/类属性,尤其是在类的情况下)是完全不同的东西。 类型属性是类型本身的属性。 当一个类型的元素本身没有所需的属性时,它指的是一个类型属性。 元素属性是元素直接拥有的唯一属性。 -为什么要进行这种区分? 如果所有属性都是元素属性,那么在创建对象时复制和初始化所有属性将是低效的。 -此外,以这种方式划分属性明确了诸如“该属性是共享的”和“该属性是分开持有的”之类的角色。 +元素屬性(在記錄中定義的屬性)和類型屬性(也稱為實例/類屬性,尤其是在類的情況下)是完全不同的東西。 類型屬性是類型本身的屬性。 當一個類型的元素本身沒有所需的屬性時,它指的是一個類型屬性。 元素屬性是元素直接擁有的唯一屬性。 +為什么要進行這種區分? 如果所有屬性都是元素屬性,那么在創建對象時復制和初始化所有屬性將是低效的。 +此外,以這種方式劃分屬性明確了諸如“該屬性是共享的”和“該屬性是分開持有的”之類的角色。 -下面的例子说明了这一点。 `species` 属性对所有实例都是通用的,因此将其用作类属性更自然。 但是,属性 `name` 应该是实例属性,因为每个实例都应该单独拥有它。 +下面的例子說明了這一點。 `species` 屬性對所有實例都是通用的,因此將其用作類屬性更自然。 但是,屬性 `name` 應該是實例屬性,因為每個實例都應該單獨擁有它。 ```python Person = Class {name = Str} @@ -71,51 +71,51 @@ Person. greet self = log "Hello, My name is {self::name}." -Person.describe() # 类型:Person -Person.greet() # 类型错误: 未绑定的方法 Person.greet 需要一个参数 +Person.describe() # 類型:Person +Person.greet() # 類型錯誤: 未綁定的方法 Person.greet 需要一個參數 john = Person.new {name = "John"} -john.describe() # 类型: human -john.greet() # 你好,我是约翰 +john.describe() # 類型: human +john.greet() # 你好,我是約翰 alice = Person.new {name = "Alice"} -alice.describe() # 类型: human -alice.greet() # 你好,我是爱丽丝 +alice.describe() # 類型: human +alice.greet() # 你好,我是愛麗絲 ``` -顺便说一下,如果实例属性和类型属性具有相同的名称和相同的类型,则会发生编译错误。 这是为了避免混淆。 +順便說一下,如果實例屬性和類型屬性具有相同的名稱和相同的類型,則會發生編譯錯誤。 這是為了避免混淆。 ```python C = Class {.i = Int} -C.i = 1 # 属性错误:`.i` 已在实例字段中定义 +C.i = 1 # 屬性錯誤:`.i` 已在實例字段中定義 ``` -## 类(Class), 类型(Type) +## 類(Class), 類型(Type) -请注意,`1` 的类和类型是不同的。 -只有一个类 `Int` 是 `1` 的生成器。 可以通过`classof(obj)`或`obj.__class__`获取对象所属的类。 -相比之下,`1`有无数种。 例如,`{1}, {0, 1}, 0..12, Nat, Int, Num`。 -但是,可以将最小类型定义为单一类型,在本例中为“{1}”。 可以通过`Typeof(obj)`获取对象所属的类型。 这是一个编译时函数。 -对象可以使用补丁方法以及类方法。 -Erg 不允许您添加类方法,但您可以使用 [patch](./07_patch.md) 来扩展类。 +請注意,`1` 的類和類型是不同的。 +只有一個類 `Int` 是 `1` 的生成器。 可以通過`classof(obj)`或`obj.__class__`獲取對象所屬的類。 +相比之下,`1`有無數種。 例如,`{1}, {0, 1}, 0..12, Nat, Int, Num`。 +但是,可以將最小類型定義為單一類型,在本例中為“{1}”。 可以通過`Typeof(obj)`獲取對象所屬的類型。 這是一個編譯時函數。 +對象可以使用補丁方法以及類方法。 +Erg 不允許您添加類方法,但您可以使用 [patch](./07_patch.md) 來擴展類。 -您还可以从现有类([Inheritable](./../27_decorator.md/#inheritable) 类)继承。 -您可以使用 `Inherit` 创建一个继承类。 左侧的类型称为派生类,右侧的“继承”的参数类型称为基类(继承类)。 +您還可以從現有類([Inheritable](./../27_decorator.md/#inheritable) 類)繼承。 +您可以使用 `Inherit` 創建一個繼承類。 左側的類型稱為派生類,右側的“繼承”的參數類型稱為基類(繼承類)。 ```python MyStr = Inherit Str -# other: 如果你设置 ``other: Str'',你可以使用 MyStr。 +# other: 如果你設置 ``other: Str'',你可以使用 MyStr。 MyStr. `-` self, other: Str = self.replace other, "" abc = MyStr.new("abc") -# 这里的比较是向上的 +# 這里的比較是向上的 assert abc - "b" == "ac" ``` -与 Python 不同,默认情况下,定义的 Erg 类是 `final`(不可继承的)。 -要使类可继承,必须将 `Inheritable` 装饰器附加到该类。 -Str` 是可继承的类之一。 +與 Python 不同,默認情況下,定義的 Erg 類是 `final`(不可繼承的)。 +要使類可繼承,必須將 `Inheritable` 裝飾器附加到該類。 +Str` 是可繼承的類之一。 ```python MyStr = Inherit Str # OK @@ -126,10 +126,10 @@ InheritableMyStr = Inherit Str MyStr3 = Inherit InheritableMyStr # OK ``` -`Inherit Object` 和 `Class()` 在实践中几乎是等价的。 一般使用后者。 +`Inherit Object` 和 `Class()` 在實踐中幾乎是等價的。 一般使用后者。 -类具有与类型不同的等价检查机制。 -类型基于其结构进行等效性测试。 +類具有與類型不同的等價檢查機制。 +類型基于其結構進行等效性測試。 ```python Person = {.name = Str; .age = Nat} @@ -144,12 +144,12 @@ class has no equivalence relation defined. Person = Class {.name = Str; .age = Nat} Human = Class {.name = Str; .age = Nat} -Person == Human # 类型错误:无法比较类 +Person == Human # 類型錯誤:無法比較類 ``` -## 与结构类型的区别 +## 與結構類型的區別 -我们说过类是一种可以生成自己的元素的类型,但这并不是严格的描述。 事实上,一个记录类型+补丁可以做同样的事情。 +我們說過類是一種可以生成自己的元素的類型,但這并不是嚴格的描述。 事實上,一個記錄類型+補丁可以做同樣的事情。 ```python Person = {.name = Str; .age = Nat} @@ -160,19 +160,19 @@ PersonImpl. john = Person.new("John Smith", 25) ``` -使用类有四个优点。 -第一个是构造函数经过有效性检查,第二个是它的性能更高,第三个是您可以使用符号子类型(NST),第四个是您可以继承和覆盖。 +使用類有四個優點。 +第一個是構造函數經過有效性檢查,第二個是它的性能更高,第三個是您可以使用符號子類型(NST),第四個是您可以繼承和覆蓋。 -我们之前看到记录类型 + 补丁也可以定义一个构造函数(某种意义上),但这当然不是一个合法的构造函数。 这当然不是一个合法的构造函数,因为它可以返回一个完全不相关的对象,即使它调用自己`.new`。 在类的情况下,`.new` 被静态检查以查看它是否生成满足要求的对象。 +我們之前看到記錄類型 + 補丁也可以定義一個構造函數(某種意義上),但這當然不是一個合法的構造函數。 這當然不是一個合法的構造函數,因為它可以返回一個完全不相關的對象,即使它調用自己`.new`。 在類的情況下,`.new` 被靜態檢查以查看它是否生成滿足要求的對象。 ~ -类的类型检查只是检查对象的`。 __class__` 对象的属性。 因此可以快速检查一个对象是否属于一个类型。 +類的類型檢查只是檢查對象的`。 __class__` 對象的屬性。 因此可以快速檢查一個對象是否屬于一個類型。 ~ -Erg 在课堂上启用 NST; NST 的优点包括健壮性。 -在编写大型程序时,经常会出现对象的结构巧合匹配的情况。 +Erg 在課堂上啟用 NST; NST 的優點包括健壯性。 +在編寫大型程序時,經常會出現對象的結構巧合匹配的情況。 ```python Dog = {.name = Str; .age = Nat} @@ -189,8 +189,8 @@ john = {.name = "John Smith"; .age = 20} john.bark() # "Yelp!" ``` -`Dog` 和 `Person` 的结构完全一样,但让动物打招呼,让人类吠叫显然是无稽之谈。 -前者是不可能的,所以让它不适用更安全。 在这种情况下,最好使用类。 +`Dog` 和 `Person` 的結構完全一樣,但讓動物打招呼,讓人類吠叫顯然是無稽之談。 +前者是不可能的,所以讓它不適用更安全。 在這種情況下,最好使用類。 ```python Dog = Class {.name = Str; .age = Nat} @@ -200,12 +200,12 @@ Person = Class {.name = Str; .age = Nat} Person.greet self = log "Hello, my name is {self.name}." john = Person.new {.name = "John Smith"; .age = 20} -john.bark() # 类型错误: `Person` 对象没有方法 `.bark`。 +john.bark() # 類型錯誤: `Person` 對象沒有方法 `.bark`。 ``` -另一个特点是补丁添加的类型属性是虚拟的,实现类不作为实体保存。 -也就是说,`T.x`、`T.bar` 是可以通过与 `{i = Int}` 兼容的类型访问(编译时绑定)的对象,并且未在 `{i = Int}` 或 ` C`。 -相反,类属性由类本身持有。 因此,它们不能被不处于继承关系的类访问,即使它们具有相同的结构。 +另一個特點是補丁添加的類型屬性是虛擬的,實現類不作為實體保存。 +也就是說,`T.x`、`T.bar` 是可以通過與 `{i = Int}` 兼容的類型訪問(編譯時綁定)的對象,并且未在 `{i = Int}` 或 ` C`。 +相反,類屬性由類本身持有。 因此,它們不能被不處于繼承關系的類訪問,即使它們具有相同的結構。 ```python C = Class {i = Int} @@ -220,25 +220,25 @@ T. print! dir(T) # ["bar", "x", ...]. assert T.x == 1 assert {i = 1}.x == 1 -print! T.bar # <函数 bar> -{i = Int}.bar # 类型错误:Record({i = Int}) 没有方法 `.bar`。 -C.bar # 类型错误:C 没有方法 `.bar` 打印! +print! T.bar # <函數 bar> +{i = Int}.bar # 類型錯誤:Record({i = Int}) 沒有方法 `.bar`。 +C.bar # 類型錯誤:C 沒有方法 `.bar` 打印! print! {i = 1}.bar # <方法 bar> C.new({i = 1}).bar # <方法 bar> ``` -## 与数据类的区别 +## 與數據類的區別 -有两种类型的类:常规类,通过`Class`成为记录类,以及从记录类继承(`Inherit`)的数据类。 -数据类继承了记录类的功能,具有分解赋值、默认实现的`==`和`hash`等特性。另一方面,数据类有自己的等价关系和格式展示。 -另一方面,如果要定义自己的等价关系或格式显示,则应使用普通类。 +有兩種類型的類:常規類,通過`Class`成為記錄類,以及從記錄類繼承(`Inherit`)的數據類。 +數據類繼承了記錄類的功能,具有分解賦值、默認實現的`==`和`hash`等特性。另一方面,數據類有自己的等價關系和格式展示。 +另一方面,如果要定義自己的等價關系或格式顯示,則應使用普通類。 ```python C = Class {i = Int} c = C.new {i = 1} d = C.new {i = 2} print! c # -c == d # 类型错误:`==` 没有为 `C` 实现 +c == d # 類型錯誤:`==` 沒有為 `C` 實現 D = Inherit {i = Int} e = D.new {i = 1} @@ -247,9 +247,9 @@ print! e # D{i = 1} assert e ! = f ``` -## 枚举类 +## 枚舉類 -为了便于定义“Or”类型的类,提供了一个“Enum”。 +為了便于定義“Or”類型的類,提供了一個“Enum”。 ```python X = Class() @@ -257,8 +257,8 @@ Y = Class() XorY = Enum X, Y ``` -每种类型都可以通过`XorY.X`、`XorY.Y`来访问,构造函数可以通过`XorY.cons(X)`获得。 -`.cons` 是一个接受类并返回其构造函数的方法。 +每種類型都可以通過`XorY.X`、`XorY.Y`來訪問,構造函數可以通過`XorY.cons(X)`獲得。 +`.cons` 是一個接受類并返回其構造函數的方法。 ```python x1 = XorY.new X.new() @@ -266,9 +266,9 @@ x2 = XorY.cons(X)() assert x1 == x2 ``` -## 类关系 +## 類關系 -类是需求类型的子类型。 类中可以使用需求类型的方法(包括补丁方法)。 +類是需求類型的子類型。 類中可以使用需求類型的方法(包括補丁方法)。 ```python T = Trait {.foo = Foo} @@ -283,5 +283,5 @@ assert T.foo == Foo ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/type/05_inheritance.md b/doc/zh_TW/syntax/type/05_inheritance.md index c4efa961..19ee1501 100644 --- a/doc/zh_TW/syntax/type/05_inheritance.md +++ b/doc/zh_TW/syntax/type/05_inheritance.md @@ -1,7 +1,7 @@ -# 继承 +# 繼承 -继承允许您定义一个新类,为现有类添加功能或专业化。 -继承类似于包含在特征中。 继承的类成为原始类的子类型。 +繼承允許您定義一個新類,為現有類添加功能或專業化。 +繼承類似于包含在特征中。 繼承的類成為原始類的子類型。 ```python NewInt = Inherit Int @@ -12,9 +12,9 @@ assert NewInt.new(1).plus1() == 2 assert NewInt.new(1) + NewInt.new(1) == 2 ``` -如果你希望新定义的类是可继承的,你必须给它一个 `Inheritable` 装饰器。 +如果你希望新定義的類是可繼承的,你必須給它一個 `Inheritable` 裝飾器。 -您可以指定一个可选参数 `additional` 以允许该类具有其他实例属性,但前提是该类是一个值类。 但是,如果类是值类,则不能添加实例属性。 +您可以指定一個可選參數 `additional` 以允許該類具有其他實例屬性,但前提是該類是一個值類。 但是,如果類是值類,則不能添加實例屬性。 ```python @Inheritable @@ -24,15 +24,15 @@ Student = Inherit Person, additional: {id = Int} john = Person.new {name = "John"} alice = Student.new {name = "Alice", id = 123} -MailAddress = Inherit Str, additional: {owner = Str} # 类型错误:实例变量不能添加到值类中 +MailAddress = Inherit Str, additional: {owner = Str} # 類型錯誤:實例變量不能添加到值類中 ``` -Erg 的特殊设计不允许继承“Never”类型。 Erg 的特殊设计不允许继承 `Never` 类型,因为 `Never` 是一个永远无法实例化的独特类。 +Erg 的特殊設計不允許繼承“Never”類型。 Erg 的特殊設計不允許繼承 `Never` 類型,因為 `Never` 是一個永遠無法實例化的獨特類。 -## 枚举类的继承 +## 枚舉類的繼承 -[Or 类型](./13_algebraic.md) 也可以被继承。 在这种情况下,您可以通过指定可选参数 `Excluding` 来删除任何选项(可以使用 `or` 进行多项选择)。 -不能添加其他选项。 添加选项的类不是原始类的子类型。 +[Or 類型](./13_algebraic.md) 也可以被繼承。 在這種情況下,您可以通過指定可選參數 `Excluding` 來刪除任何選項(可以使用 `or` 進行多項選擇)。 +不能添加其他選項。 添加選項的類不是原始類的子類型。 ```python Number = Class Int or Float or Complex @@ -42,11 +42,11 @@ Number.abs(self): Float = f: Float -> f.abs() c: Complex -> c.abs().into Float -# c: 复杂不能出现在匹配选项中 +# c: 復雜不能出現在匹配選項中 RealNumber = Inherit Number, Excluding: Complex ``` -同样,也可以指定[细化类型](./12_refinement.md)。 +同樣,也可以指定[細化類型](./12_refinement.md)。 ```python Months = Class 0..12 @@ -56,22 +56,22 @@ StrMoreThan3 = Class StrWithLen N | N >= 3 StrMoreThan4 = Inherit StrMoreThan3, Excluding: StrWithLen N | N == 3 ``` -## 覆盖 +## 覆蓋 -该类与补丁相同,可以将新方法添加到原始类型,但可以进一步“覆盖”该类。 -这种覆盖称为覆盖。要覆盖,必须满足三个条件。 -首先,覆盖必须有一个 `Override` 装饰器,因为默认情况下它会导致错误。 -另外,覆盖不能改变方法的类型。它必须是原始类型的子类型。 -如果你重写了一个被另一个方法引用的方法,你也必须重写所有被引用的方法。 +該類與補丁相同,可以將新方法添加到原始類型,但可以進一步“覆蓋”該類。 +這種覆蓋稱為覆蓋。要覆蓋,必須滿足三個條件。 +首先,覆蓋必須有一個 `Override` 裝飾器,因為默認情況下它會導致錯誤。 +另外,覆蓋不能改變方法的類型。它必須是原始類型的子類型。 +如果你重寫了一個被另一個方法引用的方法,你也必須重寫所有被引用的方法。 -为什么这个条件是必要的?这是因为重写不仅会改变一种方法的行为,而且可能会影响另一种方法的行为。 +為什么這個條件是必要的?這是因為重寫不僅會改變一種方法的行為,而且可能會影響另一種方法的行為。 -让我们从第一个条件开始。此条件是为了防止“意外覆盖”。 -换句话说,必须使用 `Override` 装饰器来防止派生类中新定义的方法的名称与基类的名称冲突。 +讓我們從第一個條件開始。此條件是為了防止“意外覆蓋”。 +換句話說,必須使用 `Override` 裝飾器來防止派生類中新定義的方法的名稱與基類的名稱沖突。 -接下来,考虑第二个条件。这是为了类型一致性。由于派生类是基类的子类型,因此它的行为也必须与基类的行为兼容。 +接下來,考慮第二個條件。這是為了類型一致性。由于派生類是基類的子類型,因此它的行為也必須與基類的行為兼容。 -最后,考虑第三个条件。这种情况是 Erg 独有的,在其他面向对象语言中并不常见,同样是为了安全。让我们看看如果不是这种情况会出现什么问题。 +最后,考慮第三個條件。這種情況是 Erg 獨有的,在其他面向對象語言中并不常見,同樣是為了安全。讓我們看看如果不是這種情況會出現什么問題。 ```python # 反面示例 @@ -86,13 +86,13 @@ Base! Inherited! = Inherit Base! Inherited! @Override - g! ref! self = self.f!() # 无限递归警告:此代码陷入无限循环 - # 覆盖错误:方法 `.g` 被 `.f` 引用但未被覆盖 + g! ref! self = self.f!() # 無限遞歸警告:此代碼陷入無限循環 + # 覆蓋錯誤:方法 `.g` 被 `.f` 引用但未被覆蓋 ``` -在继承类 `Inherited!` 中,`.g!` 方法被重写以将处理转移到 `.f!`。 但是,基类中的 `.f!` 方法会将其处理转移到 `.g!`,从而导致无限循环。 `.f` 是 `Base!` 类中的一个没有问题的方法,但它被覆盖以一种意想不到的方式使用,并且被破坏了。 +在繼承類 `Inherited!` 中,`.g!` 方法被重寫以將處理轉移到 `.f!`。 但是,基類中的 `.f!` 方法會將其處理轉移到 `.g!`,從而導致無限循環。 `.f` 是 `Base!` 類中的一個沒有問題的方法,但它被覆蓋以一種意想不到的方式使用,并且被破壞了。 -Erg 已将此规则构建到规范中。 +Erg 已將此規則構建到規范中。 ```python # OK. @@ -114,51 +114,51 @@ Inherited! g! ref! self = self.f!() ``` -然而,这个规范并没有完全解决覆盖问题。 然而,这个规范并没有完全解决覆盖问题,因为编译器无法检测覆盖是否解决了问题。 -创建派生类的程序员有责任纠正覆盖的影响。 只要有可能,尝试定义一个别名方法。 +然而,這個規范并沒有完全解決覆蓋問題。 然而,這個規范并沒有完全解決覆蓋問題,因為編譯器無法檢測覆蓋是否解決了問題。 +創建派生類的程序員有責任糾正覆蓋的影響。 只要有可能,嘗試定義一個別名方法。 -### 替换特征(或看起来像什么) +### 替換特征(或看起來像什么) -尽管无法在继承时替换特征,但有一些示例似乎可以这样做。 +盡管無法在繼承時替換特征,但有一些示例似乎可以這樣做。 -例如,`Int`,`Real` 的子类型(实现了 `Add()`),似乎重新实现了 `Add()`。 +例如,`Int`,`Real` 的子類型(實現了 `Add()`),似乎重新實現了 `Add()`。 ```python Int = Class ... , Impl := Add() and ... ``` -但实际上 `Real` 中的 `Add()` 代表 `Add(Real, Real)`,而在 `Int` 中它只是被 `Add(Int, Int)` 覆盖。 -它们是两个不同的特征(`Add` 是一个 [covariate](./advanced/variance.md),所以`Add(Real, Real) :> Add(Int, Int)`)。 +但實際上 `Real` 中的 `Add()` 代表 `Add(Real, Real)`,而在 `Int` 中它只是被 `Add(Int, Int)` 覆蓋。 +它們是兩個不同的特征(`Add` 是一個 [covariate](./advanced/variance.md),所以`Add(Real, Real) :> Add(Int, Int)`)。 -## 多重继承 +## 多重繼承 -Erg 不允许普通类之间的交集、差异和互补。 +Erg 不允許普通類之間的交集、差異和互補。 ```python -Int and Str # 类型错误:无法合并类 +Int and Str # 類型錯誤:無法合并類 ``` -该规则防止从多个类继承,即多重继承。 +該規則防止從多個類繼承,即多重繼承。 ```python -IntAndStr = Inherit Int and Str # 语法错误:不允许类的多重继承 +IntAndStr = Inherit Int and Str # 語法錯誤:不允許類的多重繼承 ``` -但是,可以使用多个继承的 Python 类。 +但是,可以使用多個繼承的 Python 類。 -## 多层(多级)继承 +## 多層(多級)繼承 -Erg 继承也禁止多层继承。 也就是说,您不能定义从另一个类继承的类。 -从“Object”继承的可继承类可能会异常继承。 +Erg 繼承也禁止多層繼承。 也就是說,您不能定義從另一個類繼承的類。 +從“Object”繼承的可繼承類可能會異常繼承。 -同样在这种情况下,可以使用 Python 的多层继承类。 +同樣在這種情況下,可以使用 Python 的多層繼承類。 -## 重写继承的属性 +## 重寫繼承的屬性 -Erg 不允许重写从基类继承的属性。 这有两个含义。 +Erg 不允許重寫從基類繼承的屬性。 這有兩個含義。 -第一个是对继承的源类属性的更新操作。 例如,它不能重新分配,也不能通过 `.update!` 方法更新。 +第一個是對繼承的源類屬性的更新操作。 例如,它不能重新分配,也不能通過 `.update!` 方法更新。 -覆盖与重写不同,因为它是一种用更专业的方法覆盖的操作。 覆盖也必须替换为兼容的类型。 +覆蓋與重寫不同,因為它是一種用更專業的方法覆蓋的操作。 覆蓋也必須替換為兼容的類型。 ```python @Inheritable @@ -170,14 +170,14 @@ Base! Inherited! = Inherit Base! Inherited! var.update! v -> v + 1 - # 类型错误:不能更新基类变量 + # 類型錯誤:不能更新基類變量 @Override inc_pub! ref! self = self.pub + 1 - # 覆盖错误:`.inc_pub!` 必须是 `Self! 的子类型! () => ()` + # 覆蓋錯誤:`.inc_pub!` 必須是 `Self! 的子類型! () => ()` ``` -第二个是对继承源的(变量)实例属性的更新操作。 这也是被禁止的。 基类的实例属性只能从基类提供的方法中更新。 -无论属性的可见性如何,都无法直接更新。 但是,它们可以被读取。 +第二個是對繼承源的(變量)實例屬性的更新操作。 這也是被禁止的。 基類的實例屬性只能從基類提供的方法中更新。 +無論屬性的可見性如何,都無法直接更新。 但是,它們可以被讀取。 ```python @Inheritable @@ -192,41 +192,41 @@ Inherited! add2_pub! ref! self = self.inc_pub!() self.inc_pub!() - # NG, `Child` 不能触摸 `self.pub` 和 `self::pri`。 + # NG, `Child` 不能觸摸 `self.pub` 和 `self::pri`。 add2_pub! ref! self = self.pub.update! p -> p + 2 ``` -毕竟 Erg 继承只能添加新的属性和覆盖基类的方法。 +畢竟 Erg 繼承只能添加新的屬性和覆蓋基類的方法。 -## 使用继承 +## 使用繼承 -虽然继承在正确使用时是一项强大的功能,但它也有一个缺点,即它往往会使类依赖关系复杂化,尤其是在使用多层或多层继承时。复杂的依赖关系会降低代码的可维护性。 -Erg 禁止多重和多层继承的原因是为了降低这种风险,并且引入了类补丁功能以降低依赖关系的复杂性,同时保留继承的“添加功能”方面。 +雖然繼承在正確使用時是一項強大的功能,但它也有一個缺點,即它往往會使類依賴關系復雜化,尤其是在使用多層或多層繼承時。復雜的依賴關系會降低代碼的可維護性。 +Erg 禁止多重和多層繼承的原因是為了降低這種風險,并且引入了類補丁功能以降低依賴關系的復雜性,同時保留繼承的“添加功能”方面。 -那么,反过来说,应该在哪里使用继承呢?一个指标是何时需要“基类的语义子类型”。 -Erg 允许类型系统自动进行部分子类型确定(例如,Nat,其中 Int 大于或等于 0)。 -但是,例如,仅依靠 Erg 的类型系统很难创建“表示有效电子邮件地址的字符串类型”。您可能应该对普通字符串执行验证。然后,我们想为已通过验证的字符串对象添加某种“保证”。这相当于向下转换为继承的类。将 `Str object` 向下转换为 `ValidMailAddressStr` 与验证字符串是否采用正确的电子邮件地址格式是一一对应的。 +那么,反過來說,應該在哪里使用繼承呢?一個指標是何時需要“基類的語義子類型”。 +Erg 允許類型系統自動進行部分子類型確定(例如,Nat,其中 Int 大于或等于 0)。 +但是,例如,僅依靠 Erg 的類型系統很難創建“表示有效電子郵件地址的字符串類型”。您可能應該對普通字符串執行驗證。然后,我們想為已通過驗證的字符串對象添加某種“保證”。這相當于向下轉換為繼承的類。將 `Str object` 向下轉換為 `ValidMailAddressStr` 與驗證字符串是否采用正確的電子郵件地址格式是一一對應的。 ```python ValidMailAddressStr = Inherit Str ValidMailAddressStr. init s: Str = - validate s # 邮件地址验证 + validate s # 郵件地址驗證 Self.new s s1 = "invalid mail address" s2 = "foo@gmail.com" -_ = ValidMailAddressStr.init s1 # 恐慌:无效的邮件地址 +_ = ValidMailAddressStr.init s1 # 恐慌:無效的郵件地址 valid = ValidMailAddressStr.init s2 -valid: ValidMailAddressStr # 确保电子邮件地址格式正确 +valid: ValidMailAddressStr # 確保電子郵件地址格式正確 ``` -另一个指标是您何时想要实现名义多态性。 -例如,下面定义的 `greet!` 过程将接受任何类型为 `Named` 的对象。 -但显然应用 `Dog` 类型的对象是错误的。 所以我们将使用 `Person` 类作为参数类型。 -这样,只有 `Person` 对象、从它们继承的类和 `Student` 对象将被接受为参数。 -这是比较保守的,避免不必要地承担过多的责任。 +另一個指標是您何時想要實現名義多態性。 +例如,下面定義的 `greet!` 過程將接受任何類型為 `Named` 的對象。 +但顯然應用 `Dog` 類型的對象是錯誤的。 所以我們將使用 `Person` 類作為參數類型。 +這樣,只有 `Person` 對象、從它們繼承的類和 `Student` 對象將被接受為參數。 +這是比較保守的,避免不必要地承擔過多的責任。 ```python Named = {name = Str; ...} @@ -242,12 +242,12 @@ max = Dog.new {name = "Max", breed = "Labrador"} john = Person.new {name = "John"} alice = Student.new {name = "Alice", id = 123} -structural_greet! max # 你好,我是马克斯 -structural_greet! john # 你好,我是约翰 -greet! alice # 你好,我是爱丽丝 -greet! max # 类型错误: +structural_greet! max # 你好,我是馬克斯 +structural_greet! john # 你好,我是約翰 +greet! alice # 你好,我是愛麗絲 +greet! max # 類型錯誤: ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/type/06_nst_vs_sst.md b/doc/zh_TW/syntax/type/06_nst_vs_sst.md index 7d0393eb..1464f8a1 100644 --- a/doc/zh_TW/syntax/type/06_nst_vs_sst.md +++ b/doc/zh_TW/syntax/type/06_nst_vs_sst.md @@ -1,4 +1,4 @@ -# 名义子类型与结构子类型 +# 名義子類型與結構子類型 ```python Months = 0..12 @@ -27,17 +27,17 @@ 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。 -SST 需要抽象技能来编写在任何用例中都不会崩溃的代码。 好的抽象可以带来高生产力,但错误的抽象(外观上的共性)会导致适得其反的结果。(NST 可以通过故意将抽象保持在最低限度来降低这种风险。如果您不是库实现者,那么仅使用 NST 进行编码并不是一个坏主意。 +如果您無法決定使用哪一個,我們的建議是 NST。 +SST 需要抽象技能來編寫在任何用例中都不會崩潰的代碼。 好的抽象可以帶來高生產力,但錯誤的抽象(外觀上的共性)會導致適得其反的結果。(NST 可以通過故意將抽象保持在最低限度來降低這種風險。如果您不是庫實現者,那么僅使用 NST 進行編碼并不是一個壞主意。

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/type/07_patch.md b/doc/zh_TW/syntax/type/07_patch.md index 20adf0c8..da3f02ef 100644 --- a/doc/zh_TW/syntax/type/07_patch.md +++ b/doc/zh_TW/syntax/type/07_patch.md @@ -1,8 +1,8 @@ -# 修补 +# 修補 -Erg 不允许修改现有类型和类。 -这意味着,不可能在类中定义额外的方法,也不能执行特化(一种语言特性,单态化多态声明的类型并定义专用方法,如在 C++ 中)。 -但是,在许多情况下,您可能希望向现有类型或类添加功能,并且有一个称为“修补”的功能允许您执行此操作。 +Erg 不允許修改現有類型和類。 +這意味著,不可能在類中定義額外的方法,也不能執行特化(一種語言特性,單態化多態聲明的類型并定義專用方法,如在 C++ 中)。 +但是,在許多情況下,您可能希望向現有類型或類添加功能,并且有一個稱為“修補”的功能允許您執行此操作。 ```python StrReverse = Patch Str @@ -12,34 +12,34 @@ StrReverse. assert "abc".reverse() == "cba" ``` -补丁的名称应该是要添加的主要功能的简单描述。 -这样,被修补类型的对象(`Str`)可以使用修补程序的方法(`StrReverse`)。 -实际上,内置方法`.reverse`并不是`Str`的方法,而是`StrRReverse`中添加的方法。 +補丁的名稱應該是要添加的主要功能的簡單描述。 +這樣,被修補類型的對象(`Str`)可以使用修補程序的方法(`StrReverse`)。 +實際上,內置方法`.reverse`并不是`Str`的方法,而是`StrRReverse`中添加的方法。 -但是,补丁方法的优先级低于名义类型(类/特质)的方法,并且不能覆盖现有类型。 +但是,補丁方法的優先級低于名義類型(類/特質)的方法,并且不能覆蓋現有類型。 ```python StrangeInt = Patch Int StrangeInt. - `_+_` = Int.`_-_` # 赋值错误:. `_+_` 已在 Int 中定义 + `_+_` = Int.`_-_` # 賦值錯誤:. `_+_` 已在 Int 中定義 ``` -如果要覆盖,则必须从类继承。 -但是,基本上建议不要覆盖并定义具有不同名称的方法。 -由于一些安全限制,覆盖不是很容易做到。 +如果要覆蓋,則必須從類繼承。 +但是,基本上建議不要覆蓋并定義具有不同名稱的方法。 +由于一些安全限制,覆蓋不是很容易做到。 ```python StrangeInt = Inherit Int StrangeInt. -# 覆盖方法必须被赋予覆盖装饰器。 - # 另外,你需要覆盖所有依赖于 Int.`_+_` 的 Int 方法。 +# 覆蓋方法必須被賦予覆蓋裝飾器。 + # 另外,你需要覆蓋所有依賴于 Int.`_+_` 的 Int 方法。 @Override - `_+_` = Super.`_-_` # OverrideError: Int.`_+_` 被 ... ````` 引用,所以这些方法也必须被覆盖 + `_+_` = Super.`_-_` # OverrideError: Int.`_+_` 被 ... ````` 引用,所以這些方法也必須被覆蓋 ``` -## 选择修补程序 +## 選擇修補程序 -可以为单一类型定义修复程序,并且可以组合在一起。 +可以為單一類型定義修復程序,并且可以組合在一起。 ```python # foo.er @@ -70,7 +70,7 @@ assert "to camel case".to_camel_case() == "toCamelCase" assert "to kebab case".to_kebab_case() == "to-kebab-case" ``` -如果定义了多个修复程序,其中一些可能会导致重复实施 +如果定義了多個修復程序,其中一些可能會導致重復實施 ```python # foo.er @@ -78,15 +78,15 @@ assert "to kebab case".to_kebab_case() == "to-kebab-case" StrReverse = Patch(Str) StrReverse. reverse self = ... -# 更高效的实现 +# 更高效的實現 StrReverseMk2 = Patch(Str) StrReverseMk2. reverse self = ... -"hello".reverse() # 补丁选择错误: `.reverse` 的多个选择: StrReverse, StrReverseMk2 +"hello".reverse() # 補丁選擇錯誤: `.reverse` 的多個選擇: StrReverse, StrReverseMk2 ``` -在这种情况下,您可以使用 __related function__ 形式而不是方法形式使其唯一 +在這種情況下,您可以使用 __related function__ 形式而不是方法形式使其唯一 ```python assert StrReverseMk2.reverse("hello") == "olleh" @@ -100,11 +100,11 @@ You can also make it unique by selectively importing. assert "hello".reverse() == "olleh" ``` -## 胶水补丁 +## 膠水補丁 -维修程序也可以将类型相互关联。 `StrReverse` 补丁涉及 `Str` 和 `Reverse`。 -这样的补丁称为 __glue patch__。 -因为 `Str` 是内置类型,所以用户需要使用胶水补丁来改造特征。 +維修程序也可以將類型相互關聯。 `StrReverse` 補丁涉及 `Str` 和 `Reverse`。 +這樣的補丁稱為 __glue patch__。 +因為 `Str` 是內置類型,所以用戶需要使用膠水補丁來改造特征。 ```python Reverse = Trait { @@ -117,9 +117,9 @@ StrReverse. self.iter().rev().collect(Str) ``` -每个类型/特征对只能定义一个胶水补丁。 -这是因为如果多个胶水修复程序同时“可见”,就不可能唯一确定选择哪个实现。 -但是,当移动到另一个范围(模块)时,您可以交换维修程序。 +每個類型/特征對只能定義一個膠水補丁。 +這是因為如果多個膠水修復程序同時“可見”,就不可能唯一確定選擇哪個實現。 +但是,當移動到另一個范圍(模塊)時,您可以交換維修程序。 ```python NumericStr = Inherit Str @@ -129,13 +129,13 @@ NumericStr. NumStrRev = Patch NumericStr, Impl := Reverse NumStrRev. ... -# 重复修补程序错误:数值Str已与“反向”关联` -# 提示:'Str'(NumericStr'的超类)通过'StrReverse'与'Reverse'关联 +# 重復修補程序錯誤:數值Str已與“反向”關聯` +# 提示:'Str'(NumericStr'的超類)通過'StrReverse'與'Reverse'關聯 ``` -## 附录:与 Rust 特征的关系 +## 附錄:與 Rust 特征的關系 -Erg 修复程序相当于 Rust 的(改造的)`impl` 块。 +Erg 修復程序相當于 Rust 的(改造的)`impl` 塊。 ```rust // Rust @@ -150,7 +150,7 @@ impl Reverse for String { } ``` -可以说,Rust 的特征是 Erg 的特征和修复程序的特征。 这使得 Rust 的特征听起来更方便,但事实并非如此。 +可以說,Rust 的特征是 Erg 的特征和修復程序的特征。 這使得 Rust 的特征聽起來更方便,但事實并非如此。 ```python # Erg @@ -164,8 +164,8 @@ StrReverse. self.iter().rev().collect(Str) ``` -因为 impl 块在 Erg 中被对象化为补丁,所以在从其他模块导入时可以选择性地包含。 作为副作用,它还允许将外部特征实现到外部结构。 -此外,结构类型不再需要诸如 `dyn trait` 和 `impl trait` 之类的语法。 +因為 impl 塊在 Erg 中被對象化為補丁,所以在從其他模塊導入時可以選擇性地包含。 作為副作用,它還允許將外部特征實現到外部結構。 +此外,結構類型不再需要諸如 `dyn trait` 和 `impl trait` 之類的語法。 ```python # Erg @@ -183,11 +183,11 @@ fn iter(i: I) -> impl Iterator where I: IntoIterator { } ``` -## 通用补丁 +## 通用補丁 -补丁不仅可以为一种特定类型定义,还可以为“一般功能类型”等定义。 -在这种情况下,要给出自由度的项作为参数给出(在下面的情况下,`T:Type`)。 以这种方式定义的补丁称为全对称补丁。 -如您所见,全对称补丁正是一个返回补丁的函数,但它本身也可以被视为补丁。 +補丁不僅可以為一種特定類型定義,還可以為“一般功能類型”等定義。 +在這種情況下,要給出自由度的項作為參數給出(在下面的情況下,`T:Type`)。 以這種方式定義的補丁稱為全對稱補丁。 +如您所見,全對稱補丁正是一個返回補丁的函數,但它本身也可以被視為補丁。 ```python FnType T: Type = Patch(T -> T) @@ -197,15 +197,15 @@ FnType(T). assert (Int -> Int).type == Int ``` -## 结构补丁 +## 結構補丁 -此外,可以为满足特定结构的任何类型定义修复程序。 -但是,这比名义上的维修程序和类方法具有较低的优先级。 +此外,可以為滿足特定結構的任何類型定義修復程序。 +但是,這比名義上的維修程序和類方法具有較低的優先級。 -在定义结构修复程序时应使用仔细的设计,因为某些属性会因扩展而丢失,例如以下内容。 +在定義結構修復程序時應使用仔細的設計,因為某些屬性會因擴展而丟失,例如以下內容。 ```python -# 这不应该是 `Structural` +# 這不應該是 `Structural` Norm = Structural Patch {x = Int; y = Int} Norm. norm self = self::x**2 + self::y**2 @@ -218,5 +218,5 @@ assert Point3D.new({x = 1; y = 2; z = 3}).norm() == 14 # AssertionError: ```

- 上一页 | 下一页 + 上一頁 | 下一頁

diff --git a/doc/zh_TW/syntax/type/08_value.md b/doc/zh_TW/syntax/type/08_value.md index 1483139a..c4b8986b 100644 --- a/doc/zh_TW/syntax/type/08_value.md +++ b/doc/zh_TW/syntax/type/08_value.md @@ -1,6 +1,6 @@ -# 值类型 +# 值類型 -值类型是可以在编译时评估的 Erg 内置类型,具体来说: +值類型是可以在編譯時評估的 Erg 內置類型,具體來說: ```python Value = ( @@ -21,17 +21,17 @@ Value = ( ) ``` -应用于它们的值类型对象、常量和编译时子例程称为 __constant 表达式__。 +應用于它們的值類型對象、常量和編譯時子例程稱為 __constant 表達式__。 ```python 1, 1.0, 1+2im, True, None, "aaa", [1, 2, 3], Fib(12) ``` -小心子程序。子例程可能是也可能不是值类型。 -由于子程序的实质只是一个指针,因此可以将其视为一个值[1](#1),但是在编译不是子程序的东西时不能使用 在恒定的上下文中。 不是值类型,因为它没有多大意义。 +小心子程序。子例程可能是也可能不是值類型。 +由于子程序的實質只是一個指針,因此可以將其視為一個值[1](#1),但是在編譯不是子程序的東西時不能使用 在恒定的上下文中。 不是值類型,因為它沒有多大意義。 -将来可能会添加归类为值类型的类型。 +將來可能會添加歸類為值類型的類型。 --- -1 Erg 中的术语“值类型”与其他语言中的定义不同。 纯 Erg 语义中没有内存的概念,并且因为它被放置在堆栈上而说它是值类型,或者因为它实际上是一个指针而说它不是值类型是不正确的。 值类型仅表示它是“值”类型或其子类型。 [↩](#f1) +1 Erg 中的術語“值類型”與其他語言中的定義不同。 純 Erg 語義中沒有內存的概念,并且因為它被放置在堆棧上而說它是值類型,或者因為它實際上是一個指針而說它不是值類型是不正確的。 值類型僅表示它是“值”類型或其子類型。 [?](#f1) diff --git a/doc/zh_TW/syntax/type/09_attributive.md b/doc/zh_TW/syntax/type/09_attributive.md index 96cae23e..ec51fae5 100644 --- a/doc/zh_TW/syntax/type/09_attributive.md +++ b/doc/zh_TW/syntax/type/09_attributive.md @@ -1,9 +1,9 @@ -# 属性类型 +# 屬性類型 -属性类型是包含 Record 和 Dataclass、Patch、Module 等的类型。 -属于属性类型的类型不是值类型。 +屬性類型是包含 Record 和 Dataclass、Patch、Module 等的類型。 +屬于屬性類型的類型不是值類型。 -## 记录类型复合 +## 記錄類型復合 -可以展平复合的记录类型。 -例如,`{... {.name = Str; .age = Nat}; ... {.name = Str; .id = Nat}}` 变成 `{.name = Str; .age = 自然; .id = Nat}`。 \ No newline at end of file +可以展平復合的記錄類型。 +例如,`{... {.name = Str; .age = Nat}; ... {.name = Str; .id = Nat}}` 變成 `{.name = Str; .age = 自然; .id = Nat}`。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/10_interval.md b/doc/zh_TW/syntax/type/10_interval.md index 2ecd67e8..b699706c 100644 --- a/doc/zh_TW/syntax/type/10_interval.md +++ b/doc/zh_TW/syntax/type/10_interval.md @@ -1,22 +1,22 @@ -# 间隔类型 +# 間隔類型 -`Range` 对象最基本的用途是作为迭代器。 +`Range` 對象最基本的用途是作為迭代器。 ```python for! 0..9, i => print! i ``` -请注意,与 Python 不同,它包含一个结束编号。 +請注意,與 Python 不同,它包含一個結束編號。 -然而,这不仅仅用于 `Range` 对象。 也可以使用类型。 这种类型称为Interval类型。 +然而,這不僅僅用于 `Range` 對象。 也可以使用類型。 這種類型稱為Interval類型。 ```python i: 0..10 = 2 ``` -`Nat` 类型等价于 `0..= 3} ``` -当有多个 pred 时,可以用 `;` 或 `and` 或 `or` 分隔。 `;` 和 `and` 的意思是一样的。 +當有多個 pred 時,可以用 `;` 或 `and` 或 `or` 分隔。 `;` 和 `and` 的意思是一樣的。 `Odd` 的元素是 `1, 3, 5, 7, 9, ...`。 -它被称为细化类型,因为它的元素是现有类型的一部分,就好像它是细化一样。 +它被稱為細化類型,因為它的元素是現有類型的一部分,就好像它是細化一樣。 -`Pred` 被称为(左侧)谓词表达式。 和赋值表达式一样,它不返回有意义的值,左侧只能放置一个模式。 -也就是说,诸如`X**2 - 5X + 6 == 0`之类的表达式不能用作细化类型的谓词表达式。 在这方面,它不同于右侧的谓词表达式。 +`Pred` 被稱為(左側)謂詞表達式。 和賦值表達式一樣,它不返回有意義的值,左側只能放置一個模式。 +也就是說,諸如`X**2 - 5X + 6 == 0`之類的表達式不能用作細化類型的謂詞表達式。 在這方面,它不同于右側的謂詞表達式。 ```python -{X: Int | X**2 - 5X + 6 == 0} # 语法错误:谓词形式无效。 只有名字可以在左边 +{X: Int | X**2 - 5X + 6 == 0} # 語法錯誤:謂詞形式無效。 只有名字可以在左邊 ``` -如果你知道如何解二次方程,你会期望上面的细化形式等价于`{2, 3}`。 -但是,Erg 编译器对代数的了解很少,因此无法解决右边的谓词。 +如果你知道如何解二次方程,你會期望上面的細化形式等價于`{2, 3}`。 +但是,Erg 編譯器對代數的了解很少,因此無法解決右邊的謂詞。 ## 智能投射 -很高兴您定义了 `Odd`,但事实上,它看起来不能在文字之外使用太多。 要将普通 `Int` 对象中的奇数提升为 `Odd`,即将 `Int` 向下转换为 `Odd`,您需要传递 `Odd` 的构造函数。 -对于细化类型,普通构造函数 `.new` 可能会出现恐慌,并且有一个名为 `.try_new` 的辅助构造函数返回一个 `Result` 类型。 +很高興您定義了 `Odd`,但事實上,它看起來不能在文字之外使用太多。 要將普通 `Int` 對象中的奇數提升為 `Odd`,即將 `Int` 向下轉換為 `Odd`,您需要傳遞 `Odd` 的構造函數。 +對于細化類型,普通構造函數 `.new` 可能會出現恐慌,并且有一個名為 `.try_new` 的輔助構造函數返回一個 `Result` 類型。 ```python i = Odd.new (0..10).sample!() i: Odd # or Panic ``` -它也可以用作 `match` 中的类型说明。 +它也可以用作 `match` 中的類型說明。 ```python # i: 0..10 @@ -51,12 +51,12 @@ match i: log "i: Nat" ``` -但是,Erg 目前无法做出诸如“偶数”之类的子决策,因为它不是“奇数”等。 +但是,Erg 目前無法做出諸如“偶數”之類的子決策,因為它不是“奇數”等。 -## 枚举、区间和筛选类型 +## 枚舉、區間和篩選類型 -前面介绍的枚举/区间类型是细化类型的语法糖。 -`{a, b, ...}` 是 `{I: Typeof(a) | I == a 或 I == b 或 ... }`,并且 `a..b` 被去糖化为 `{I: Typeof(a) | 我 >= a 和我 <= b}`。 +前面介紹的枚舉/區間類型是細化類型的語法糖。 +`{a, b, ...}` 是 `{I: Typeof(a) | I == a 或 I == b 或 ... }`,并且 `a..b` 被去糖化為 `{I: Typeof(a) | 我 >= a 和我 <= b}`。 ```python {1, 2} == {I: Int | I == 1 or I == 2} @@ -64,12 +64,12 @@ match i: 1... <10 == {I: Int | I >= 1 and I < 10} ``` -## 细化模式 +## 細化模式 -正如 `_: {X}` 可以重写为 `X`(常量模式),`_: {X: T | Pred}` 可以重写为`X: T | Pred` +正如 `_: {X}` 可以重寫為 `X`(常量模式),`_: {X: T | Pred}` 可以重寫為`X: T | Pred` ```python -# 方法 `.m` 是为长度为 3 或更大的数组定义的 +# 方法 `.m` 是為長度為 3 或更大的數組定義的 Array(T, N | N >= 3) .m(&self) = ... ``` diff --git a/doc/zh_TW/syntax/type/13_algebraic.md b/doc/zh_TW/syntax/type/13_algebraic.md index 5567aafc..67d6bf97 100644 --- a/doc/zh_TW/syntax/type/13_algebraic.md +++ b/doc/zh_TW/syntax/type/13_algebraic.md @@ -1,37 +1,37 @@ -# 代数类型 +# 代數類型 -代数类型是通过将类型视为代数来操作类型而生成的类型。 -它们处理的操作包括Union、Intersection、Diff、Complement等。 -普通类只能进行Union,其他操作会导致类型错误。 +代數類型是通過將類型視為代數來操作類型而生成的類型。 +它們處理的操作包括Union、Intersection、Diff、Complement等。 +普通類只能進行Union,其他操作會導致類型錯誤。 -## 联合(Union) +## 聯合(Union) -联合类型可以为类型提供多种可能性。 顾名思义,它们是由“或”运算符生成的。 -一个典型的 Union 是 `Option` 类型。 `Option` 类型是 `T 或 NoneType` 补丁类型,主要表示可能失败的值。 +聯合類型可以為類型提供多種可能性。 顧名思義,它們是由“或”運算符生成的。 +一個典型的 Union 是 `Option` 類型。 `Option` 類型是 `T 或 NoneType` 補丁類型,主要表示可能失敗的值。 ```python IntOrStr = Int or Str assert dict.get("some key") in (Int or NoneType) -# 隐式变为 `T != NoneType` +# 隱式變為 `T != NoneType` Option T = T or NoneType ``` ## 路口 -交集类型是通过将类型与 `and` 操作组合得到的。 +交集類型是通過將類型與 `and` 操作組合得到的。 ```python Num = Add and Sub and Mul and Eq ``` -如上所述,普通类不能与“and”操作结合使用。 这是因为实例只属于一个类。 +如上所述,普通類不能與“and”操作結合使用。 這是因為實例只屬于一個類。 -## 差异 +## 差異 -Diff 类型是通过 `not` 操作获得的。 -最好使用 `and not` 作为更接近英文文本的符号,但建议只使用 `not`,因为它更适合与 `and` 和 `or` 一起使用。 +Diff 類型是通過 `not` 操作獲得的。 +最好使用 `and not` 作為更接近英文文本的符號,但建議只使用 `not`,因為它更適合與 `and` 和 `or` 一起使用。 ```python CompleteNum = Add and Sub and Mul and Div and Eq and Ord @@ -41,45 +41,45 @@ True = Bool not {False} OneTwoThree = {1, 2, 3, 4, 5, 6} - {4, 5, 6, 7, 8, 9, 10} ``` -## 补充 +## 補充 -补码类型是通过 `not` 操作得到的,这是一个一元操作。 `not T` 类型是 `{=} not T` 的简写。 -类型为“非 T”的交集等价于 Diff,类型为“非 T”的 Diff 等价于交集。 -但是,不推荐这种写法。 +補碼類型是通過 `not` 操作得到的,這是一個一元操作。 `not T` 類型是 `{=} not T` 的簡寫。 +類型為“非 T”的交集等價于 Diff,類型為“非 T”的 Diff 等價于交集。 +但是,不推薦這種寫法。 ```python -# 非零数类型的最简单定义 +# 非零數類型的最簡單定義 NonZero = Not {0} -# 不推荐使用的样式 +# 不推薦使用的樣式 {True} == Bool and not {False} # 1 == 2 + - 1 Bool == {True} not not {False} # 2 == 1 - -1 ``` -## 真代数类型 +## 真代數類型 -有两种代数类型:可以简化的表观代数类型和不能进一步简化的真实代数类型。 -“表观代数类型”包括 Enum、Interval 和 Record 类型的 `or` 和 `and`。 -这些不是真正的代数类型,因为它们被简化了,并且将它们用作类型说明符将导致警告; 要消除警告,您必须简化它们或定义它们的类型。 +有兩種代數類型:可以簡化的表觀代數類型和不能進一步簡化的真實代數類型。 +“表觀代數類型”包括 Enum、Interval 和 Record 類型的 `or` 和 `and`。 +這些不是真正的代數類型,因為它們被簡化了,并且將它們用作類型說明符將導致警告; 要消除警告,您必須簡化它們或定義它們的類型。 ```python assert {1, 2, 3} or {2, 3} == {1, 2, 3} assert {1, 2, 3} and {2, 3} == {2, 3} assert -2..-1 or 1..2 == {-2, -1, 1, 2} -i: {1, 2} or {3, 4} = 1 # 类型警告:{1, 2} 或 {3, 4} 可以简化为 {1, 2, 3, 4} +i: {1, 2} or {3, 4} = 1 # 類型警告:{1, 2} 或 {3, 4} 可以簡化為 {1, 2, 3, 4} p: {x = Int, ...} and {y = Int; ...} = {x = 1; y = 2; z = 3} -# 类型警告:{x = Int, ...} 和 {y = Int; ...} 可以简化为 {x = Int; y = 整数; ...} +# 類型警告:{x = Int, ...} 和 {y = Int; ...} 可以簡化為 {x = Int; y = 整數; ...} Point1D = {x = Int; ...} Point2D = Point1D and {y = Int; ...} # == {x = Int; y = Int; ...} q: Point2D = {x = 1; y = 2; z = 3} ``` -真正的代数类型包括类型“或”和“与”。 类之间的“或”等类属于“或”类型。 +真正的代數類型包括類型“或”和“與”。 類之間的“或”等類屬于“或”類型。 ```python assert Int or Str == Or(Int, Str) assert Int and Marker == And(Int, Marker) ``` -Diff, Complement 类型不是真正的代数类型,因为它们总是可以被简化。 +Diff, Complement 類型不是真正的代數類型,因為它們總是可以被簡化。 diff --git a/doc/zh_TW/syntax/type/14_dependent.md b/doc/zh_TW/syntax/type/14_dependent.md index 70ef8633..133b5bf4 100644 --- a/doc/zh_TW/syntax/type/14_dependent.md +++ b/doc/zh_TW/syntax/type/14_dependent.md @@ -1,10 +1,10 @@ -# 依赖类型 +# 依賴類型 -依赖类型是一个特性,可以说是 Erg 的最大特性。 -依赖类型是将值作为参数的类型。 普通的多态类型只能将类型作为参数,但依赖类型放宽了这个限制。 +依賴類型是一個特性,可以說是 Erg 的最大特性。 +依賴類型是將值作為參數的類型。 普通的多態類型只能將類型作為參數,但依賴類型放寬了這個限制。 -依赖类型等价于`[T; N]`(`数组(T,N)`)。 -这种类型不仅取决于内容类型“T”,还取决于内容数量“N”。 `N` 包含一个`Nat` 类型的对象。 +依賴類型等價于`[T; N]`(`數組(T,N)`)。 +這種類型不僅取決于內容類型“T”,還取決于內容數量“N”。 `N` 包含一個`Nat` 類型的對象。 ```python a1 = [1, 2, 3] @@ -14,7 +14,7 @@ assert a1 in [Nat; 4] assert a1 + a2 in [Nat; 7] ``` -如果函数参数中传递的类型对象与返回类型有关,则写: +如果函數參數中傳遞的類型對象與返回類型有關,則寫: ```python narray: |N: Nat| {N} -> [{N}; N] @@ -22,16 +22,16 @@ narray(N: Nat): [N; N] = [N; N] assert array(3) == [3, 3, 3] ``` -定义依赖类型时,所有类型参数都必须是常量。 +定義依賴類型時,所有類型參數都必須是常量。 -依赖类型本身存在于现有语言中,但 Erg 具有在依赖类型上定义过程方法的特性 +依賴類型本身存在于現有語言中,但 Erg 具有在依賴類型上定義過程方法的特性 ```python x=1 f x = print! f::x, module::x -# Phantom 类型有一个名为 Phantom 的属性,其值与类型参数相同 +# Phantom 類型有一個名為 Phantom 的屬性,其值與類型參數相同 T X: Int = Class Impl := Phantom X T(X). x self = self::Phantom @@ -39,19 +39,19 @@ T(X). T(1).x() # 1 ``` -可变依赖类型的类型参数可以通过方法应用程序进行转换。 -转换规范是用 `~>` 完成的 +可變依賴類型的類型參數可以通過方法應用程序進行轉換。 +轉換規范是用 `~>` 完成的 ```python -# 注意 `Id` 是不可变类型,不能转换 +# 注意 `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!() @@ -60,15 +60,15 @@ VM!("running" ~> "running").stop!ref!self = vm = VM!.new() vm.start!() vm.stop!() -vm.stop!() # 类型错误:VM!(!"stopped", 1) 没有 .stop!() +vm.stop!() # 類型錯誤:VM!(!"stopped", 1) 沒有 .stop!() # 提示:VM!(!"running", 1) 有 .stop!() ``` -您还可以嵌入或继承现有类型以创建依赖类型。 +您還可以嵌入或繼承現有類型以創建依賴類型。 ```python MyArray(T, N) = Inherit[T; N] -# self 的类型:Self(T, N) 与 .array 一起变化 +# self 的類型:Self(T, N) 與 .array 一起變化 MyStruct!(T, N: Nat!) = Class {.array: [T; !N]} ``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/15_quantified.md b/doc/zh_TW/syntax/type/15_quantified.md index fb4af5b7..a80193f5 100644 --- a/doc/zh_TW/syntax/type/15_quantified.md +++ b/doc/zh_TW/syntax/type/15_quantified.md @@ -1,14 +1,14 @@ -# 类型变量,量化类型 +# 類型變量,量化類型 -类型变量是用于例如指定子程序参数类型的变量,它的类型是任意的(不是单态的)。 -首先,作为引入类型变量的动机,考虑 `id` 函数,它按原样返回输入。 +類型變量是用于例如指定子程序參數類型的變量,它的類型是任意的(不是單態的)。 +首先,作為引入類型變量的動機,考慮 `id` 函數,它按原樣返回輸入。 ```python id x: Int = x ``` -返回输入的“id”函数是为“Int”类型定义的,但这个函数显然可以为任何类型定义。 -让我们使用 `Object` 来表示最大的类。 +返回輸入的“id”函數是為“Int”類型定義的,但這個函數顯然可以為任何類型定義。 +讓我們使用 `Object` 來表示最大的類。 ```python id x: Object = x @@ -18,16 +18,16 @@ s = id "foo" b = id True ``` -当然,它现在接受任意类型,但有一个问题:返回类型被扩展为 `Object`。 返回类型扩展为 `Object`。 -如果输入是“Int”类型,我想查看返回类型“Int”,如果输入是“Str”类型,我想查看“Str”。 +當然,它現在接受任意類型,但有一個問題:返回類型被擴展為 `Object`。 返回類型擴展為 `Object`。 +如果輸入是“Int”類型,我想查看返回類型“Int”,如果輸入是“Str”類型,我想查看“Str”。 ```python print! id 1 # -id(1) + 1 # 类型错误:无法添加 `Object` 和 `Int +id(1) + 1 # 類型錯誤:無法添加 `Object` 和 `Int ``` -要确保输入的类型与返回值的类型相同,请使用 __type 变量__。 -类型变量在`||`(类型变量列表)中声明。 +要確保輸入的類型與返回值的類型相同,請使用 __type 變量__。 +類型變量在`||`(類型變量列表)中聲明。 ```python id|T: Type| x: T = x @@ -36,12 +36,12 @@ assert id("foo") == "foo" assert id(True) == True ``` -这称为函数的 __universal quantification(泛化)__。 有细微的差别,但它对应于其他语言中称为泛型的函数。 泛化函数称为__多态函数__。 -定义一个多态函数就像为所有类型定义一个相同形式的函数(Erg 禁止重载,所以下面的代码真的不能写)。 +這稱為函數的 __universal quantification(泛化)__。 有細微的差別,但它對應于其他語言中稱為泛型的函數。 泛化函數稱為__多態函數__。 +定義一個多態函數就像為所有類型定義一個相同形式的函數(Erg 禁止重載,所以下面的代碼真的不能寫)。 ```python id|T: Type| x: T = x -# 伪代码 +# 偽代碼 id x: Int = x id x: Str = x id x: Bool = x @@ -50,23 +50,23 @@ id x: NoneType = x ... ``` -此外,类型变量“T”可以推断为“Type”类型,因为它在类型规范中使用。 所以 `|T: Type|` 可以简单地缩写为 `|T|`。 -你也可以省略`|T, N| 脚; N]` 如果可以推断它不是类型对象(`T: Type, N: Nat`)。 +此外,類型變量“T”可以推斷為“Type”類型,因為它在類型規范中使用。 所以 `|T: Type|` 可以簡單地縮寫為 `|T|`。 +你也可以省略`|T, N| 腳; N]` 如果可以推斷它不是類型對象(`T: Type, N: Nat`)。 -如果类型对于任意类型来说太大,您也可以提供约束。 -约束也有优势,例如,子类型规范允许使用某些方法。 +如果類型對于任意類型來說太大,您也可以提供約束。 +約束也有優勢,例如,子類型規范允許使用某些方法。 ```python # T <: Add -# => T 是 Add 的子类 +# => T 是 Add 的子類 # => 可以做加法 add|T <: Add| l: T, r: T = l + r ``` -在本例中,`T` 必须是`Add` 类型的子类,并且要分配的`l` 和`r` 的实际类型必须相同。 -在这种情况下,“T”由“Int”、“Ratio”等满足。因此,例如,“Int”和“Str”的添加没有定义,因此被拒绝。 +在本例中,`T` 必須是`Add` 類型的子類,并且要分配的`l` 和`r` 的實際類型必須相同。 +在這種情況下,“T”由“Int”、“Ratio”等滿足。因此,例如,“Int”和“Str”的添加沒有定義,因此被拒絕。 -您也可以像这样键入它。 +您也可以像這樣鍵入它。 ```python f| @@ -78,7 +78,7 @@ f| x + y + z + x ``` -如果注释列表很长,您可能需要预先声明它。 +如果注釋列表很長,您可能需要預先聲明它。 ```python f: |Y, Z: Type, X <: Add(Y, O1), O1 <: Add(Z, O2), O2 <: Add(X, O3)| (X, Y, Z) -> O3 @@ -86,13 +86,13 @@ f|X, Y, Z| x: X, y: Y, z: Z = x + y + z + x ``` -与许多具有泛型的语言不同,所有声明的类型变量都必须在临时参数列表(`x: X, y: Y, z: Z` 部分)或其他类型变量的参数中使用。 -这是 Erg 语言设计的一个要求,即所有类型变量都可以从真实参数中推断出来。 -因此,无法推断的信息,例如返回类型,是从真实参数传递的; Erg 允许从实参传递类型。 +與許多具有泛型的語言不同,所有聲明的類型變量都必須在臨時參數列表(`x: X, y: Y, z: Z` 部分)或其他類型變量的參數中使用。 +這是 Erg 語言設計的一個要求,即所有類型變量都可以從真實參數中推斷出來。 +因此,無法推斷的信息,例如返回類型,是從真實參數傳遞的; Erg 允許從實參傳遞類型。 ```python Iterator T = Trait { - # 从参数传递返回类型。 + # 從參數傳遞返回類型。 # .collect: |K: Type -> Type| Self(T). ({K}) -> K(T) .collect(self(T), K: Type -> Type): K(T) = ... ... @@ -102,7 +102,7 @@ it = [1, 2, 3].iter().map i -> i + 1 it.collect(Array) # [2, 3, 4]. ``` -类型变量只能在 `||` 期间声明。 但是,一旦声明,它们就可以在任何地方使用,直到它们退出作用域 +類型變量只能在 `||` 期間聲明。 但是,一旦聲明,它們就可以在任何地方使用,直到它們退出作用域 ```python f|X|(x: X): () = @@ -115,42 +115,42 @@ f 1 # ``` -您也可以在使用时明确单相如下 +您也可以在使用時明確單相如下 ```python f: Int -> Int = id|Int| ``` -在这种情况下,指定的类型优先于实际参数的类型(匹配失败将导致类型错误,即实际参数的类型错误)。 -即如果传递的实际对象可以转换为指定的类型,则进行转换; 否则会导致编译错误。 +在這種情況下,指定的類型優先于實際參數的類型(匹配失敗將導致類型錯誤,即實際參數的類型錯誤)。 +即如果傳遞的實際對象可以轉換為指定的類型,則進行轉換; 否則會導致編譯錯誤。 ```python assert id(1) == 1 assert id|Int|(1) in Int assert id|Ratio|(1) in Ratio -# 你也可以使用关键字参数 +# 你也可以使用關鍵字參數 assert id|T: Int|(1) == 1 -id|Int|("str") # 类型错误: id|Int| is type `Int -> Int`但得到了 Str +id|Int|("str") # 類型錯誤: id|Int| is type `Int -> Int`但得到了 Str ``` -当此语法与理解相冲突时,您需要将其括在 `()` 中。 +當此語法與理解相沖突時,您需要將其括在 `()` 中。 ```python -# {id|Int| x | x <- 1..10} 将被解释为 {id | ...} +# {id|Int| x | x <- 1..10} 將被解釋為 {id | ...} {(id|Int| x) | x <- 1..10} ``` -不能使用与已存在的类型相同的名称来声明类型变量。 这是因为所有类型变量都是常量。 +不能使用與已存在的類型相同的名稱來聲明類型變量。 這是因為所有類型變量都是常量。 ```python I: Type -# ↓ 无效类型变量,已经存在 +# ↓ 無效類型變量,已經存在 f|I: Type| ... = ... ``` -## 在方法定义中输入参数 +## 在方法定義中輸入參數 -默认情况下,左侧的类型参数被视为绑定变量。 +默認情況下,左側的類型參數被視為綁定變量。 ```python K(T: Type, N: Nat) = ... @@ -158,76 +158,76 @@ K(T, N). foo(x) = ... ``` -使用另一个类型变量名称将导致警告。 +使用另一個類型變量名稱將導致警告。 ```python K(T: Type, N: Nat) = ... -K(U, M). # 警告:K 的类型变量名是 'T' 和 'N' +K(U, M). # 警告:K 的類型變量名是 'T' 和 'N' foo(x) = ... ``` -自定义以来,所有命名空间中的常量都是相同的,因此它们当然不能用于类型变量名称 +自定義以來,所有命名空間中的常量都是相同的,因此它們當然不能用于類型變量名稱 ```python N = 1 -K(N: Nat) = ... # 名称错误:N 已定义 +K(N: Nat) = ... # 名稱錯誤:N 已定義 L(M: Nat) = ... -# 仅当 M == N == 1 时才定义 +# 僅當 M == N == 1 時才定義 L(N). foo(self, x) = ... -# 为任何定义 M: Nat +# 為任何定義 M: Nat L(M). .bar(self, x) = ... ``` -每个类型参数不能有多个定义,但可以定义具有相同名称的方法,因为未分配类型参数的依赖类型(非原始类型)和分配的依赖类型(原始类型)之间没有关系 )。 +每個類型參數不能有多個定義,但可以定義具有相同名稱的方法,因為未分配類型參數的依賴類型(非原始類型)和分配的依賴類型(原始類型)之間沒有關系 )。 ```python K(I: Int) = ... K. - # K 不是真正的类型(atomic Kind),所以我们不能定义方法 - # 这不是方法(更像是静态方法) + # K 不是真正的類型(atomic Kind),所以我們不能定義方法 + # 這不是方法(更像是靜態方法) foo(x) = ... K(0). foo(self, x): Nat = ... ``` -## 所有对称类型 +## 所有對稱類型 -上一节中定义的 `id` 函数是一个可以是任何类型的函数。 那么 `id` 函数本身的类型是什么? +上一節中定義的 `id` 函數是一個可以是任何類型的函數。 那么 `id` 函數本身的類型是什么? ```python print! classof(id) # |T: Type| T -> T ``` -我们得到一个类型`|T: Type| T -> T`。 这称为一个 __封闭的全称量化类型/全称类型__,即`['a. ...]'` 在 ML 和 `forall t. ...` 在 Haskell 中。 为什么使用形容词“关闭”将在下面讨论。 +我們得到一個類型`|T: Type| T -> T`。 這稱為一個 __封閉的全稱量化類型/全稱類型__,即`['a. ...]'` 在 ML 和 `forall t. ...` 在 Haskell 中。 為什么使用形容詞“關閉”將在下面討論。 -封闭的全称量化类型有一个限制:只有子程序类型可以被通用量化,即只有子程序类型可以放在左子句中。 但这已经足够了,因为子程序是 Erg 中最基本的控制结构,所以当我们说“我要处理任意 X”时,即我想要一个可以处理任意 X 的子程序。所以,量化类型具有相同的含义 作为多态函数类型。 从现在开始,这种类型基本上被称为多态函数类型。 +封閉的全稱量化類型有一個限制:只有子程序類型可以被通用量化,即只有子程序類型可以放在左子句中。 但這已經足夠了,因為子程序是 Erg 中最基本的控制結構,所以當我們說“我要處理任意 X”時,即我想要一個可以處理任意 X 的子程序。所以,量化類型具有相同的含義 作為多態函數類型。 從現在開始,這種類型基本上被稱為多態函數類型。 -与匿名函数一样,多态类型具有任意类型变量名称,但它们都具有相同的值。 +與匿名函數一樣,多態類型具有任意類型變量名稱,但它們都具有相同的值。 ```python assert (|T: Type| T -> T) == (|U: Type| U -> U) ``` -当存在 alpha 等价时,等式得到满足,就像在 lambda 演算中一样。 由于对类型的操作有一些限制,所以总是可以确定等价的(如果我们不考虑 stoppage 属性)。 +當存在 alpha 等價時,等式得到滿足,就像在 lambda 演算中一樣。 由于對類型的操作有一些限制,所以總是可以確定等價的(如果我們不考慮 stoppage 屬性)。 -## 多态函数类型的子类型化 +## 多態函數類型的子類型化 -多态函数类型可以是任何函数类型。 这意味着与任何函数类型都存在子类型关系。 让我们详细看看这种关系。 +多態函數類型可以是任何函數類型。 這意味著與任何函數類型都存在子類型關系。 讓我們詳細看看這種關系。 -类型变量在左侧定义并在右侧使用的类型,例如 `OpenFn T: Type = T -> T`,称为 __open 通用类型__。 -相反,在右侧定义和使用类型变量的类型,例如 `ClosedFn = |T: Type| T -> T`,被称为 __封闭的通用类型__。 +類型變量在左側定義并在右側使用的類型,例如 `OpenFn T: Type = T -> T`,稱為 __open 通用類型__。 +相反,在右側定義和使用類型變量的類型,例如 `ClosedFn = |T: Type| T -> T`,被稱為 __封閉的通用類型__。 -开放通用类型是所有同构“真”类型的超类型。 相反,封闭的通用类型是所有同构真类型的子类型。 +開放通用類型是所有同構“真”類型的超類型。 相反,封閉的通用類型是所有同構真類型的子類型。 ```python (|T: Type| T -> T) < (Int -> Int) < (T -> T) ``` -您可能还记得封闭的较小/开放的较大。 -但为什么会这样呢? 为了更好地理解,让我们考虑每个实例。 +您可能還記得封閉的較小/開放的較大。 +但為什么會這樣呢? 為了更好地理解,讓我們考慮每個實例。 ```python # id: |T: Type| T -> T @@ -236,7 +236,7 @@ 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 @@ -244,31 +244,31 @@ id_arbitrary_fn|T|(f1: T -> T): (T -> T) = f # 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) # 类型错误 +id_poly_fn(iid) # 類型錯誤 -# 按原样返回 Int 类型函数 +# 按原樣返回 Int 類型函數 id_int_fn(f3: Int -> Int): (Int -> Int) = f # id_int_fn(id) == id|Int| # id_int_fn(iid) == iid ``` -由于 `id` 是 `|T: Type| 类型T -> T`,可以赋值给`Int-> Int`类型的参数`f3`,我们可以考虑`(|T| T -> T) < (Int -> Int)`。 -反之,`Int -> Int`类型的`iid`不能赋值给`(|T| T -> T)`类型的参数`f2`,但可以赋值给`(|T| T -> T)`的参数`f1`输入 `T -> T`,所以 `(Int -> Int) < (T -> T)`。 -因此,确实是`(|T| T -> T) < (Int -> Int) < (T -> T)`。 +由于 `id` 是 `|T: Type| 類型T -> T`,可以賦值給`Int-> Int`類型的參數`f3`,我們可以考慮`(|T| T -> T) < (Int -> Int)`。 +反之,`Int -> Int`類型的`iid`不能賦值給`(|T| T -> T)`類型的參數`f2`,但可以賦值給`(|T| T -> T)`的參數`f1`輸入 `T -> T`,所以 `(Int -> Int) < (T -> T)`。 +因此,確實是`(|T| T -> T) < (Int -> Int) < (T -> T)`。 -## 量化类型和依赖类型 +## 量化類型和依賴類型 -依赖类型和量化类型(多态函数类型)之间有什么关系,它们之间有什么区别? -我们可以说依赖类型是一种接受参数的类型,而量化类型是一种赋予参数任意性的类型。 +依賴類型和量化類型(多態函數類型)之間有什么關系,它們之間有什么區別? +我們可以說依賴類型是一種接受參數的類型,而量化類型是一種賦予參數任意性的類型。 -重要的一点是封闭的多态类型本身没有类型参数。例如,多态函数类型`|T| T -> T` 是一个接受多态函数 __only__ 的类型,它的定义是封闭的。您不能使用其类型参数`T`来定义方法等。 +重要的一點是封閉的多態類型本身沒有類型參數。例如,多態函數類型`|T| T -> T` 是一個接受多態函數 __only__ 的類型,它的定義是封閉的。您不能使用其類型參數`T`來定義方法等。 -在 Erg 中,类型本身也是一个值,因此带参数的类型(例如函数类型)可能是依赖类型。换句话说,多态函数类型既是量化类型又是依赖类型。 +在 Erg 中,類型本身也是一個值,因此帶參數的類型(例如函數類型)可能是依賴類型。換句話說,多態函數類型既是量化類型又是依賴類型。 ```python PolyFn = Patch(|T| T -> T) PolyFn. - type self = T # 名称错误:找不到“T” + type self = T # 名稱錯誤:找不到“T” DepFn T = Patch(T -> T) DepFn. type self = diff --git a/doc/zh_TW/syntax/type/16_subtyping.md b/doc/zh_TW/syntax/type/16_subtyping.md index 86c44646..ebb4a6ae 100644 --- a/doc/zh_TW/syntax/type/16_subtyping.md +++ b/doc/zh_TW/syntax/type/16_subtyping.md @@ -1,6 +1,6 @@ -# 子类型 +# 子類型 -在 Erg 中,可以使用比较运算符 `<`、`>` 确定类包含。 +在 Erg 中,可以使用比較運算符 `<`、`>` 確定類包含。 ```python Nat < Int @@ -11,20 +11,20 @@ Int < Object {I: Int | I >= 1} < {I: Int | I >= 0} ``` -请注意,这与 `<:` 运算符的含义不同。 它声明左侧的类是右侧类型的子类型,并且仅在编译时才有意义。 +請注意,這與 `<:` 運算符的含義不同。 它聲明左側的類是右側類型的子類型,并且僅在編譯時才有意義。 ```python -C <: T # T: 结构类型 +C <: T # T: 結構類型 f|D <: E| ... assert F < G ``` -您还可以为多态子类型规范指定 `Self <: Add`,例如 `Self(R, O) <: Add(R, O)`。 +您還可以為多態子類型規范指定 `Self <: Add`,例如 `Self(R, O) <: Add(R, O)`。 -## 结构类型和类类型关系 +## 結構類型和類類型關系 -结构类型是结构类型的类型,如果它们具有相同的结构,则被认为是相同的对象。 +結構類型是結構類型的類型,如果它們具有相同的結構,則被認為是相同的對象。 ```python T = Structural {i = Int} @@ -36,23 +36,23 @@ assert t in T assert t in U ``` -相反,类是符号类型的类型,不能在结构上与类型和实例进行比较 +相反,類是符號類型的類型,不能在結構上與類型和實例進行比較 ```python C = Class {i = Int} D = Class {i = Int} -assert C == D # 类型错误:无法比较类 +assert C == D # 類型錯誤:無法比較類 c = C.new {i = 1} assert c in C assert not c in D ``` -## 子程序的子类型化 +## 子程序的子類型化 -子例程的参数和返回值只采用一个类。 -换句话说,您不能直接将结构类型或特征指定为函数的类型。 -必须使用部分类型规范将其指定为“作为该类型子类型的单个类”。 +子例程的參數和返回值只采用一個類。 +換句話說,您不能直接將結構類型或特征指定為函數的類型。 +必須使用部分類型規范將其指定為“作為該類型子類型的單個類”。 ```python # OK @@ -60,13 +60,13 @@ f1 x, y: Int = x + y # NG f2 x, y: Add = x + y # OK -# A 是一些具体的类 +# A 是一些具體的類 f3 x, y: A = x + y ``` -子程序中的类型推断也遵循此规则。 当子例程中的变量具有未指定的类型时,编译器首先检查它是否是其中一个类的实例,如果不是,则在特征范围内查找匹配项。 如果仍然找不到,则会发生编译错误。 此错误可以通过使用结构类型来解决,但由于推断匿名类型可能会给程序员带来意想不到的后果,因此它被设计为由程序员使用 `Structural` 显式指定。 +子程序中的類型推斷也遵循此規則。 當子例程中的變量具有未指定的類型時,編譯器首先檢查它是否是其中一個類的實例,如果不是,則在特征范圍內查找匹配項。 如果仍然找不到,則會發生編譯錯誤。 此錯誤可以通過使用結構類型來解決,但由于推斷匿名類型可能會給程序員帶來意想不到的后果,因此它被設計為由程序員使用 `Structural` 顯式指定。 -## 类向上转换 +## 類向上轉換 ```python i: Int diff --git a/doc/zh_TW/syntax/type/17_type_casting.md b/doc/zh_TW/syntax/type/17_type_casting.md index 5fd31369..010719ea 100644 --- a/doc/zh_TW/syntax/type/17_type_casting.md +++ b/doc/zh_TW/syntax/type/17_type_casting.md @@ -1,12 +1,12 @@ -# 投掷 +# 投擲 -## 向上转型 +## 向上轉型 -因为 Python 是一种使用鸭子类型的语言,所以没有强制转换的概念。没有必要向上转型,本质上也没有向下转型。 -但是,Erg 是静态类型的,因此有时必须进行强制转换。 -一个简单的例子是 `1 + 2.0`:`+`(Int, Ratio) 或 Int(<: Add(Ratio, Ratio)) 操作在 Erg 语言规范中没有定义。这是因为 `Int <: Ratio`,所以 1 向上转换为 1.0,即 Ratio 的一个实例。 +因為 Python 是一種使用鴨子類型的語言,所以沒有強制轉換的概念。沒有必要向上轉型,本質上也沒有向下轉型。 +但是,Erg 是靜態類型的,因此有時必須進行強制轉換。 +一個簡單的例子是 `1 + 2.0`:`+`(Int, Ratio) 或 Int(<: Add(Ratio, Ratio)) 操作在 Erg 語言規范中沒有定義。這是因為 `Int <: Ratio`,所以 1 向上轉換為 1.0,即 Ratio 的一個實例。 -~~ Erg扩展字节码在BINARY_ADD中增加了类型信息,此时类型信息为Ratio-Ratio。在这种情况下,BINARY_ADD 指令执行 Int 的转换,因此没有插入指定转换的特殊指令。因此,例如,即使您在子类中重写了某个方法,如果您将父类指定为类型,则会执行类型强制,并在父类的方法中执行该方法(在编译时执行名称修改以引用父母的方法)。编译器只执行类型强制验证和名称修改。运行时不强制转换对象(当前。可以实现强制转换指令以优化执行)。 ~~ +~~ Erg擴展字節碼在BINARY_ADD中增加了類型信息,此時類型信息為Ratio-Ratio。在這種情況下,BINARY_ADD 指令執行 Int 的轉換,因此沒有插入指定轉換的特殊指令。因此,例如,即使您在子類中重寫了某個方法,如果您將父類指定為類型,則會執行類型強制,并在父類的方法中執行該方法(在編譯時執行名稱修改以引用父母的方法)。編譯器只執行類型強制驗證和名稱修改。運行時不強制轉換對象(當前。可以實現強制轉換指令以優化執行)。 ~~ ```python @Inheritable @@ -16,7 +16,7 @@ Parent. Child = Inherit Parent Child. - # Override 需要 Override 装饰器 + # Override 需要 Override 裝飾器 @Override greet!() = print! "Hello from Child" @@ -25,11 +25,11 @@ greet! p: Parent = p.greet!() parent = Parent.new() child = Child.new() -parent # 来自Parent的问候! -child # 来自child的问候! +parent # 來自Parent的問候! +child # 來自child的問候! ``` -此行为不会造成与 Python 的不兼容。 首先,Python 没有指定变量的类型,所以可以这么说,所有的变量都是类型变量。 由于类型变量会选择它们可以适应的最小类型,因此如果您没有在 Erg 中指定类型,则可以实现与 Python 中相同的行为。 +此行為不會造成與 Python 的不兼容。 首先,Python 沒有指定變量的類型,所以可以這么說,所有的變量都是類型變量。 由于類型變量會選擇它們可以適應的最小類型,因此如果您沒有在 Erg 中指定類型,則可以實現與 Python 中相同的行為。 ```python @Inheritable @@ -46,11 +46,11 @@ greet! some = some.greet!() parent = Parent.new() child = Child.new() -parent # 来自Parent的问候! -child # 来自child的问候! +parent # 來自Parent的問候! +child # 來自child的問候! ``` -您还可以使用 `.from` 和 `.into`,它们会为相互继承的类型自动实现 +您還可以使用 `.from` 和 `.into`,它們會為相互繼承的類型自動實現 ```python assert 1 == 1.0 @@ -58,9 +58,9 @@ assert Ratio.from(1) == 1.0 assert 1.into() == 1.0 ``` -## 向下转型 +## 向下轉型 -由于向下转换通常是不安全的并且转换方法很重要,我们改为实现“TryFrom.try_from” +由于向下轉換通常是不安全的并且轉換方法很重要,我們改為實現“TryFrom.try_from” ```python IntTryFromFloat = Patch Int diff --git a/doc/zh_TW/syntax/type/18_mut.md b/doc/zh_TW/syntax/type/18_mut.md index 30f660a2..3bed2c2f 100644 --- a/doc/zh_TW/syntax/type/18_mut.md +++ b/doc/zh_TW/syntax/type/18_mut.md @@ -1,9 +1,9 @@ -# 可变类型 +# 可變類型 -> __Warning__:本节中的信息是旧的并且包含一些错误。 +> __Warning__:本節中的信息是舊的并且包含一些錯誤。 -默认情况下,Erg 中的所有类型都是不可变的,即它们的内部状态无法更新。 -但是你当然也可以定义可变类型。 变量类型用 `!` 声明。 +默認情況下,Erg 中的所有類型都是不可變的,即它們的內部狀態無法更新。 +但是你當然也可以定義可變類型。 變量類型用 `!` 聲明。 ```python Person! = Class({name = Str; age = Nat!}) @@ -12,12 +12,12 @@ Person!. inc_age!ref!self = self::name.update!old -> old + 1 ``` -准确地说,基类型是可变类型或包含可变类型的复合类型的类型必须在类型名称的末尾有一个“!”。 没有 `!` 的类型可以存在于同一个命名空间中,并被视为单独的类型。 -在上面的例子中,`.age` 属性是可变的,`.name` 属性是不可变的。 如果即使一个属性是可变的,那么整个属性也是可变的。 +準確地說,基類型是可變類型或包含可變類型的復合類型的類型必須在類型名稱的末尾有一個“!”。 沒有 `!` 的類型可以存在于同一個命名空間中,并被視為單獨的類型。 +在上面的例子中,`.age` 屬性是可變的,`.name` 屬性是不可變的。 如果即使一個屬性是可變的,那么整個屬性也是可變的。 -可变类型可以定义重写实例的过程方法,但具有过程方法并不一定使它们可变。 例如数组类型`[T; N]` 实现了一个 `sample!` 随机选择一个元素的方法,但当然不会破坏性地修改数组。 +可變類型可以定義重寫實例的過程方法,但具有過程方法并不一定使它們可變。 例如數組類型`[T; N]` 實現了一個 `sample!` 隨機選擇一個元素的方法,但當然不會破壞性地修改數組。 -对可变对象的破坏性操作主要是通过 .update! 方法完成的。 `.update!` 方法是一个高阶过程,它通过应用函数 `f` 来更新 `self` +對可變對象的破壞性操作主要是通過 .update! 方法完成的。 `.update!` 方法是一個高階過程,它通過應用函數 `f` 來更新 `self` ```python i = !1 @@ -25,7 +25,7 @@ i.update! old -> old + 1 assert i == 2 ``` -`.set!` 方法只是丢弃旧内容并用新值替换它。 .set!x = .update!_ -> x。 +`.set!` 方法只是丟棄舊內容并用新值替換它。 .set!x = .update!_ -> x。 ```python i = !1 @@ -33,14 +33,14 @@ i.set! 2 assert i == 2 ``` -`.freeze_map` 方法对不变的值进行操作 +`.freeze_map` 方法對不變的值進行操作 ```python a = [1, 2, 3].into [Nat; !3] x = a.freeze_map a: [Nat; 3] -> a.iter().map(i -> i + 1).filter(i -> i % 2 == 0).collect(Array) ``` -在多态不可变类型中,该类型的类型参数“T”被隐式假定为不可变。 +在多態不可變類型中,該類型的類型參數“T”被隱式假定為不可變。 ```python # ImmutType < Type @@ -48,29 +48,29 @@ KT: ImmutType = Class ... K!T: Type = Class ... ``` -在标准库中,变量 `(...)!` 类型通常基于不可变 `(...)` 类型。 但是,`T!` 和 `T` 类型没有特殊的语言关系,并且不能这样构造 [1](#1) 。 +在標準庫中,變量 `(...)!` 類型通常基于不可變 `(...)` 類型。 但是,`T!` 和 `T` 類型沒有特殊的語言關系,并且不能這樣構造 [1](#1) 。 -请注意,有几种类型的对象可变性。 -下面我们将回顾内置集合类型的不可变/可变语义。 +請注意,有幾種類型的對象可變性。 +下面我們將回顧內置集合類型的不可變/可變語義。 ```python -# 数组类型 -## 不可变类型 -[T; N] # 不能执行可变操作 -## 可变类型 -[T; N] # 可以一一改变内容 -[T; !N] # 可变长度,内容不可变但可以通过添加/删除元素来修改 -[!T; N] # 内容是不可变的对象,但是可以替换成不同的类型(实际上可以通过不改变类型来替换) -[!T; !N] # 类型和长度可以改变 -[T; !N] # 内容和长度可以改变 -[!T!; N] # 内容和类型可以改变 -[!T!; !N] # 可以执行各种可变操作 +# 數組類型 +## 不可變類型 +[T; N] # 不能執行可變操作 +## 可變類型 +[T; N] # 可以一一改變內容 +[T; !N] # 可變長度,內容不可變但可以通過添加/刪除元素來修改 +[!T; N] # 內容是不可變的對象,但是可以替換成不同的類型(實際上可以通過不改變類型來替換) +[!T; !N] # 類型和長度可以改變 +[T; !N] # 內容和長度可以改變 +[!T!; N] # 內容和類型可以改變 +[!T!; !N] # 可以執行各種可變操作 ``` -当然,您不必全部记住和使用它们。 -对于可变数组类型,只需将 `!` 添加到您想要可变的部分,实际上是 `[T; N]`, `[T!; N]`,`[T; !N]`, ` [T!; !N]` 可以涵盖大多数情况。 +當然,您不必全部記住和使用它們。 +對于可變數組類型,只需將 `!` 添加到您想要可變的部分,實際上是 `[T; N]`, `[T!; N]`,`[T; !N]`, ` [T!; !N]` 可以涵蓋大多數情況。 -这些数组类型是语法糖,实际类型是: +這些數組類型是語法糖,實際類型是: ```python # actually 4 types @@ -83,7 +83,7 @@ K!T: Type = Class ... [!T!; !N] = ArrayWithMutTypeAndLength!(!T!, !N) ``` -这就是能够改变类型的意思。 +這就是能夠改變類型的意思。 ```python a = [1, 2, 3].into [!Nat; 3] @@ -91,73 +91,73 @@ a.map!(_ -> "a") a: [!Str; 3] ``` -其他集合类型也是如此。 +其他集合類型也是如此。 ```python -# 元组类型 -## 不可变类型 -(T, U) # 元素个数不变,内容不能变 -## 可变类型 -(T!, U) # 元素个数不变,第一个元素可以改变 -(T,U)! # 元素个数不变,内容可以替换 +# 元組類型 +## 不可變類型 +(T, U) # 元素個數不變,內容不能變 +## 可變類型 +(T!, U) # 元素個數不變,第一個元素可以改變 +(T,U)! # 元素個數不變,內容可以替換 ... ``` ```python -# 设置类型 -## 不可变类型 -{T; N} # 不可变元素个数,内容不能改变 -## 可变类型 -{T!; N} # 不可变元素个数,内容可以改变(一个一个) -{T; N}! # 可变元素个数,内容不能改变 -{T!; N}! # 可变元素个数,内容可以改变 +# 設置類型 +## 不可變類型 +{T; N} # 不可變元素個數,內容不能改變 +## 可變類型 +{T!; N} # 不可變元素個數,內容可以改變(一個一個) +{T; N}! # 可變元素個數,內容不能改變 +{T!; N}! # 可變元素個數,內容可以改變 ... ``` ```python -# 字典类型 -## 不可变类型 -{K: V} # 长度不可变,内容不能改变 -## 可变类型 -{K:V!} # 恒定长度,值可以改变(一一) -{K:V}! # 可变长度,内容不能改变,但可以通过添加或删除元素来增加或删除,内容类型也可以改变 +# 字典類型 +## 不可變類型 +{K: V} # 長度不可變,內容不能改變 +## 可變類型 +{K:V!} # 恒定長度,值可以改變(一一) +{K:V}! # 可變長度,內容不能改變,但可以通過添加或刪除元素來增加或刪除,內容類型也可以改變 ... ``` ```python -# 记录类型 -## 不可变类型 -{x = Int; y = Str} # 内容不能改变 -## 可变类型 -{x = Int!; y = Str} # 可以改变x的值 -{x = Int; y = Str}! # 替换 {x = Int; 的任何实例 y = Str} +# 記錄類型 +## 不可變類型 +{x = Int; y = Str} # 內容不能改變 +## 可變類型 +{x = Int!; y = Str} # 可以改變x的值 +{x = Int; y = Str}! # 替換 {x = Int; 的任何實例 y = Str} ... ``` -一个类型 `(...)` 简单地变成了 `T! = (...)!` 当 `T = (...)` 被称为简单结构化类型。 简单的结构化类型也可以(语义上)说是没有内部结构的类型。 -数组、元组、集合、字典和记录类型都是非简单的结构化类型,但 Int 和 Sieve 类型是。 +一個類型 `(...)` 簡單地變成了 `T! = (...)!` 當 `T = (...)` 被稱為簡單結構化類型。 簡單的結構化類型也可以(語義上)說是沒有內部結構的類型。 +數組、元組、集合、字典和記錄類型都是非簡單的結構化類型,但 Int 和 Sieve 類型是。 ```python -#筛子类型 -## 枚举 +#篩子類型 +## 枚舉 {1, 2, 3} # 1, 2, 3 之一,不可更改 {1、2、3}! # 1、2、3,可以改 -##区间类型 +##區間類型 1..12 #1到12,不能改 -1..12! # 1-12中的任意一个,你可以改变 -##筛型(普通型) -{I: Int | I % 2 == 0} #偶数类型,不可变 -{I: Int | I % 2 == 0} #偶数类型,可以改变 -{I: Int | I % 2 == 0}! # 与上面完全相同的类型,但上面的表示法是首选 +1..12! # 1-12中的任意一個,你可以改變 +##篩型(普通型) +{I: Int | I % 2 == 0} #偶數類型,不可變 +{I: Int | I % 2 == 0} #偶數類型,可以改變 +{I: Int | I % 2 == 0}! # 與上面完全相同的類型,但上面的表示法是首選 ``` -从上面的解释来看,可变类型不仅包括自身可变的,还包括内部类型可变的。 -诸如 `{x: Int!}` 和 `[Int!; 之类的类型3]` 是内部可变类型,其中内部的对象是可变的,而实例本身是不可变的。 +從上面的解釋來看,可變類型不僅包括自身可變的,還包括內部類型可變的。 +諸如 `{x: Int!}` 和 `[Int!; 之類的類型3]` 是內部可變類型,其中內部的對象是可變的,而實例本身是不可變的。 -对于具有内部结构并在类型构造函数本身上具有 `!` 的类型 `K!(T, U)`,`*self` 可以更改整个对象。也可以进行局部更改。 -但是,希望尽可能保持本地更改权限,因此如果只能更改 `T`,最好使用 `K(T!, U)`。 -而对于没有内部结构的类型‘T!’,这个实例只是一个可以交换的‘T’盒子。方法不能更改类型。 +對于具有內部結構并在類型構造函數本身上具有 `!` 的類型 `K!(T, U)`,`*self` 可以更改整個對象。也可以進行局部更改。 +但是,希望盡可能保持本地更改權限,因此如果只能更改 `T`,最好使用 `K(T!, U)`。 +而對于沒有內部結構的類型‘T!’,這個實例只是一個可以交換的‘T’盒子。方法不能更改類型。 --- -1 `T!` 和 `T` 类型没有特殊的语言关系是有意的。这是一个设计。如果存在关系,例如命名空间中存在`T`/`T!`类型,则无法从其他模块引入`T!`/`T`类型。此外,可变类型不是为不可变类型唯一定义的。给定定义 `T = (U, V)`,`T!` 的可能变量子类型是 `(U!, V)` 和 `(U, V!)`。[↩](#f1) \ No newline at end of file +1 `T!` 和 `T` 類型沒有特殊的語言關系是有意的。這是一個設計。如果存在關系,例如命名空間中存在`T`/`T!`類型,則無法從其他模塊引入`T!`/`T`類型。此外,可變類型不是為不可變類型唯一定義的。給定定義 `T = (U, V)`,`T!` 的可能變量子類型是 `(U!, V)` 和 `(U, V!)`。[?](#f1) \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/19_bound.md b/doc/zh_TW/syntax/type/19_bound.md index d6aecf50..54a09032 100644 --- a/doc/zh_TW/syntax/type/19_bound.md +++ b/doc/zh_TW/syntax/type/19_bound.md @@ -1,13 +1,13 @@ -# 类型绑定 +# 類型綁定 -类型边界为类型规范添加条件。 实现这一点的函数是守卫(守卫子句)。 -此功能可用于函数签名、匿名函数签名以及筛选类型。 -守卫写在返回类型之后。 +類型邊界為類型規范添加條件。 實現這一點的函數是守衛(守衛子句)。 +此功能可用于函數簽名、匿名函數簽名以及篩選類型。 +守衛寫在返回類型之后。 -## 谓词 +## 謂詞 -您可以使用返回 `Bool` 的表达式(谓词表达式)指定变量满足的条件。 -只能使用 [值对象](./08_value.md) 和运算符。 未来版本可能会支持编译时函数 +您可以使用返回 `Bool` 的表達式(謂詞表達式)指定變量滿足的條件。 +只能使用 [值對象](./08_value.md) 和運算符。 未來版本可能會支持編譯時函數 ```python f a: [T; N] | T, N, N > 5 = ... diff --git a/doc/zh_TW/syntax/type/advanced.md b/doc/zh_TW/syntax/type/advanced.md index 01dd89dc..d4abf310 100644 --- a/doc/zh_TW/syntax/type/advanced.md +++ b/doc/zh_TW/syntax/type/advanced.md @@ -1 +1 @@ -下面,我们将讨论更高级的类型系统。 初学者不必阅读所有部分。 \ No newline at end of file +下面,我們將討論更高級的類型系統。 初學者不必閱讀所有部分。 \ 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 index 8210a9dd..4bb7763a 100644 --- a/doc/zh_TW/syntax/type/advanced/GADTs.md +++ b/doc/zh_TW/syntax/type/advanced/GADTs.md @@ -1,6 +1,6 @@ -# 广义代数数据类型 (GADT) +# 廣義代數數據類型 (GADT) -Erg 可以通过对 Or 类型进行分类来创建广义代数数据类型 (GADT)。 +Erg 可以通過對 Or 類型進行分類來創建廣義代數數據類型 (GADT)。 ```python Nil T = Class(Impl := Phantom T) @@ -15,18 +15,18 @@ List. {nil; cons; ...} = List print! cons(1, cons(2, nil())).head() # 1 -print! nil.head() # 运行时错误:“空list” +print! nil.head() # 運行時錯誤:“空list” ``` -我们说 `List.nil|T|() = ...` 而不是 `List(T).nil() = ...` 的原因是我们在使用它时不需要指定类型。 +我們說 `List.nil|T|() = ...` 而不是 `List(T).nil() = ...` 的原因是我們在使用它時不需要指定類型。 ```python i = List.nil() _: List Int = cons 1, i ``` -这里定义的 `List T` 是 GADTs,但它是一个幼稚的实现,并没有显示 GADTs 的真正价值。 -例如,上面的 .head 方法会在 body 为空时抛出运行时错误,但是这个检查可以在编译时进行。 +這里定義的 `List T` 是 GADTs,但它是一個幼稚的實現,并沒有顯示 GADTs 的真正價值。 +例如,上面的 .head 方法會在 body 為空時拋出運行時錯誤,但是這個檢查可以在編譯時進行。 ```python List: (Type, {"Empty", "Nonempty"}) -> Type @@ -40,11 +40,11 @@ List(T, "Nonempty"). {nil; cons; ...} = List print! cons(1, cons(2, nil())).head() # 1 -print! nil().head() # 类型错误 +print! nil().head() # 類型錯誤 ``` -街上经常解释的 GADT 的一个例子是一个列表,可以像上面那样通过类型来判断内容是否为空。 -Erg 可以进一步细化以定义一个有长度的列表。 +街上經常解釋的 GADT 的一個例子是一個列表,可以像上面那樣通過類型來判斷內容是否為空。 +Erg 可以進一步細化以定義一個有長度的列表。 ```python List: (Type, Nat) -> Type @@ -60,7 +60,7 @@ List(_, N | N >= 2). {nil; cons; ...} = List print! cons(1, cons(2, nil)).pair() # [1, 2] -print! cons(1, nil).pair() # 类型错误 +print! cons(1, nil).pair() # 類型錯誤 print! cons(1, nil).head() # 1 -print! nil. head() # 类型错误 +print! nil. head() # 類型錯誤 ``` \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/_rank2type.md b/doc/zh_TW/syntax/type/advanced/_rank2type.md index 596df334..f6ab52ee 100644 --- a/doc/zh_TW/syntax/type/advanced/_rank2type.md +++ b/doc/zh_TW/syntax/type/advanced/_rank2type.md @@ -1,29 +1,29 @@ -# rank-2 多态性 +# rank-2 多態性 -> __Warning__:本文档已过时,一般包含错误。 +> __Warning__:本文檔已過時,一般包含錯誤。 -Erg 允许您定义接受各种类型的函数,例如 `id|T|(x: T): T = x`,即多相关。 -那么,我们可以定义一个接受多相关的函数吗? -比如这样的函数(注意这个定义是错误的): +Erg 允許您定義接受各種類型的函數,例如 `id|T|(x: T): T = x`,即多相關。 +那么,我們可以定義一個接受多相關的函數嗎? +比如這樣的函數(注意這個定義是錯誤的): ```python # 我想要 tuple_map(i -> i * 2, (1, "a")) == (2, "aa") tuple_map|T|(f: T -> T, tup: (Int, Str)): (Int, Str) = (f(tup.0), f(tup.1)) ``` -注意 `1` 和 `"a"` 有不同的类型,所以匿名函数一次不是单态的。 需要单相两次。 -这样的函数不能在我们目前讨论的类型范围内定义。 这是因为类型变量没有范围的概念。 -让我们暂时离开类型,看看值级别的范围概念。 +注意 `1` 和 `"a"` 有不同的類型,所以匿名函數一次不是單態的。 需要單相兩次。 +這樣的函數不能在我們目前討論的類型范圍內定義。 這是因為類型變量沒有范圍的概念。 +讓我們暫時離開類型,看看值級別的范圍概念。 ```python arr = [1, 2, 3] arr.map i -> i + 1 ``` -上面代码中的 `arr` 和 `i` 是不同作用域的变量。 因此,每个寿命都是不同的(`i` 更短)。 +上面代碼中的 `arr` 和 `i` 是不同作用域的變量。 因此,每個壽命都是不同的(`i` 更短)。 -到目前为止,所有类型变量的类型都具有相同的生命周期。 换句话说,‘T’、‘X’和‘Y’必须同时确定,之后保持不变。 -反之,如果我们可以将 `T` 视为“内部作用域”中的类型变量,我们可以组成一个 `tuple_map` 函数。 __Rank 2 type__ 就是为此目的而准备的。 +到目前為止,所有類型變量的類型都具有相同的生命周期。 換句話說,‘T’、‘X’和‘Y’必須同時確定,之后保持不變。 +反之,如果我們可以將 `T` 視為“內部作用域”中的類型變量,我們可以組成一個 `tuple_map` 函數。 __Rank 2 type__ 就是為此目的而準備的。 ```python # tuple_map: ((|T: Type| T -> T), (Int, Str)) -> (Int, Str) @@ -31,26 +31,26 @@ tuple_map f: (|T: Type| T -> T), tup: (Int, Str) = (f(tup.0), f(tup.1)) assert tuple_map(i -> i * 2, (1, "a")) == (2, "aa") ``` -`{(type) | 形式的类型 (类型变量列表)}` 被称为通用类型(详见[通用类型](./../quantified.md))。 -目前我们看到的`id`函数是一个典型的通用函数=多相关函数。 +`{(type) | 形式的類型 (類型變量列表)}` 被稱為通用類型(詳見[通用類型](./../quantified.md))。 +目前我們看到的`id`函數是一個典型的通用函數=多相關函數。 ```python id x = x id: |T: Type| T -> T ``` -通用类型与函数类型构造函数`->`的关联有特殊的规则,根据关联的方式,类型的语义是完全不同的。 +通用類型與函數類型構造函數`->`的關聯有特殊的規則,根據關聯的方式,類型的語義是完全不同的。 -用简单的单参数函数来考虑这一点。 +用簡單的單參數函數來考慮這一點。 ```python -f1: (T -> T) -> 整数 | T # 接受任何函数并返回 Int 的函数 -f2: (|T: Type| T -> T) -> Int # 接收多相关并返回 Int 的函数 -f3: Int -> (|T: Type| T -> T) # 一个函数,接受一个 Int 并返回一个封闭的通用函数 -f4: |T: Type|(Int -> (T -> T)) # 同上(首选) +f1: (T -> T) -> 整數 | T # 接受任何函數并返回 Int 的函數 +f2: (|T: Type| T -> T) -> Int # 接收多相關并返回 Int 的函數 +f3: Int -> (|T: Type| T -> T) # 一個函數,接受一個 Int 并返回一個封閉的通用函數 +f4: |T: Type|(Int -> (T -> T)) # 同上(首選) ``` -`f1` 和 `f2` 不同,而 `f3` 和 `f4` 相同,这似乎很奇怪。 让我们实际构造一个这种类型的函数。 +`f1` 和 `f2` 不同,而 `f3` 和 `f4` 相同,這似乎很奇怪。 讓我們實際構造一個這種類型的函數。 ```python # id: |T: Type| T -> T @@ -83,21 +83,21 @@ g2: Int -> Int = take_i_and_return_arbit_f|Int|(1) assert f2 == g2 ``` -开放的多相关函数类型具体称为 __任意函数类型__。 任意函数类型有无数种可能性:`Int -> Int`、`Str -> Str`、`Bool -> Bool`、`|T: Type| T -> T`, ... 是。 -另一方面,只有一个封闭的(返回与参数相同类型的对象)多态类型`|T:Type| T -> T`。 这种类型被专门称为 __多态函数类型__。 -也就是说,`f1`可以通过`x: Int -> x+1`、`x: Bool -> not x`、`x -> x`等=`f1`是一个多相关数是的, 但是您只能将 `x -> x` 等传递给 `f2` = `f2` 不是 __多元相关__。 -但是像`f2`这样的函数类型明显不同于普通类型,我们需要新的概念来处理它们。 那是类型的“等级”。 +開放的多相關函數類型具體稱為 __任意函數類型__。 任意函數類型有無數種可能性:`Int -> Int`、`Str -> Str`、`Bool -> Bool`、`|T: Type| T -> T`, ... 是。 +另一方面,只有一個封閉的(返回與參數相同類型的對象)多態類型`|T:Type| T -> T`。 這種類型被專門稱為 __多態函數類型__。 +也就是說,`f1`可以通過`x: Int -> x+1`、`x: Bool -> not x`、`x -> x`等=`f1`是一個多相關數是的, 但是您只能將 `x -> x` 等傳遞給 `f2` = `f2` 不是 __多元相關__。 +但是像`f2`這樣的函數類型明顯不同于普通類型,我們需要新的概念來處理它們。 那是類型的“等級”。 -关于rank的定义,没有量化的类型,如`Int`、`Str`、`Bool`、`T`、`Int -> Int`、`Option Int`等,都被视为“rank” 0”。 +關于rank的定義,沒有量化的類型,如`Int`、`Str`、`Bool`、`T`、`Int -> Int`、`Option Int`等,都被視為“rank” 0”。 ```python -# K 是多项式类型,例如 Option +# K 是多項式類型,例如 Option R0 = (Int or Str or Bool or ...) or (R0 -> R0) or K(R0) ``` -接下来,具有一阶全称的类型,例如`|T| T -> T`,或者在返回值类型中包含它们的类型是“rank 1”。 -此外,具有二阶全称量化的类型(具有 rank 1 类型作为参数的类型,例如 `(|T| T -> T) -> Int`)或将它们包含在返回类型中的类型称为“rank 2 ”。 -重复上述以定义“Rank N”类型。 此外,秩-N 类型包括秩为N 或更少的所有类型。 因此,混合等级的类型与其中最高的等级相同。 +接下來,具有一階全稱的類型,例如`|T| T -> T`,或者在返回值類型中包含它們的類型是“rank 1”。 +此外,具有二階全稱量化的類型(具有 rank 1 類型作為參數的類型,例如 `(|T| T -> T) -> Int`)或將它們包含在返回類型中的類型稱為“rank 2 ”。 +重復上述以定義“Rank N”類型。 此外,秩-N 類型包括秩為N 或更少的所有類型。 因此,混合等級的類型與其中最高的等級相同。 ```python R1 = (|...| R0) or (R0 -> R1) or K(R1) or R0 @@ -106,7 +106,7 @@ R2 = (|...| R1) or (R1 -> R2) or K(R2) or R1 Rn = (|...| Rn-1) or (Rn-1 -> Rn) or K(Rn) or Rn-1 ``` -让我们看看例子: +讓我們看看例子: ```python (|T: Type| T -> T) -> (|U: Type| U -> U) @@ -120,7 +120,7 @@ Option(|T: Type| T -> T) => R1 ``` -根据定义,`tuple_map` 是 rank-2 类型。 +根據定義,`tuple_map` 是 rank-2 類型。 ```python tuple_map: @@ -130,13 +130,13 @@ tuple_map: => R2 ``` -Erg 最多可以处理 rank 2 的类型(因为 rank N 类型包括所有 rank N 或更少的类型,确切地说,所有 Erg 类型都是 rank 2 类型)。 试图构造更多类型的函数是错误的。 -例如,所有处理多相关的函数都需要指定其他参数类型。 而且,这样的功能是不可配置的。 +Erg 最多可以處理 rank 2 的類型(因為 rank N 類型包括所有 rank N 或更少的類型,確切地說,所有 Erg 類型都是 rank 2 類型)。 試圖構造更多類型的函數是錯誤的。 +例如,所有處理多相關的函數都需要指定其他參數類型。 而且,這樣的功能是不可配置的。 ```python -# 这是一个 rank-3 类型的函数 +# 這是一個 rank-3 類型的函數 # |X, Y: Type|((|T: Type| T -> T), (X, Y)) -> (X, Y) generic_tuple_map|X, Y: Type| f: (|T: Type| T -> T), tup: (X, Y) = (f(tup.0), f(tup.1)) ``` -众所周知,具有 3 级或更高等级的类型在理论上无法通过类型推断来确定。 然而,大多数实际需求可以被等级 2 类型覆盖。 \ No newline at end of file +眾所周知,具有 3 級或更高等級的類型在理論上無法通過類型推斷來確定。 然而,大多數實際需求可以被等級 2 類型覆蓋。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/default_param.md b/doc/zh_TW/syntax/type/advanced/default_param.md index 34b2a88d..7348b947 100644 --- a/doc/zh_TW/syntax/type/advanced/default_param.md +++ b/doc/zh_TW/syntax/type/advanced/default_param.md @@ -1,6 +1,6 @@ -# 带默认参数的函数类型 +# 帶默認參數的函數類型 -首先,让我们看一个使用默认参数的示例。 +首先,讓我們看一個使用默認參數的示例。 ```python f: (Int, Int, z := Int) -> Int @@ -16,13 +16,13 @@ assert fold(f, [1, 2, 3]) == 6 assert fold(g, [1, 2, 3]) == 8 ``` -`:=` 之后的参数是默认参数。 -子类型规则如下: +`:=` 之后的參數是默認參數。 +子類型規則如下: ```python ((X, y := Y) -> Z) <: (X -> Z) ((X, y := Y, ...) -> Z) <: ((X, ...) -> Z) ``` -第一个意味着可以用没有默认参数的函数来识别具有默认参数的函数。 -第二个意味着可以省略任何默认参数。 \ No newline at end of file +第一個意味著可以用沒有默認參數的函數來識別具有默認參數的函數。 +第二個意味著可以省略任何默認參數。 \ 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 index 99532ba9..7dbf7ed3 100644 --- a/doc/zh_TW/syntax/type/advanced/erasure.md +++ b/doc/zh_TW/syntax/type/advanced/erasure.md @@ -1,43 +1,43 @@ -# 类型擦除 +# 類型擦除 -类型擦除是将类型参数设置为 `_` 并故意丢弃其信息的过程。类型擦除是许多多态语言的特性,但在 Erg 的语法上下文中,将其称为类型参数擦除更为准确。 +類型擦除是將類型參數設置為 `_` 并故意丟棄其信息的過程。類型擦除是許多多態語言的特性,但在 Erg 的語法上下文中,將其稱為類型參數擦除更為準確。 -类型擦除的最常见示例是 `[T, _]`。数组在编译时并不总是知道它们的长度。例如,引用命令行参数的 `sys.argv` 的类型为 `[Str, _]`。由于 Erg 的编译器无法知道命令行参数的长度,因此必须放弃有关其长度的信息。 -然而,一个已经被类型擦除的类型变成了一个未被擦除的类型的超类型(例如`[T; N] <: [T; _]`),所以它可以接受更多的对象。 -类型的对象`[T; N]` 当然可以使用 `[T; _]`,但使用后会删除`N`信息。如果长度没有改变,那么可以使用`[T; N]` 在签名中。如果长度保持不变,则必须由签名指示。 +類型擦除的最常見示例是 `[T, _]`。數組在編譯時并不總是知道它們的長度。例如,引用命令行參數的 `sys.argv` 的類型為 `[Str, _]`。由于 Erg 的編譯器無法知道命令行參數的長度,因此必須放棄有關其長度的信息。 +然而,一個已經被類型擦除的類型變成了一個未被擦除的類型的超類型(例如`[T; N] <: [T; _]`),所以它可以接受更多的對象。 +類型的對象`[T; N]` 當然可以使用 `[T; _]`,但使用后會刪除`N`信息。如果長度沒有改變,那么可以使用`[T; N]` 在簽名中。如果長度保持不變,則必須由簽名指示。 ```python -# 保证不改变数组长度的函数(例如,排序) -f: [T; N] -> [T; N] # 没有的函数 (f: [T; N]) -# 没有的功能(例如过滤器) +# 保證不改變數組長度的函數(例如,排序) +f: [T; N] -> [T; N] # 沒有的函數 (f: [T; N]) +# 沒有的功能(例如過濾器) g: [T; n] -> [T; _] ``` -如果您在类型规范本身中使用 `_`,则类型将向上转换为 `Object`。 -对于非类型类型参数(Int、Bool 等),带有 `_` 的参数将是未定义的。 +如果您在類型規范本身中使用 `_`,則類型將向上轉換為 `Object`。 +對于非類型類型參數(Int、Bool 等),帶有 `_` 的參數將是未定義的。 ```python i: _ # i: Object [_; _] == [Object; _] == Array ``` -类型擦除与省略类型说明不同。 一旦类型参数信息被删除,除非您再次声明它,否则它不会被返回。 +類型擦除與省略類型說明不同。 一旦類型參數信息被刪除,除非您再次聲明它,否則它不會被返回。 ```python implicit = (1..5).iter().map(i -> i * 2).to_arr() explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat)) ``` -在 Rust 中,这对应于以下代码: +在 Rust 中,這對應于以下代碼: ```rust let partial = (1..6).iter().map(|i| i * 2).collect::>(); ``` -Erg 不允许部分省略类型,而是使用高阶种类多态性。 +Erg 不允許部分省略類型,而是使用高階種類多態性。 ```python -# collect 是采用 Kind 的高阶 Kind 方法 +# collect 是采用 Kind 的高階 Kind 方法 hk = (1..5).iter().map(i -> i * 2).collect(Array) hk: Array(Int) ``` diff --git a/doc/zh_TW/syntax/type/advanced/existential.md b/doc/zh_TW/syntax/type/advanced/existential.md index f28b67ed..e5900b93 100644 --- a/doc/zh_TW/syntax/type/advanced/existential.md +++ b/doc/zh_TW/syntax/type/advanced/existential.md @@ -1,23 +1,23 @@ -# 存在类型 +# 存在類型 -如果存在对应于∀的for-all类型,那么很自然地假设存在对应于∃的存在类型。 -存在类型并不难。 你已经知道存在类型,只是没有意识到它本身。 +如果存在對應于?的for-all類型,那么很自然地假設存在對應于?的存在類型。 +存在類型并不難。 你已經知道存在類型,只是沒有意識到它本身。 ```python T: Trait f x: T = ... ``` -上面的 trait `T` 被用作存在类型。 -相比之下,小写的`T`只是一个特征,`X`是一个for-all类型。 +上面的 trait `T` 被用作存在類型。 +相比之下,小寫的`T`只是一個特征,`X`是一個for-all類型。 ```python f|X <: T| x: X = ... ``` -事实上,existential 类型被 for-all 类型所取代。 那么为什么会有存在类型这样的东西呢? -首先,正如我们在上面看到的,存在类型不涉及类型变量,这简化了类型规范。 -此外,由于可以删除类型变量,因此如果它是一个全推定类型,则可以构造一个等级为 2 或更高的类型。 +事實上,existential 類型被 for-all 類型所取代。 那么為什么會有存在類型這樣的東西呢? +首先,正如我們在上面看到的,存在類型不涉及類型變量,這簡化了類型規范。 +此外,由于可以刪除類型變量,因此如果它是一個全推定類型,則可以構造一個等級為 2 或更高的類型。 ```python show_map f: (|T| T -> T), arr: [Show; _] = @@ -27,8 +27,8 @@ show_map f: (|T| T -> T), arr: [Show; _] = y ``` -但是,如您所见,existential 类型忘记或扩展了原始类型,因此如果您不想扩展返回类型,则必须使用 for-all 类型。 -相反,仅作为参数且与返回值无关的类型可以写为存在类型。 +但是,如您所見,existential 類型忘記或擴展了原始類型,因此如果您不想擴展返回類型,則必須使用 for-all 類型。 +相反,僅作為參數且與返回值無關的類型可以寫為存在類型。 ```python # id(1): 我希望它是 Int @@ -37,5 +37,5 @@ id|T|(x: T): T = x show(s: Show): () = log s ``` -顺便说一句,类不称为存在类型。 一个类不被称为存在类型,因为它的元素对象是预定义的。 -存在类型是指满足某种特征的任何类型,它不是知道实际分配了什么类型的地方。 \ No newline at end of file +順便說一句,類不稱為存在類型。 一個類不被稱為存在類型,因為它的元素對象是預定義的。 +存在類型是指滿足某種特征的任何類型,它不是知道實際分配了什么類型的地方。 \ 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 index 0989b952..313c3903 100644 --- a/doc/zh_TW/syntax/type/advanced/keyword_param.md +++ b/doc/zh_TW/syntax/type/advanced/keyword_param.md @@ -1,22 +1,22 @@ -# 带有关键字参数的函数类型 +# 帶有關鍵字參數的函數類型 ```python h(f) = f(y: 1, x: 2) h: |T: type|((y: Int, x: Int) -> T) -> T ``` -带有关键字参数的函数的子类型化规则如下。 +帶有關鍵字參數的函數的子類型化規則如下。 ```python -((x: T, y: U) -> V) <: ((T, U) -> V) # x, y 为任意关键字参数 +((x: T, y: U) -> V) <: ((T, U) -> V) # x, y 為任意關鍵字參數 ((y: U, x: T) -> V) <: ((x: T, y: U) -> V) ((x: T, y: U) -> V) <: ((y: U, x: T) -> V) ``` -这意味着可以删除或替换关键字参数。 -但是你不能同时做这两件事。 -也就是说,您不能将 `(x: T, y: U) -> V` 转换为 `(U, T) -> V`。 -请注意,关键字参数仅附加到顶级元组,而不附加到数组或嵌套元组。 +這意味著可以刪除或替換關鍵字參數。 +但是你不能同時做這兩件事。 +也就是說,您不能將 `(x: T, y: U) -> V` 轉換為 `(U, T) -> V`。 +請注意,關鍵字參數僅附加到頂級元組,而不附加到數組或嵌套元組。 ```python Valid: [T, U] -> V diff --git a/doc/zh_TW/syntax/type/advanced/kind.md b/doc/zh_TW/syntax/type/advanced/kind.md index f0da4035..2cb42a9e 100644 --- a/doc/zh_TW/syntax/type/advanced/kind.md +++ b/doc/zh_TW/syntax/type/advanced/kind.md @@ -1,44 +1,44 @@ # Kind -一切都在 Erg 中输入。类型本身也不例外。 __kind__ 表示“类型的类型”。例如,`Int` 属于 `Type`,就像 `1` 属于 `Int`。 `Type` 是最简单的一种,__atomic kind__。在类型论符号中,`Type` 对应于 `*`。 +一切都在 Erg 中輸入。類型本身也不例外。 __kind__ 表示“類型的類型”。例如,`Int` 屬于 `Type`,就像 `1` 屬于 `Int`。 `Type` 是最簡單的一種,__atomic kind__。在類型論符號中,`Type` 對應于 `*`。 -在Kind的概念中,实际上重要的是一种或多种Kind(多项式Kind)。单项类型,例如`Option`,属于它。一元Kind表示为 `Type -> Type` [1](#1)。诸如 `Array` 或 `Option` 之类的 __container__ 特别是一种以类型作为参数的多项式类型。 -正如符号 `Type -> Type` 所表明的,`Option` 实际上是一个接收类型 `T` 并返回类型 `Option T` 的函数。但是,由于这个函数不是通常意义上的函数,所以通常称为一元类。 +在Kind的概念中,實際上重要的是一種或多種Kind(多項式Kind)。單項類型,例如`Option`,屬于它。一元Kind表示為 `Type -> Type` [1](#1)。諸如 `Array` 或 `Option` 之類的 __container__ 特別是一種以類型作為參數的多項式類型。 +正如符號 `Type -> Type` 所表明的,`Option` 實際上是一個接收類型 `T` 并返回類型 `Option T` 的函數。但是,由于這個函數不是通常意義上的函數,所以通常稱為一元類。 -注意`->`本身,它是一个匿名函数操作符,当它接收一个类型并返回一个类型时,也可以看作是一Kind型。 +注意`->`本身,它是一個匿名函數操作符,當它接收一個類型并返回一個類型時,也可以看作是一Kind型。 -另请注意,不是原子Kind的Kind不是类型。正如 `-1` 是一个数字但 `-` 不是,`Option Int` 是一个类型但 `Option` 不是。 `Option` 等有时被称为类型构造函数。 +另請注意,不是原子Kind的Kind不是類型。正如 `-1` 是一個數字但 `-` 不是,`Option Int` 是一個類型但 `Option` 不是。 `Option` 等有時被稱為類型構造函數。 ```python assert not Option in Type assert Option in Type -> Type ``` -所以像下面这样的代码会报错: -在 Erg 中,方法只能在原子类型中定义,并且名称 `self` 不能在方法的第一个参数以外的任何地方使用。 +所以像下面這樣的代碼會報錯: +在 Erg 中,方法只能在原子類型中定義,并且名稱 `self` 不能在方法的第一個參數以外的任何地方使用。 ```python -#K 是一元类型 +#K 是一元類型 K: Type -> Type K T = Class... K. -foo x = ... # OK,这就像是所谓的静态方法 - bar self, x = ... # 类型错误: 无法为非类型对象定义方法 +foo x = ... # OK,這就像是所謂的靜態方法 + bar self, x = ... # 類型錯誤: 無法為非類型對象定義方法 K(T). baz self, x = ... # OK ``` -二进制或更高类型的示例是 `{T: U}`(: `(Type, Type) -> Type`), `(T, U, V)`(: `(Type, Type, Type) - > Type `), ... 等等。 +二進制或更高類型的示例是 `{T: U}`(: `(Type, Type) -> Type`), `(T, U, V)`(: `(Type, Type, Type) - > Type `), ... 等等。 -还有一个零项类型`() -> Type`。 这有时等同于类型论中的原子类型,但在 Erg 中有所区别。 一个例子是`类`。 +還有一個零項類型`() -> Type`。 這有時等同于類型論中的原子類型,但在 Erg 中有所區別。 一個例子是`類`。 ```python Nil = Class() ``` -## 收容类 +## 收容類 -多项类型之间也存在部分类型关系,或者更确切地说是部分类型关系。 +多項類型之間也存在部分類型關系,或者更確切地說是部分類型關系。 ```python K T = ... @@ -46,15 +46,15 @@ L = Inherit K L<: K ``` -也就是说,对于任何 `T`,如果 `L T <: K T`,则 `L <: K`,反之亦然。 +也就是說,對于任何 `T`,如果 `L T <: K T`,則 `L <: K`,反之亦然。 ```python -∀T. L T <: K T <=> L <: K +?T. L T <: K T <=> L <: K ``` -## 高阶Kind +## 高階Kind -还有一种高阶Kind。 这是一种与高阶函数相同的概念,一种自身接收一种类型。 `(Type -> Type) -> Type` 是一种更高的Kind。 让我们定义一个属于更高Kind的对象。 +還有一種高階Kind。 這是一種與高階函數相同的概念,一種自身接收一種類型。 `(Type -> Type) -> Type` 是一種更高的Kind。 讓我們定義一個屬于更高Kind的對象。 ```python IntContainerOf K: Type -> Type = K Int @@ -63,46 +63,46 @@ assert IntContainerOf Result == Result Int assert IntContainerOf in (Type -> Type) -> Type ``` -多项式类型的有界变量通常表示为 K, L, ...,其中 K 是 Kind 的 K +多項式類型的有界變量通常表示為 K, L, ...,其中 K 是 Kind 的 K -## 设置Kind +## 設置Kind -在类型论中,有记录的概念。 这与 Erg 记录 [2](#2) 几乎相同。 +在類型論中,有記錄的概念。 這與 Erg 記錄 [2](#2) 幾乎相同。 ```python -# 这是一条记录,对应于类型论中所谓的记录 +# 這是一條記錄,對應于類型論中所謂的記錄 {x = 1; y = 2} ``` -当所有的记录值都是类型时,它是一种类型,称为记录类型。 +當所有的記錄值都是類型時,它是一種類型,稱為記錄類型。 ```python assert {x = 1; y = 2} in {x = Int; y = Int} ``` -记录类型键入记录。 一个好的猜测者可能认为应该有一个“记录类型”来键入记录类型。 实际上它是存在的。 +記錄類型鍵入記錄。 一個好的猜測者可能認為應該有一個“記錄類型”來鍵入記錄類型。 實際上它是存在的。 ```python log Typeof {x = Int; y = Int} # {{x = Int; y = Int}} ``` -像 `{{x = Int; 这样的类型 y = Int}}` 是一种记录类型。 这不是一个特殊的符号。 它只是一个枚举类型,只有 `{x = Int; y = Int}` 作为一个元素。 +像 `{{x = Int; 這樣的類型 y = Int}}` 是一種記錄類型。 這不是一個特殊的符號。 它只是一個枚舉類型,只有 `{x = Int; y = Int}` 作為一個元素。 ```python Point = {x = Int; y = Int} Pointy = {Point} ``` -记录类型的一个重要属性是,如果 `T: |T|` 和 `U <: T` 则 `U: |T|`。 -从枚举实际上是筛子类型的语法糖这一事实也可以看出这一点。 +記錄類型的一個重要屬性是,如果 `T: |T|` 和 `U <: T` 則 `U: |T|`。 +從枚舉實際上是篩子類型的語法糖這一事實也可以看出這一點。 ```python -# {c} == {X: T | X == c} 对于普通对象,但是不能为类型定义相等性,所以 |T| == {X | X <: T} +# {c} == {X: T | X == c} 對于普通對象,但是不能為類型定義相等性,所以 |T| == {X | X <: T} {Point} == {P | P <: Point} ``` -类型约束中的 `U <: T` 实际上是 `U: |T|` 的语法糖。 -作为此类类型的集合的种类通常称为集合种类。 Setkind 也出现在迭代器模式中。 +類型約束中的 `U <: T` 實際上是 `U: |T|` 的語法糖。 +作為此類類型的集合的種類通常稱為集合種類。 Setkind 也出現在迭代器模式中。 ```python Iterable T = Trait { @@ -111,7 +111,7 @@ Iterable T = Trait { } ``` -## 多项式类型的类型推断 +## 多項式類型的類型推斷 ```python Container K: Type -> Type, T: Type = Patch K(T, T) @@ -127,21 +127,21 @@ Fn2 T, U: Type = Patch T -> U Fn2(T, U). f self = ... -(Int -> Int).f() # 选择了哪一个? +(Int -> Int).f() # 選擇了哪一個? ``` -在上面的示例中,方法 `f` 会选择哪个补丁? -天真,似乎选择了`Fn T`,但是`Fn2 T,U`也是可以的,`Option T`原样包含`T`,所以任何类型都适用,`Container K,T`也匹配`->(Int, Int)`,即 `Container(`->`, Int)` 为 `Int -> Int`。因此,上述所有四个修复程序都是可能的选择。 +在上面的示例中,方法 `f` 會選擇哪個補丁? +天真,似乎選擇了`Fn T`,但是`Fn2 T,U`也是可以的,`Option T`原樣包含`T`,所以任何類型都適用,`Container K,T`也匹配`->(Int, Int)`,即 `Container(`->`, Int)` 為 `Int -> Int`。因此,上述所有四個修復程序都是可能的選擇。 -在这种情况下,根据以下优先标准选择修复程序。 +在這種情況下,根據以下優先標準選擇修復程序。 -* 任何 `K(T)`(例如 `T or NoneType`)优先匹配 `Type -> Type` 而不是 `Type`。 -* 任何 `K(T, U)`(例如 `T -> U`)优先匹配 `(Type, Type) -> Type` 而不是 `Type`。 -* 类似的标准适用于种类 3 或更多。 -* 选择需要较少类型变量来替换的那个。例如,`Int -> Int` 是 `T -> T` 而不是 `K(T, T)`(替换类型变量:K, T)或 `T -> U`(替换类型变量:T, U )。(替换类型变量:T)优先匹配。 -* 如果更换的次数也相同,则报错为不可选择。 +* 任何 `K(T)`(例如 `T or NoneType`)優先匹配 `Type -> Type` 而不是 `Type`。 +* 任何 `K(T, U)`(例如 `T -> U`)優先匹配 `(Type, Type) -> Type` 而不是 `Type`。 +* 類似的標準適用于種類 3 或更多。 +* 選擇需要較少類型變量來替換的那個。例如,`Int -> Int` 是 `T -> T` 而不是 `K(T, T)`(替換類型變量:K, T)或 `T -> U`(替換類型變量:T, U )。(替換類型變量:T)優先匹配。 +* 如果更換的次數也相同,則報錯為不可選擇。 --- -1 在类型理论符号中,`*=>*` [↩](#f1) +1 在類型理論符號中,`*=>*` [?](#f1) -2 可见性等细微差别。[↩](#f2) \ No newline at end of file +2 可見性等細微差別。[?](#f2) \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/marker_trait.md b/doc/zh_TW/syntax/type/advanced/marker_trait.md index 67227598..733173bf 100644 --- a/doc/zh_TW/syntax/type/advanced/marker_trait.md +++ b/doc/zh_TW/syntax/type/advanced/marker_trait.md @@ -1,10 +1,10 @@ -# 标记特征 +# 標記特征 -标记特征是没有必需属性的特征。 也就是说,您可以在不实现任何方法的情况下实现 Impl。 -没有 required 属性似乎没有意义,但由于注册了它属于 trait 的信息,因此可以使用 patch 方法或由编译器进行特殊处理。 +標記特征是沒有必需屬性的特征。 也就是說,您可以在不實現任何方法的情況下實現 Impl。 +沒有 required 屬性似乎沒有意義,但由于注冊了它屬于 trait 的信息,因此可以使用 patch 方法或由編譯器進行特殊處理。 -所有标记特征都包含在“标记”特征中。 -作为标准提供的“光”是一种标记特征。 +所有標記特征都包含在“標記”特征中。 +作為標準提供的“光”是一種標記特征。 ```python Light = Subsume Marker @@ -24,7 +24,7 @@ assert i + 1 == 2 assert i in M ``` -标记类也可以使用 `Excluding` 参数排除。 +標記類也可以使用 `Excluding` 參數排除。 ```python NInt = Inherit MarkedInt, Impl := N, Excluding: M diff --git a/doc/zh_TW/syntax/type/advanced/mut_struct.md b/doc/zh_TW/syntax/type/advanced/mut_struct.md index e17faa08..83ff0c82 100644 --- a/doc/zh_TW/syntax/type/advanced/mut_struct.md +++ b/doc/zh_TW/syntax/type/advanced/mut_struct.md @@ -1,23 +1,23 @@ -# 可变结构类型 +# 可變結構類型 -`T!` 类型被描述为可以被任何 `T` 类型对象替换的盒子类型。 +`T!` 類型被描述為可以被任何 `T` 類型對象替換的盒子類型。 ```python Particle!State: {"base", "excited"}! = Class(... Impl := Phantom State) Particle! - # 此方法将状态从“base”移动到“excited” + # 此方法將狀態從“base”移動到“excited” apply_electric_field!(ref! self("base" ~> "excited"), field: Vector) = ... ``` -`T!` 类型可以替换数据,但不能改变其结构。 -更像是一个真实程序的行为,它不能改变它的大小(在堆上)。 这样的类型称为不可变结构(mutable)类型。 +`T!` 類型可以替換數據,但不能改變其結構。 +更像是一個真實程序的行為,它不能改變它的大小(在堆上)。 這樣的類型稱為不可變結構(mutable)類型。 -事实上,有些数据结构不能用不变的结构类型来表示。 -例如,可变长度数组。 `[T; N]!`类型可以包含任何`[T; N]`,但不能被`[T; N+1]` 等等。 +事實上,有些數據結構不能用不變的結構類型來表示。 +例如,可變長度數組。 `[T; N]!`類型可以包含任何`[T; N]`,但不能被`[T; N+1]` 等等。 -换句话说,长度不能改变。 要改变长度,必须改变类型本身的结构。 +換句話說,長度不能改變。 要改變長度,必須改變類型本身的結構。 -这是通过可变结构(可变)类型实现的。 +這是通過可變結構(可變)類型實現的。 ```python v = [Str; !0].new() @@ -25,10 +25,10 @@ v.push! "Hello" v: [Str; !1]. ``` -对于可变结构类型,可变类型参数用 `!` 标记。 在上述情况下,类型 `[Str; !0]` 可以更改为 `[Str; !1]` 等等。 即,可以改变长度。 -顺便说一句,`[T; !N]` 类型是 `ArrayWithLength!(T, !N)` 类型的糖衣语法。 +對于可變結構類型,可變類型參數用 `!` 標記。 在上述情況下,類型 `[Str; !0]` 可以更改為 `[Str; !1]` 等等。 即,可以改變長度。 +順便說一句,`[T; !N]` 類型是 `ArrayWithLength!(T, !N)` 類型的糖衣語法。 -可变结构类型当然可以是用户定义的。 但是请注意,在构造方法方面与不变结构类型存在一些差异。 +可變結構類型當然可以是用戶定義的。 但是請注意,在構造方法方面與不變結構類型存在一些差異。 ```python Nil T = Class(Impl := Phantom T) diff --git a/doc/zh_TW/syntax/type/advanced/newtype.md b/doc/zh_TW/syntax/type/advanced/newtype.md index 7100c029..fde9b08d 100644 --- a/doc/zh_TW/syntax/type/advanced/newtype.md +++ b/doc/zh_TW/syntax/type/advanced/newtype.md @@ -1,24 +1,24 @@ -# 新类型模式 +# 新類型模式 -这是 Rust 中常用的 newtype 模式的 Erg 版本。 +這是 Rust 中常用的 newtype 模式的 Erg 版本。 -Erg 允许定义类型别名如下,但它们只引用相同的类型。 +Erg 允許定義類型別名如下,但它們只引用相同的類型。 ```python UserID = Int ``` -因此,例如,如果你有一个规范,类型为 `UserId` 的数字必须是一个正的 8 位数字,你可以输入 `10` 或 `-1`,因为它与类型 `Int` 相同 . 如果设置为 `Nat`,则可以拒绝 `-1`,但 8 位数字的性质不能仅用 Erg 的类型系统来表达。 +因此,例如,如果你有一個規范,類型為 `UserId` 的數字必須是一個正的 8 位數字,你可以輸入 `10` 或 `-1`,因為它與類型 `Int` 相同 . 如果設置為 `Nat`,則可以拒絕 `-1`,但 8 位數字的性質不能僅用 Erg 的類型系統來表達。 -此外,例如,在设计数据库系统时,假设有几种类型的 ID:用户 ID、产品 ID、产品 ID 和用户 ID。 如果 ID 类型的数量增加,例如用户 ID、产品 ID、订单 ID 等,可能会出现将不同类型的 ID 传递给不同函数的 bug。 即使用户 ID 和产品 ID 在结构上相同,但它们在语义上是不同的。 +此外,例如,在設計數據庫系統時,假設有幾種類型的 ID:用戶 ID、產品 ID、產品 ID 和用戶 ID。 如果 ID 類型的數量增加,例如用戶 ID、產品 ID、訂單 ID 等,可能會出現將不同類型的 ID 傳遞給不同函數的 bug。 即使用戶 ID 和產品 ID 在結構上相同,但它們在語義上是不同的。 -对于这种情况,newtype 模式是一个很好的设计模式。 +對于這種情況,newtype 模式是一個很好的設計模式。 ```python UserId = Class {id = Nat} UserId. new id: Nat = - assert id.dights().len() == 8, else: "UserId 必须是长度为 8 的正数" + assert id.dights().len() == 8, else: "UserId 必須是長度為 8 的正數" UserId::__new__ {id;} i = UserId.new(10000000) @@ -26,6 +26,6 @@ print! i # <__main__.UserId object> i + UserId.new(10000001) # TypeError: + is not implemented between `UserId` and `UserId ``` -构造函数保证 8 位数字的前置条件。 -`UserId` 失去了 `Nat` 拥有的所有方法,所以每次都必须重新定义必要的操作。 -如果重新定义的成本不值得,最好使用继承。 另一方面,在某些情况下,方法丢失是可取的,因此请根据情况选择适当的方法。 +構造函數保證 8 位數字的前置條件。 +`UserId` 失去了 `Nat` 擁有的所有方法,所以每次都必須重新定義必要的操作。 +如果重新定義的成本不值得,最好使用繼承。 另一方面,在某些情況下,方法丟失是可取的,因此請根據情況選擇適當的方法。 diff --git a/doc/zh_TW/syntax/type/advanced/overloading.md b/doc/zh_TW/syntax/type/advanced/overloading.md index 373585b0..0cbe405c 100644 --- a/doc/zh_TW/syntax/type/advanced/overloading.md +++ b/doc/zh_TW/syntax/type/advanced/overloading.md @@ -1,7 +1,7 @@ -# 重载 +# 重載 -Erg 不支持 __ad hoc 多态性__。 也就是说,函数和种类(重载)的多重定义是不可能的。 但是,您可以通过使用特征和补丁的组合来重现重载行为。 -您可以使用特征而不是特征类,但随后将涵盖所有实现 `.add1` 的类型。 +Erg 不支持 __ad hoc 多態性__。 也就是說,函數和種類(重載)的多重定義是不可能的。 但是,您可以通過使用特征和補丁的組合來重現重載行為。 +您可以使用特征而不是特征類,但隨后將涵蓋所有實現 `.add1` 的類型。 ```python Add1 = Trait { @@ -19,10 +19,10 @@ assert add1(1) == 2 assert add1(1.0) == 2.0 ``` -这种接受一个类型的所有子类型的多态称为__subtyping polymorphism__。 +這種接受一個類型的所有子類型的多態稱為__subtyping polymorphism__。 -如果每种类型的过程完全相同,则可以编写如下。 当行为从类到类(但返回类型相同)时,使用上述内容。 -使用类型参数的多态称为 __parametric polymorphism__。 参数多态性通常与子类型结合使用,如下所示,在这种情况下,它是参数和子类型多态性的组合。 +如果每種類型的過程完全相同,則可以編寫如下。 當行為從類到類(但返回類型相同)時,使用上述內容。 +使用類型參數的多態稱為 __parametric polymorphism__。 參數多態性通常與子類型結合使用,如下所示,在這種情況下,它是參數和子類型多態性的組合。 ```python add1|T <: Int or Str| x: T = x + 1 @@ -30,7 +30,7 @@ assert add1(1) == 2 assert add1(1.0) == 2.0 ``` -此外,可以使用默认参数重现具有不同数量参数的类型的重载。 +此外,可以使用默認參數重現具有不同數量參數的類型的重載。 ```python C = Class {.x = Int; .y = Int} @@ -40,12 +40,12 @@ C. assert C.new(0, 0) == C.new(0) ``` -Erg 的立场是,您不能定义行为完全不同的函数,例如根据参数的数量具有不同的类型,但如果行为不同,则应该以不同的方式命名。 +Erg 的立場是,您不能定義行為完全不同的函數,例如根據參數的數量具有不同的類型,但如果行為不同,則應該以不同的方式命名。 -综上所述,Erg 禁止重载,采用子类型加参数多态,原因如下。 +綜上所述,Erg 禁止重載,采用子類型加參數多態,原因如下。 -首先,重载函数分布在它们的定义中。 这使得在发生错误时很难报告错误的原因。 -此外,导入子程序可能会改变已定义子程序的行为。 +首先,重載函數分布在它們的定義中。 這使得在發生錯誤時很難報告錯誤的原因。 +此外,導入子程序可能會改變已定義子程序的行為。 ```python @@ -55,21 +55,21 @@ id x: Int = x ... id x: Ratio = x ... -id "str" # 类型错误:没有为 Str 实现 id -# 但是……但是……这个错误是从哪里来的? +id "str" # 類型錯誤:沒有為 Str 實現 id +# 但是……但是……這個錯誤是從哪里來的? ``` -其次,它与默认参数不兼容。 当具有默认参数的函数被重载时,会出现一个优先级的问题。 +其次,它與默認參數不兼容。 當具有默認參數的函數被重載時,會出現一個優先級的問題。 ```python f x: Int = ... f(x: Int, y := 0) = ... -f(1) # 选择哪个? +f(1) # 選擇哪個? ``` -此外,它与声明不兼容。 -声明 `f: Num -> Num` 不能指定它引用的定义。 这是因为 `Int -> Ratio` 和 `Ratio -> Int` 不包含在内。 +此外,它與聲明不兼容。 +聲明 `f: Num -> Num` 不能指定它引用的定義。 這是因為 `Int -> Ratio` 和 `Ratio -> Int` 不包含在內。 ```python f: Num -> Num @@ -77,14 +77,14 @@ f(x: Int): Ratio = ... f(x: Ratio): Int = ... ``` -并且语法不一致:Erg禁止变量重新赋值,但是重载的语法看起来像重新赋值。 -也不能用匿名函数代替。 +并且語法不一致:Erg禁止變量重新賦值,但是重載的語法看起來像重新賦值。 +也不能用匿名函數代替。 ```python # 同 `f = x -> body` f x = body -# 一样……什么? +# 一樣……什么? f x: Int = x f x: Ratio = x ``` diff --git a/doc/zh_TW/syntax/type/advanced/phantom.md b/doc/zh_TW/syntax/type/advanced/phantom.md index 14c95749..52fbf2ef 100644 --- a/doc/zh_TW/syntax/type/advanced/phantom.md +++ b/doc/zh_TW/syntax/type/advanced/phantom.md @@ -1,7 +1,7 @@ -# 幻影(phantom)类 +# 幻影(phantom)類 -幻像类型是标记特征,其存在仅用于向编译器提供注释。 -作为幻像类型的一种用法,让我们看一下列表的结构。 +幻像類型是標記特征,其存在僅用于向編譯器提供注釋。 +作為幻像類型的一種用法,讓我們看一下列表的結構。 ```python Nil = Class() @@ -9,26 +9,26 @@ List T, 0 = Inherit Nil List T, N: Nat = Class {head = T; rest = List(T, N-1)} ``` -此代码导致错误。 +此代碼導致錯誤。 ```python 3 | List T, 0 = Inherit Nil ^^^ -类型构造错误:由于Nil没有参数T,所以无法用Nil构造List(T, 0) -提示:使用 'Phantom' 特质消耗 T +類型構造錯誤:由于Nil沒有參數T,所以無法用Nil構造List(T, 0) +提示:使用 'Phantom' 特質消耗 T ``` -此错误是在使用 `List(_, 0).new Nil.new()` 时无法推断 `T` 的抱怨。 -在这种情况下,无论 `T` 类型是什么,它都必须在右侧使用。 大小为零的类型(例如长度为零的元组)很方便,因为它没有运行时开销。 +此錯誤是在使用 `List(_, 0).new Nil.new()` 時無法推斷 `T` 的抱怨。 +在這種情況下,無論 `T` 類型是什么,它都必須在右側使用。 大小為零的類型(例如長度為零的元組)很方便,因為它沒有運行時開銷。 ```python Nil T = Class((T; 0)) List T, 0 = Inherit Nil T List T, N: Nat = Class {head = T; rest = List(T, N-1)} ``` -此代码通过编译。 但是理解意图有点棘手,除非类型参数是类型,否则不能使用它。 +此代碼通過編譯。 但是理解意圖有點棘手,除非類型參數是類型,否則不能使用它。 -在这种情况下,幻影类型正是您所需要的。 幻像类型是大小为 0 的广义类型。 +在這種情況下,幻影類型正是您所需要的。 幻像類型是大小為 0 的廣義類型。 ```python Nil T = Class(Impl := Phantom T) @@ -39,10 +39,10 @@ nil = Nil(Int).new() assert nil.__size__ == 0 ``` -`Phantom` 拥有`T` 类型。 但实际上 `Phantom T` 类型的大小是 0 并且不包含 `T` 类型的对象。 +`Phantom` 擁有`T` 類型。 但實際上 `Phantom T` 類型的大小是 0 并且不包含 `T` 類型的對象。 -此外,`Phantom` 可以使用除其类型之外的任意类型参数。 在下面的示例中,`Phantom` 包含一个名为 `State` 的类型参数,它是 `Str` 的子类型对象。 -同样,`State` 是一个假的类型变量,不会出现在对象的实体中。 +此外,`Phantom` 可以使用除其類型之外的任意類型參數。 在下面的示例中,`Phantom` 包含一個名為 `State` 的類型參數,它是 `Str` 的子類型對象。 +同樣,`State` 是一個假的類型變量,不會出現在對象的實體中。 ```python VM! State: {"stopped", "running"}! = Class(... State) @@ -52,5 +52,5 @@ VM!("stopped"). self::set_phantom!("running")) ``` -`state` 是通过 `update_phantom!` 或 `set_phantom!` 方法更新的。 -这是标准补丁为`Phantom!`(`Phantom`的变量版本)提供的方法,其用法与变量`update!`和`set!`相同。 \ No newline at end of file +`state` 是通過 `update_phantom!` 或 `set_phantom!` 方法更新的。 +這是標準補丁為`Phantom!`(`Phantom`的變量版本)提供的方法,其用法與變量`update!`和`set!`相同。 \ No newline at end of file diff --git a/doc/zh_TW/syntax/type/advanced/projection.md b/doc/zh_TW/syntax/type/advanced/projection.md index 9ecaf889..6d295db2 100644 --- a/doc/zh_TW/syntax/type/advanced/projection.md +++ b/doc/zh_TW/syntax/type/advanced/projection.md @@ -1,6 +1,6 @@ -# 投影类型 +# 投影類型 -投影类型表示如下代码中的“Self.AddO”等类型。 +投影類型表示如下代碼中的“Self.AddO”等類型。 ```python Add R = Trait { @@ -13,8 +13,8 @@ AddForInt. AddO = Int ``` -类型“Add(R)”可以说是定义了与某个对象的加法的类型。 由于方法应该是一个类型属性,`+` 类型声明应该写在缩进下面。 -`Add` 类型的场景是声明 `.AddO = Type`,而 `.AddO` 类型的实体是一个投影类型,由一个作为 ` 子类型的类型持有 添加`。 例如,`Int.AddO = Int`、`Odd.AddO = Even`。 +類型“Add(R)”可以說是定義了與某個對象的加法的類型。 由于方法應該是一個類型屬性,`+` 類型聲明應該寫在縮進下面。 +`Add` 類型的場景是聲明 `.AddO = Type`,而 `.AddO` 類型的實體是一個投影類型,由一個作為 ` 子類型的類型持有 添加`。 例如,`Int.AddO = Int`、`Odd.AddO = Even`。 ```python assert Int < Add diff --git a/doc/zh_TW/syntax/type/advanced/quantified_dependent.md b/doc/zh_TW/syntax/type/advanced/quantified_dependent.md index c96caca5..e9f70a41 100644 --- a/doc/zh_TW/syntax/type/advanced/quantified_dependent.md +++ b/doc/zh_TW/syntax/type/advanced/quantified_dependent.md @@ -1,15 +1,15 @@ -# 量化依赖类型 +# 量化依賴類型 -Erg 有量化和依赖类型。 那么很自然地,就可以创建一个将两者结合起来的类型。 那是量化的依赖类型。 +Erg 有量化和依賴類型。 那么很自然地,就可以創建一個將兩者結合起來的類型。 那是量化的依賴類型。 ```python NonNullStr = |N: Nat| StrWithLen N | N ! = 0 # 同 {S | N: Nat; S: StrWithLen N; N ! = 0} NonEmptyArray = |N: Nat| [_; N | N > 0] # 同 {A | N: Nat; A: Array(_, N); N > 0} ``` -量化依赖类型的标准形式是“K(A, ... | Pred)”。 `K` 是类型构造函数,`A, B` 是类型参数,`Pred` 是条件表达式。 +量化依賴類型的標準形式是“K(A, ... | Pred)”。 `K` 是類型構造函數,`A, B` 是類型參數,`Pred` 是條件表達式。 -作为左值的量化依赖类型只能在与原始类型相同的模块中定义方法。 +作為左值的量化依賴類型只能在與原始類型相同的模塊中定義方法。 ```python K A: Nat = Class ... @@ -19,9 +19,9 @@ K(A | A >= 1). method ref! self(A ~> A+1) = ... ``` -作为右值的量化依赖类型需要在类型变量列表 (`||`) 中声明要使用的类型变量。 +作為右值的量化依賴類型需要在類型變量列表 (`||`) 中聲明要使用的類型變量。 ```python -# T 是具体类型 +# T 是具體類型 a: |N: Nat| [T; N | N > 1] ``` diff --git a/doc/zh_TW/syntax/type/advanced/shared.md b/doc/zh_TW/syntax/type/advanced/shared.md index ec294166..8de3d6cd 100644 --- a/doc/zh_TW/syntax/type/advanced/shared.md +++ b/doc/zh_TW/syntax/type/advanced/shared.md @@ -1,7 +1,7 @@ -# 共享参考 +# 共享參考 -共享引用是必须小心处理的语言特性之一。 -例如,在 TypeScript 中,以下代码将通过类型检查。 +共享引用是必須小心處理的語言特性之一。 +例如,在 TypeScript 中,以下代碼將通過類型檢查。 ```typescript class NormalMember {} @@ -14,12 +14,12 @@ normal_area.push(new NormalMember()) console.log(vip_area) # [NormalMember] ``` -一个 NormalMember 已进入 vip_area。 这是一个明显的错误,但是出了什么问题? -原因是共享引用 [denatured](./variance.md)。 `normal_area` 是通过复制 `vip_area` 来创建的,但是这样做的时候类型已经改变了。 -但是 `VIPMember` 继承自 `NormalMember`,所以 `VIPMember[] <: NormalMember[]`,这不是问题。 -关系 `VIPMember[] <: NormalMember[]` 适用于不可变对象。 但是,如果您执行上述破坏性操作,则会出现故障。 +一個 NormalMember 已進入 vip_area。 這是一個明顯的錯誤,但是出了什么問題? +原因是共享引用 [denatured](./variance.md)。 `normal_area` 是通過復制 `vip_area` 來創建的,但是這樣做的時候類型已經改變了。 +但是 `VIPMember` 繼承自 `NormalMember`,所以 `VIPMember[] <: NormalMember[]`,這不是問題。 +關系 `VIPMember[] <: NormalMember[]` 適用于不可變對象。 但是,如果您執行上述破壞性操作,則會出現故障。 -在 Erg 中,由于所有权系统,此类代码会被回放。 +在 Erg 中,由于所有權系統,此類代碼會被回放。 ```python NormalMember = Class() @@ -29,20 +29,20 @@ vip_area = [].into [VIPMember; !_] normal_area: [NormalMember; !_] = vip_area normal_area.push!(NormalMember.new()) -log vip_area # 所有权错误:`vip_room` 已移至 `normal_room` +log vip_area # 所有權錯誤:`vip_room` 已移至 `normal_room` ``` -然而,一个对象只属于一个地方可能会很不方便。 -出于这个原因,Erg 有一个类型 `SharedCell!T!`,它代表一个共享状态。 +然而,一個對象只屬于一個地方可能會很不方便。 +出于這個原因,Erg 有一個類型 `SharedCell!T!`,它代表一個共享狀態。 ```python $p1 = SharedCell!.new(!1) $p2 = $p1.mirror!() $p3 = SharedCell!.new(!1) -# 如果$p1 == $p2,比较内容类型Int! +# 如果$p1 == $p2,比較內容類型Int! assert $p1 == $p2 assert $p1 == $p3 -# 检查 $p1 和 $p2 是否用 `.addr!` 指向同一个东西。 +# 檢查 $p1 和 $p2 是否用 `.addr!` 指向同一個東西。 assert $p1.addr!() == $p2.addr!() assert $p1.addr!() != $p3.addr!() $p1.add! 1 @@ -51,19 +51,19 @@ assert $p2 == 2 assert $p3 == 1 ``` -`SharedCell!` 类型的对象必须以`$` 为前缀。 此外,就其性质而言,它们不可能是常数。 +`SharedCell!` 類型的對象必須以`$` 為前綴。 此外,就其性質而言,它們不可能是常數。 -`SharedCell! T!` 类型也是 `T!` 的子类型,可以调用 `T!` 类型的方法。 `SharedCell!T!` 类型特有的唯一方法是 `.addr!`、`.mirror!` 和 `.try_take`。 +`SharedCell! T!` 類型也是 `T!` 的子類型,可以調用 `T!` 類型的方法。 `SharedCell!T!` 類型特有的唯一方法是 `.addr!`、`.mirror!` 和 `.try_take`。 -一个重要的事实是`SharedCell! T!` 是非变体的,即没有为不同类型的参数定义包含。 +一個重要的事實是`SharedCell! T!` 是非變體的,即沒有為不同類型的參數定義包含。 ```python $vip_area = SharedCell!.new([].into [VIPMember; !_]) -$normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() #类型错误:预期 SharedCell!([NormalMember;!_]),但得到 SharedCell!([VIPMember;!_]) -# 提示:SharedCell!(T) 是非变体的,这意味着它不能有超类型或子类型。 +$normal_area: SharedCell!([NormalMember; !_]) = $vip_area.mirror!() #類型錯誤:預期 SharedCell!([NormalMember;!_]),但得到 SharedCell!([VIPMember;!_]) +# 提示:SharedCell!(T) 是非變體的,這意味著它不能有超類型或子類型。 ``` -但是,下面的代码没有问题。 在最后一行,它是 `VIPMember` 参数已被类型转换 +但是,下面的代碼沒有問題。 在最后一行,它是 `VIPMember` 參數已被類型轉換 ```python $normal_area = SharedCell!.new([].into [NormalMember; !_]) diff --git a/doc/zh_TW/syntax/type/advanced/special.md b/doc/zh_TW/syntax/type/advanced/special.md index 92cbeb0b..43a60d8c 100644 --- a/doc/zh_TW/syntax/type/advanced/special.md +++ b/doc/zh_TW/syntax/type/advanced/special.md @@ -1,6 +1,6 @@ -# 特殊类型(Self、Super) +# 特殊類型(Self、Super) -`Self` 代表它自己的类型。 您可以将其用作别名,但请注意派生类型的含义会发生变化(指的是自己的类型)。 +`Self` 代表它自己的類型。 您可以將其用作別名,但請注意派生類型的含義會發生變化(指的是自己的類型)。 ```python @Inheritable @@ -14,7 +14,7 @@ classof D. new_self() # D classof D. new_c() # C ``` -`Super` 表示基类的类型。方法本身引用基类,但实例使用自己的类型。 +`Super` 表示基類的類型。方法本身引用基類,但實例使用自己的類型。 ```python @Inheritable @@ -29,9 +29,9 @@ classof D. new_super() # D classof D. new_c() # C ``` -## 特殊类型变量 +## 特殊類型變量 -`Self` 和 `Super` 可以用作结构化类型和特征中的类型变量。 这指的是作为该类型子类型的类。 也就是说,`T` 类型中的`Self` 表示`Self <: T`。 +`Self` 和 `Super` 可以用作結構化類型和特征中的類型變量。 這指的是作為該類型子類型的類。 也就是說,`T` 類型中的`Self` 表示`Self <: T`。 ```python Add R = Trait { diff --git a/doc/zh_TW/syntax/type/advanced/typeof.md b/doc/zh_TW/syntax/type/advanced/typeof.md index 7fd520cd..a43da672 100644 --- a/doc/zh_TW/syntax/type/advanced/typeof.md +++ b/doc/zh_TW/syntax/type/advanced/typeof.md @@ -1,6 +1,6 @@ # Typeof, classof -`Typeof` 是一个可以窥探 Erg 类型推断系统的函数,它的行为很复杂 +`Typeof` 是一個可以窺探 Erg 類型推斷系統的函數,它的行為很復雜 ```python assert Typeof(1) == {I: Int | I == 1} @@ -16,10 +16,10 @@ assert Typeof(J) == {i = Int} assert {X: C | X == I} < C and C <= {i = Int} ``` -`Typeof` 函数返回派生类型,而不是对象的类。 -因此,例如 `C = Class T` 类的`I: C`,`Typeof(I) == T`。 -值类没有对应的记录类型。 为了解决这个问题,值类应该是具有 `__valueclass_tag__` 属性的记录类型。 -请注意,您不能访问此属性,也不能在用户定义的类型上定义 `__valueclass_tag__` 属性。 +`Typeof` 函數返回派生類型,而不是對象的類。 +因此,例如 `C = Class T` 類的`I: C`,`Typeof(I) == T`。 +值類沒有對應的記錄類型。 為了解決這個問題,值類應該是具有 `__valueclass_tag__` 屬性的記錄類型。 +請注意,您不能訪問此屬性,也不能在用戶定義的類型上定義 `__valueclass_tag__` 屬性。 ```python i: Int = ... @@ -28,15 +28,15 @@ s: Str = ... assert Typeof(s) == {__valueclass_tag__ = Phantom Str} ``` -`Typeof` 仅输出结构化类型。 我解释说结构化类型包括属性类型、筛类型和(真正的)代数类型。 -这些是独立的类型(存在推理优先级),不会发生推理冲突。 -属性类型和代数类型可以跨越多个类,而筛类型是单个类的子类型。 -Erg 尽可能将对象类型推断为筛类型,如果不可能,则将筛基类扩展为结构化类型(见下文)。 +`Typeof` 僅輸出結構化類型。 我解釋說結構化類型包括屬性類型、篩類型和(真正的)代數類型。 +這些是獨立的類型(存在推理優先級),不會發生推理沖突。 +屬性類型和代數類型可以跨越多個類,而篩類型是單個類的子類型。 +Erg 盡可能將對象類型推斷為篩類型,如果不可能,則將篩基類擴展為結構化類型(見下文)。 -## 结构化的 +## 結構化的 -所有类都可以转换为派生类型。 这称为 __结构化__。 类的结构化类型可以通过 `Structure` 函数获得。 -如果一个类是用`C = Class T`定义的(所有类都以这种形式定义),那么`Structure(C) == T`。 +所有類都可以轉換為派生類型。 這稱為 __結構化__。 類的結構化類型可以通過 `Structure` 函數獲得。 +如果一個類是用`C = Class T`定義的(所有類都以這種形式定義),那么`Structure(C) == T`。 ```python C = Class {i = Int} @@ -47,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) # 类型错误:只能构造单态类型 -# 你实际上不能用 __valueclass_tag__ 定义一条记录,但在概念上 +assert Structure(Option) # 類型錯誤:只能構造單態類型 +# 你實際上不能用 __valueclass_tag__ 定義一條記錄,但在概念上 assert Structure(Int) == {__valueclass_tag__ = Phantom Int} assert Structure(Str) == {__valueclass_tag__ = Phantom Str} assert Structure((Nat, Nat)) == {__valueclass_tag__ = Phantom(Tuple(Nat, Nat))} assert Structure(Nat -> Nat) == {__valueclass_tag__ = Phantom(Func(Nat, Nat))} -# 标记类也是带有 __valueclass_tag__ 的记录类型 +# 標記類也是帶有 __valueclass_tag__ 的記錄類型 M = Inherit Marker assert Structure(M) == {__valueclass_tag__ = Phantom M} D = Inherit(C and M) diff --git a/doc/zh_TW/syntax/type/advanced/variance.md b/doc/zh_TW/syntax/type/advanced/variance.md index 26943813..6afead62 100644 --- a/doc/zh_TW/syntax/type/advanced/variance.md +++ b/doc/zh_TW/syntax/type/advanced/variance.md @@ -1,69 +1,69 @@ -# 变化 +# 變化 -Erg 可以对多态类型进行子类型化,但有一些注意事项。 +Erg 可以對多態類型進行子類型化,但有一些注意事項。 -首先,考虑普通多态类型的包含关系。一般来说,有一个容器`K`和它分配的类型`A,B`,当`A < B`时,`K A < K B`。 -例如,`Option Int < Option Object`。因此,在`Option Object`中定义的方法也可以在`Option Int`中使用。 +首先,考慮普通多態類型的包含關系。一般來說,有一個容器`K`和它分配的類型`A,B`,當`A < B`時,`K A < K B`。 +例如,`Option Int < Option Object`。因此,在`Option Object`中定義的方法也可以在`Option Int`中使用。 -考虑典型的多态类型 `Array!(T)`。 -请注意,这一次不是 `Array!(T, N)` 因为我们不关心元素的数量。 -现在,`Array!(T)` 类型具有称为 `.push!` 和 `.pop!` 的方法,分别表示添加和删除元素。这是类型: +考慮典型的多態類型 `Array!(T)`。 +請注意,這一次不是 `Array!(T, N)` 因為我們不關心元素的數量。 +現在,`Array!(T)` 類型具有稱為 `.push!` 和 `.pop!` 的方法,分別表示添加和刪除元素。這是類型: `Array.push!: Self(T).(T) => NoneType` `Array.pop!: Self(T).() => T` -可以直观地理解: +可以直觀地理解: * `Array!(Object).push!(s)` is OK when `s: Str` (just upcast `Str` to `Object`) * When `o: Object`, `Array!(Str).push!(o)` is NG * `Array!(Object).pop!().into(Str)` is NG * `Array!(Str).pop!().into(Object)` is OK -就类型系统而言,这是 +就類型系統而言,這是 * `(Self(Object).(Object) => NoneType) < (Self(Str).(Str) => NoneType)` * `(Self(Str).() => Str) < (Self(Object).() => Object)` 方法 -前者可能看起来很奇怪。即使是 `Str < Object`,包含关系在将其作为参数的函数中也是相反的。 -在类型论中,这种关系(`.push!` 的类型关系)称为逆变,反之,`.pop!` 的类型关系称为协变。 -换句话说,函数类型就其参数类型而言是逆变的,而就其返回类型而言是协变的。 -这听起来很复杂,但正如我们之前看到的,如果将其应用于实际示例,这是一个合理的规则。 -如果您仍然不明白,请考虑以下内容。 +前者可能看起來很奇怪。即使是 `Str < Object`,包含關系在將其作為參數的函數中也是相反的。 +在類型論中,這種關系(`.push!` 的類型關系)稱為逆變,反之,`.pop!` 的類型關系稱為協變。 +換句話說,函數類型就其參數類型而言是逆變的,而就其返回類型而言是協變的。 +這聽起來很復雜,但正如我們之前看到的,如果將其應用于實際示例,這是一個合理的規則。 +如果您仍然不明白,請考慮以下內容。 -Erg 的设计原则之一是“大输入类型,小输出类型”。这正是函数可变性的情况。 -看上面的规则,输入类型越大,整体类型越小。 -这是因为通用函数明显比专用函数少。 -而且输出类型越小,整体越小。 +Erg 的設計原則之一是“大輸入類型,小輸出類型”。這正是函數可變性的情況。 +看上面的規則,輸入類型越大,整體類型越小。 +這是因為通用函數明顯比專用函數少。 +而且輸出類型越小,整體越小。 -这样一来,上面的策略就相当于说“尽量减少函数的类型”。 +這樣一來,上面的策略就相當于說“盡量減少函數的類型”。 -## 不变性 +## 不變性 -Erg 有另一个修改。它是不变的。 -这是对 `SharedCell! T!`等内置类型的修改。这意味着对于两种类型 `T!, U!` 其中 `T! != U!`,在 `SharedCell! T!` 和 `SharedCell!意思是 -这是因为`SharedCell! T!` 是共享参考。有关详细信息,请参阅 [共享参考](shared.md)。 +Erg 有另一個修改。它是不變的。 +這是對 `SharedCell! T!`等內置類型的修改。這意味著對于兩種類型 `T!, U!` 其中 `T! != U!`,在 `SharedCell! T!` 和 `SharedCell!意思是 +這是因為`SharedCell! T!` 是共享參考。有關詳細信息,請參閱 [共享參考](shared.md)。 -## 变异的泛型类型 +## 變異的泛型類型 -通用类型变量可以指定其上限和下限。 +通用類型變量可以指定其上限和下限。 ```python |A <: T| K(A) |B :> T| K(B) ``` -在类型变量列表中,执行类型变量的__variant说明__。 在上述变体规范中,类型变量“A”被声明为“T”类型的任何子类,“B”类型被声明为“T”类型的任何超类。 -在这种情况下,`T` 也称为 `A` 的上部类型和 `B` 的下部类型。 +在類型變量列表中,執行類型變量的__variant說明__。 在上述變體規范中,類型變量“A”被聲明為“T”類型的任何子類,“B”類型被聲明為“T”類型的任何超類。 +在這種情況下,`T` 也稱為 `A` 的上部類型和 `B` 的下部類型。 -突变规范也可以重叠。 +突變規范也可以重疊。 ```python # U U} ``` -这是使用变量规范的代码示例: +這是使用變量規范的代碼示例: ```python show|S <: Show| s: S = log s @@ -76,18 +76,18 @@ List(T). upcast(self, U :> T): List U = self ``` -## 更改规范 +## 更改規范 -`List T` 的例子很棘手,所以让我们更详细一点。 -要理解上面的代码,你需要了解多态类型退化。 [this section](./variance.md) 中详细讨论了方差,但现在我们需要三个事实: +`List T` 的例子很棘手,所以讓我們更詳細一點。 +要理解上面的代碼,你需要了解多態類型退化。 [this section](./variance.md) 中詳細討論了方差,但現在我們需要三個事實: -* 普通的多态类型,例如`List T`,与`T`是协变的(`List U > List T` when `U > T`) -* 函数 `T -> U` 对于参数类型 `T` 是逆变的(`(S -> U) < (T -> U)` when `S > T`) -* 函数 `T -> U` 与返回类型 `U` 是协变的(`(T -> U) > (T -> S)` 当 `U > S` 时) +* 普通的多態類型,例如`List T`,與`T`是協變的(`List U > List T` when `U > T`) +* 函數 `T -> U` 對于參數類型 `T` 是逆變的(`(S -> U) < (T -> U)` when `S > T`) +* 函數 `T -> U` 與返回類型 `U` 是協變的(`(T -> U) > (T -> S)` 當 `U > S` 時) -例如,`List Int` 可以向上转换为 `List Object`,而 `Obj -> Obj` 可以向上转换为 `Int -> Obj`。 +例如,`List Int` 可以向上轉換為 `List Object`,而 `Obj -> Obj` 可以向上轉換為 `Int -> Obj`。 -现在让我们考虑如果我们省略方法的变量说明会发生什么。 +現在讓我們考慮如果我們省略方法的變量說明會發生什么。 ```python ... @@ -99,14 +99,14 @@ List(T). upcast(self, U): List U = self ``` -即使在这种情况下,Erg 编译器也能很好地推断 `U` 的上下类型。 -但是请注意,Erg 编译器不理解方法的语义。编译器只是根据变量和类型变量的使用方式机械地推断和派生类型关系。 +即使在這種情況下,Erg 編譯器也能很好地推斷 `U` 的上下類型。 +但是請注意,Erg 編譯器不理解方法的語義。編譯器只是根據變量和類型變量的使用方式機械地推斷和派生類型關系。 -正如评论中所写,放在`List T`的`head`中的`U`类型是`T`的子类(`T:Int`,例如`Nat`)。也就是说,它被推断为 `U <: T`。此约束将 `.push{U}` upcast `(List(T), U) -> List(T) 的参数类型更改为 (List(T), T) -> List(T)`(例如 disallow `列表(整数).push{对象}`)。但是请注意,`U <: T` 约束不会改变函数的类型包含。 `(List(Int), Object) -> List(Int) to (List(Int), Int) -> List(Int)` 的事实并没有改变,只是在 `.push` 方法中表示强制转换无法执行。 -类似地,从 `List T` 到​​ `List U` 的转换可能会受到约束 `U :> T` 的约束,因此可以推断出变体规范。此约束将 `.upcast(U)` 的返回类型更改为向上转换 `List(T) -> List(T) 到 List(T) -> List(T)`(例如 `List(Object) .upcast(Int )`) 被禁止。 +正如評論中所寫,放在`List T`的`head`中的`U`類型是`T`的子類(`T:Int`,例如`Nat`)。也就是說,它被推斷為 `U <: T`。此約束將 `.push{U}` upcast `(List(T), U) -> List(T) 的參數類型更改為 (List(T), T) -> List(T)`(例如 disallow `列表(整數).push{對象}`)。但是請注意,`U <: T` 約束不會改變函數的類型包含。 `(List(Int), Object) -> List(Int) to (List(Int), Int) -> List(Int)` 的事實并沒有改變,只是在 `.push` 方法中表示強制轉換無法執行。 +類似地,從 `List T` 到?? `List U` 的轉換可能會受到約束 `U :> T` 的約束,因此可以推斷出變體規范。此約束將 `.upcast(U)` 的返回類型更改為向上轉換 `List(T) -> List(T) 到 List(T) -> List(T)`(例如 `List(Object) .upcast(Int )`) 被禁止。 -现在让我们看看如果我们允许这种向上转换会发生什么。 -让我们反转变性名称。 +現在讓我們看看如果我們允許這種向上轉換會發生什么。 +讓我們反轉變性名稱。 ```python ... @@ -114,18 +114,18 @@ List T = Class {head = T; rest = Cons T} List(T). push|U :> T|(self, x: U): List T = Self. new {head = x; rest = self} upcast(self, U :> T): List U = self -# 类型警告:`.push` 中的 `U` 不能接受除 `U == T` 之外的任何内容。 将“U”替换为“T”。 -# 类型警告:`.upcast` 中的 `U` 不能接受除 `U == T` 之外的任何内容。 将“U”替换为“T”。 +# 類型警告:`.push` 中的 `U` 不能接受除 `U == T` 之外的任何內容。 將“U”替換為“T”。 +# 類型警告:`.upcast` 中的 `U` 不能接受除 `U == T` 之外的任何內容。 將“U”替換為“T”。 ``` -只有当 `U == T` 时,约束 `U <: T` 和修改规范`U :> T` 才满足。 所以这个称号没有多大意义。 -只有“向上转换使得 `U == T`” = “向上转换不会改变 `U` 的位置”实际上是允许的。 +只有當 `U == T` 時,約束 `U <: T` 和修改規范`U :> T` 才滿足。 所以這個稱號沒有多大意義。 +只有“向上轉換使得 `U == T`” = “向上轉換不會改變 `U` 的位置”實際上是允許的。 -##附录:用户定义类型的修改 +##附錄:用戶定義類型的修改 -默认情况下,用户定义类型的突变是不可变的。 但是,您也可以使用 `Inputs/Outputs` 标记特征指定可变性。 -如果您指定 `Inputs(T)`,则类型相对于 `T` 是逆变的。 -如果您指定 `Outputs(T)`,则类型相对于 `T` 是协变的。 +默認情況下,用戶定義類型的突變是不可變的。 但是,您也可以使用 `Inputs/Outputs` 標記特征指定可變性。 +如果您指定 `Inputs(T)`,則類型相對于 `T` 是逆變的。 +如果您指定 `Outputs(T)`,則類型相對于 `T` 是協變的。 ```python K T = Class(...) @@ -133,10 +133,10 @@ assert not K(Str) <= K(Object) assert not K(Str) >= K(Object) InputStream T = Class ..., Impl := Inputs(T) -# 接受Objects的流也可以认为接受Strs +# 接受Objects的流也可以認為接受Strs assert InputStream(Str) > InputStream(Object) OutputStream T = Class ..., Impl := Outputs(T) -# 输出Str的流也可以认为输出Object +# 輸出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 index 91e13f34..22991331 100644 --- a/doc/zh_TW/syntax/type/advanced/widening.md +++ b/doc/zh_TW/syntax/type/advanced/widening.md @@ -1,14 +1,14 @@ -# 类型加宽 +# 類型加寬 -例如,定义多相关系数如下。 +例如,定義多相關系數如下。 ```python ids|T|(x: T, y: T) = x, y ``` -分配同一类的一对实例并没有错。 -当您分配另一个具有包含关系的类的实例对时,它会向上转换为较大的类并成为相同的类型。 -另外,很容易理解,如果分配了另一个不在包含关系中的类,就会发生错误。 +分配同一類的一對實例并沒有錯。 +當您分配另一個具有包含關系的類的實例對時,它會向上轉換為較大的類并成為相同的類型。 +另外,很容易理解,如果分配了另一個不在包含關系中的類,就會發生錯誤。 ```python assert ids(1, 2) == (1, 2) @@ -16,7 +16,7 @@ assert ids(1, 2.0) == (1.0, 2.0) ids(1, "a") #TypeError ``` -现在,具有不同派生类型的类型呢? +現在,具有不同派生類型的類型呢? ```python i: Int or Str @@ -24,7 +24,7 @@ j: Int or NoneType ids(i, j) # ? ``` -在解释这一点之前,我们必须关注 Erg 的类型系统实际上并不关注(运行时)类这一事实。 +在解釋這一點之前,我們必須關注 Erg 的類型系統實際上并不關注(運行時)類這一事實。 ```python 1: {__valueclass_tag__ = Phantom Int} @@ -33,60 +33,60 @@ ids(i, j) # ? "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 # 类型错误 +ids(1, "a"): {__valueclass_tag__ = Phantom Int} and {__valueclass_tag__ = Phantom Str} == Never # 類型錯誤 ``` -我看不到该类,因为它可能无法准确看到,因为在 Erg 中,对象的类属于运行时信息。 -例如,一个`Int`或Str`类型的对象的类是`Int`或`Str`,但你只有通过执行才能知道它是哪一个。 -当然,`Int` 类型的对象的类被定义为 `Int`,但是在这种情况下,从类型系统中可见的是 `Int` 的结构类型 `{__valueclass_tag__ = Int}`。 +我看不到該類,因為它可能無法準確看到,因為在 Erg 中,對象的類屬于運行時信息。 +例如,一個`Int`或Str`類型的對象的類是`Int`或`Str`,但你只有通過執行才能知道它是哪一個。 +當然,`Int` 類型的對象的類被定義為 `Int`,但是在這種情況下,從類型系統中可見的是 `Int` 的結構類型 `{__valueclass_tag__ = Int}`。 -现在让我们回到另一个结构化类型示例。 总之,上述代码将导致类型错误,因为类型不匹配。 -但是,如果您使用类型注释进行类型扩展,编译将通过。 +現在讓我們回到另一個結構化類型示例。 總之,上述代碼將導致類型錯誤,因為類型不匹配。 +但是,如果您使用類型注釋進行類型擴展,編譯將通過。 ```python i: Int or Str j: Int or NoneType -ids(i, j) # 类型错误:i 和 j 的类型不匹配 -# 提示:尝试扩大类型(例如 ids) +ids(i, j) # 類型錯誤:i 和 j 的類型不匹配 +# 提示:嘗試擴大類型(例如 ids) ids(i, j) # OK ``` `A 和 B` 有以下可能性。 -* `A and B == A`:当`A <: B`或`A == B`时。 -* `A and B == B`:当 `A :> B` 或 `A == B` 时。 -* `A and B == {}`:当 `!(A :> B)` 和 `!(A <: B)` 时。 +* `A and B == A`:當`A <: B`或`A == B`時。 +* `A and B == B`:當 `A :> B` 或 `A == B` 時。 +* `A and B == {}`:當 `!(A :> B)` 和 `!(A <: B)` 時。 `A 或 B` 具有以下可能性。 -* `A 或 B == A`:当`A :> B` 或`A == B` 时。 -* `A or B == B`:当`A <: B`或`A == B`时。 -* `A 或 B` 是不可约的(独立类型):如果 `!(A :> B)` 和 `!(A <: B)`。 +* `A 或 B == A`:當`A :> B` 或`A == B` 時。 +* `A or B == B`:當`A <: B`或`A == B`時。 +* `A 或 B` 是不可約的(獨立類型):如果 `!(A :> B)` 和 `!(A <: B)`。 -## 子程序定义中的类型扩展 +## 子程序定義中的類型擴展 -如果返回类型不匹配,Erg 默认会出错。 +如果返回類型不匹配,Erg 默認會出錯。 ```python parse_to_int s: Str = if not s.is_numeric(): do parse_to_int::return error("not numeric") -... # 返回 Int 对象 -# 类型错误:返回值类型不匹配 +... # 返回 Int 對象 +# 類型錯誤:返回值類型不匹配 # 3 | 做 parse_to_int::return error("not numeric") # └─ Error # 4 | ... # └ Int ``` -为了解决这个问题,需要将返回类型显式指定为 Or 类型 +為了解決這個問題,需要將返回類型顯式指定為 Or 類型 ```python parse_to_int(s: Str): Int or Error = if not s.is_numeric(): do parse_to_int::return error("not numeric") - ... # 返回 Int 对象 + ... # 返回 Int 對象 ``` -这是设计使然,这样您就不会无意中将子例程的返回类型与另一种类型混合。 -但是,如果返回值类型选项是具有包含关系的类型,例如 `Int` 或 `Nat`,它将与较大的对齐。 \ No newline at end of file +這是設計使然,這樣您就不會無意中將子例程的返回類型與另一種類型混合。 +但是,如果返回值類型選項是具有包含關系的類型,例如 `Int` 或 `Nat`,它將與較大的對齊。 \ No newline at end of file diff --git a/doc/zh_TW/tips.md b/doc/zh_TW/tips.md index 7d8264bc..2ce0240b 100644 --- a/doc/zh_TW/tips.md +++ b/doc/zh_TW/tips.md @@ -1,11 +1,11 @@ # 提示 -## 想要更改显示错误的语言 +## 想要更改顯示錯誤的語言 -请为您的语言下载 Erg。 -但是,外部库可能不支持多种语言。 +請為您的語言下載 Erg。 +但是,外部庫可能不支持多種語言。 -## 只想更改记录的某些属性 +## 只想更改記錄的某些屬性 ```python record: {.name = Str; .age = Nat; .height = CentiMeter} @@ -13,21 +13,21 @@ record: {.name = Str; .age = Nat; .height = CentiMeter} mut_record = {.height = !height; ...rest} ``` -## 想要隐藏变量 +## 想要隱藏變量 -使用 Erg 无法在相同范围内进行遮蔽。 但是,如果范围发生变化,您可以重新定义它们(这是一种称为实例块的语法)。 +使用 Erg 無法在相同范圍內進行遮蔽。 但是,如果范圍發生變化,您可以重新定義它們(這是一種稱為實例塊的語法)。 ````python -## 获取一个 T!-type 对象,最后将它作为 T 类型赋值给一个变量 +## 獲取一個 T!-type 對象,最后將它作為 T 類型賦值給一個變量 x: T = x: T! = foo() x.bar!() x.freeze() ```` -## 想以某种方式重用最终类(不可继承的类) +## 想以某種方式重用最終類(不可繼承的類) -您可以创建一个包装类。 这就是所谓的构图模式。 +您可以創建一個包裝類。 這就是所謂的構圖模式。 ```python FinalWrapper = Class {inner = FinalClass} @@ -37,11 +37,11 @@ FinalWrapper. ... ``` -## 想使用不是字符串的枚举类型 +## 想使用不是字符串的枚舉類型 -可以定义其他语言中常见的传统枚举类型(代数数据类型)如下 -如果您实现“单例”,则类和实例是相同的。 -此外,如果您使用 `Enum`,则选择的类型会自动定义为重定向属性。 +可以定義其他語言中常見的傳統枚舉類型(代數數據類型)如下 +如果您實現“單例”,則類和實例是相同的。 +此外,如果您使用 `Enum`,則選擇的類型會自動定義為重定向屬性。 ```python Ok = Class Impl := Singleton @@ -57,7 +57,7 @@ match! stat: ```python Status = Enum Ok, Err, ErrWithInfo -# 相当于 +# 相當于 Status = Class Ok or Err or ErrWithInfo Status. Ok = Ok @@ -65,7 +65,7 @@ Status. ErrWithInfo = ErrWithInfo ``` -## 我想在1开头枚举 +## 我想在1開頭枚舉 方法一: @@ -83,10 +83,10 @@ for! arr.iter().zip(1...) , i => ... ``` -## 想要测试一个(白盒)非公共 API +## 想要測試一個(白盒)非公共 API -`foo.er` 中的私有 API 可在 `foo.test.er` 模块中特别访问。 -`foo.test.er` 模块无法导入,因此它保持隐藏状态。 +`foo.er` 中的私有 API 可在 `foo.test.er` 模塊中特別訪問。 +`foo.test.er` 模塊無法導入,因此它保持隱藏狀態。 ```python # foo.er @@ -104,9 +104,9 @@ foo = import "foo" ... ``` -## 想定义一个从外部只读的(变量)属性 +## 想定義一個從外部只讀的(變量)屬性 -您可以将属性设为私有并定义一个 getter。 +您可以將屬性設為私有并定義一個 getter。 ```python C = Class {v = Int!} @@ -118,9 +118,9 @@ C. ... ``` -## 希望在类型系统上识别参数名称 +## 希望在類型系統上識別參數名稱 -您可以按记录接收参数。 +您可以按記錄接收參數。 ```python Point = {x = Int; y = Int} @@ -132,4 +132,4 @@ assert norm({x = 1; y = 2}) == norm({y = 2; x = 1}) ## 想要停止警告 -Erg 中没有停止警告的选项(这是设计使然)。 请重写你的代码。 +Erg 中沒有停止警告的選項(這是設計使然)。 請重寫你的代碼。 diff --git a/doc/zh_TW/tools/build.md b/doc/zh_TW/tools/build.md index 7d28452e..2f8fd227 100644 --- a/doc/zh_TW/tools/build.md +++ b/doc/zh_TW/tools/build.md @@ -1,14 +1,14 @@ -# 构建子命令 +# 構建子命令 -build 子命令构建包。 -默认构建中执行的步骤如下: +build 子命令構建包。 +默認構建中執行的步驟如下: -1. 检查注释/文档中的代码(doc 下的 md 文件) -2. 编译打包所需的代码。 -3. 对于应用程序包,生成批处理文件或相当于命令的shell脚本。 -4. 运行测试。 +1. 檢查注釋/文檔中的代碼(doc 下的 md 文件) +2. 編譯打包所需的代碼。 +3. 對于應用程序包,生成批處理文件或相當于命令的shell腳本。 +4. 運行測試。 -构建完成后的交付物输出到以下目录。 +構建完成后的交付物輸出到以下目錄。 -* 在调试构建期间:build/debug -* 对于发布构建:build/release \ No newline at end of file +* 在調試構建期間: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 index ada55481..44e6f30c 100644 --- a/doc/zh_TW/tools/env.md +++ b/doc/zh_TW/tools/env.md @@ -1,7 +1,7 @@ -# 环境子命令 +# 環境子命令 -env 子命令指定 erg 执行环境。 -使用 `erg env new [env name]` 创建一个新的执行环境。 将打开一个交互式工具,当您指定 erg 版本时,将安装该版本的 erg(如果已存在,将使用它),您将能够将其用作新环境。 -您可以使用 `erg env switch [env name]` 切换环境。 -可以使用 `erg env edit` 编辑创建的环境以预安装软件包并指定其他语言的依赖项。 -该命令最大的特点是`erg env export`可以将重现环境的信息输出为`[env name].env.er`文件。 这使您可以立即开始在与其他人相同的环境中进行开发。 此外,`erg env publish` 可以像包一样发布环境。 \ No newline at end of file +env 子命令指定 erg 執行環境。 +使用 `erg env new [env name]` 創建一個新的執行環境。 將打開一個交互式工具,當您指定 erg 版本時,將安裝該版本的 erg(如果已存在,將使用它),您將能夠將其用作新環境。 +您可以使用 `erg env switch [env name]` 切換環境。 +可以使用 `erg env edit` 編輯創建的環境以預安裝軟件包并指定其他語言的依賴項。 +該命令最大的特點是`erg env export`可以將重現環境的信息輸出為`[env name].env.er`文件。 這使您可以立即開始在與其他人相同的環境中進行開發。 此外,`erg env publish` 可以像包一樣發布環境。 \ No newline at end of file diff --git a/doc/zh_TW/tools/fmt.md b/doc/zh_TW/tools/fmt.md index b24ecae8..a7f9ce90 100644 --- a/doc/zh_TW/tools/fmt.md +++ b/doc/zh_TW/tools/fmt.md @@ -1,6 +1,6 @@ # fmt -可以使用 fmt 子命令来完成代码格式化。 -常用的标志有: +可以使用 fmt 子命令來完成代碼格式化。 +常用的標志有: -* 显式类型:在省略类型说明的情况下自动完成。 \ No newline at end of file +* 顯式類型:在省略類型說明的情況下自動完成。 \ No newline at end of file diff --git a/doc/zh_TW/tools/install.md b/doc/zh_TW/tools/install.md index f59145b5..c8a85230 100644 --- a/doc/zh_TW/tools/install.md +++ b/doc/zh_TW/tools/install.md @@ -1,10 +1,10 @@ -# 安装子命令 +# 安裝子命令 -您可以使用 install 安装在注册表站点上注册的软件包。 -基本用法与cargo等包管理器相同。 +您可以使用 install 安裝在注冊表站點上注冊的軟件包。 +基本用法與cargo等包管理器相同。 ## 便利功能 -* 如果有同名的包名,且下载次数超过该包名的10倍以上,会提示可能输入错误。 这可以防止拼写错误。 -* 如果包很大(超过 50MB),请显示大小并建议您是否真的要安装它。 -* 如果包装重复,建议使用替代包装。 \ No newline at end of file +* 如果有同名的包名,且下載次數超過該包名的10倍以上,會提示可能輸入錯誤。 這可以防止拼寫錯誤。 +* 如果包很大(超過 50MB),請顯示大小并建議您是否真的要安裝它。 +* 如果包裝重復,建議使用替代包裝。 \ No newline at end of file diff --git a/doc/zh_TW/tools/pack.md b/doc/zh_TW/tools/pack.md index 59f35f19..8b012a8e 100644 --- a/doc/zh_TW/tools/pack.md +++ b/doc/zh_TW/tools/pack.md @@ -1,21 +1,21 @@ # 包管理器 -Erg 标配有一个包管理器,您可以使用 `pack` 子命令调用它。 -以下是典型的选项。 +Erg 標配有一個包管理器,您可以使用 `pack` 子命令調用它。 +以下是典型的選項。 -* `erg pack init`:将当前目录初始化为一个包。会生成一个 `package.er` 文件和一个 `src` 目录。指定 `app` 将产生一个可执行包,`lib` 将产生一个库包,而 `hybrid` 将产生两个包。如果指定了 `--license`,将自动放置许可文件。 -* `erg pack build`:构建一个包。使用 `--release` 可以运行和优化测试。工件放置在 `build/debug` 或 `build/release` 中。 -* `erg pack install`:安装一个包。在库的情况下,`src` 被放置在 `.erg/lib` 中,而应用程序作为 shell 脚本被放置在 `.erg/app` 中。使用 `--release` 进行优化。 -* `erg pack run`:构建包并运行应用程序(仅限应用程序包)。 -* `erg pack clean`:删除构建目录的内容。 -* `erg pack test`:运行包测试。有关详细信息,请参阅 [test.md](./test.md)。 -* `erg pack publish`:发布/发布包。您将需要一个 GitHub 帐户和公钥。 +* `erg pack init`:將當前目錄初始化為一個包。會生成一個 `package.er` 文件和一個 `src` 目錄。指定 `app` 將產生一個可執行包,`lib` 將產生一個庫包,而 `hybrid` 將產生兩個包。如果指定了 `--license`,將自動放置許可文件。 +* `erg pack build`:構建一個包。使用 `--release` 可以運行和優化測試。工件放置在 `build/debug` 或 `build/release` 中。 +* `erg pack install`:安裝一個包。在庫的情況下,`src` 被放置在 `.erg/lib` 中,而應用程序作為 shell 腳本被放置在 `.erg/app` 中。使用 `--release` 進行優化。 +* `erg pack run`:構建包并運行應用程序(僅限應用程序包)。 +* `erg pack clean`:刪除構建目錄的內容。 +* `erg pack test`:運行包測試。有關詳細信息,請參閱 [test.md](./test.md)。 +* `erg pack publish`:發布/發布包。您將需要一個 GitHub 帳戶和公鑰。 -本文档解释了如何管理您自己的包。 -如果要安装或搜索外部包,请参阅 [install.md](./install.md)。 -另请参阅 [package_system.md](../syntax/33_package_system.md) 了解 Erg 包系统。 +本文檔解釋了如何管理您自己的包。 +如果要安裝或搜索外部包,請參閱 [install.md](./install.md)。 +另請參閱 [package_system.md](../syntax/33_package_system.md) 了解 Erg 包系統。 -## 整个包的标准目录结构(对于应用程序包) +## 整個包的標準目錄結構(對于應用程序包) ```console /package # package root directory @@ -31,70 +31,70 @@ Erg 标配有一个包管理器,您可以使用 `pack` 子命令调用它。 ## package.er -`erg pack init` 将生成如下所示的 `package.er` 文件。 `package.er` 描述了包的配置。 -下面是一个`package.er`的例子。 +`erg pack init` 將生成如下所示的 `package.er` 文件。 `package.er` 描述了包的配置。 +下面是一個`package.er`的例子。 ```python -name = "example" # package 名称 -author = "John Smith" # package 作者名称 +name = "example" # package 名稱 +author = "John Smith" # package 作者名稱 version="0.1.0" description = "An awesome package" -categories = ["cli"] # package 类别 +categories = ["cli"] # package 類別 type = "app" # "app" 或者 "lib" license = "" # 例如"MIT", "APACHE-2.0", "MIT OR Apache-2.0" -pre_build = "" # 构建前要执行的脚本文件名 -post_build = "" # 构建后要执行的脚本文件名 +pre_build = "" # 構建前要執行的腳本文件名 +post_build = "" # 構建后要執行的腳本文件名 dependencies = { - # 如果不指定版本,则选择最新的 - # 如果省略版本说明,包管理器会自动将上次成功构建的版本添加到注释中 - foo = pack("foo") # [INFO] 最后成功构建的版本:1.2.1 + # 如果不指定版本,則選擇最新的 + # 如果省略版本說明,包管理器會自動將上次成功構建的版本添加到注釋中 + foo = pack("foo") # [INFO] 最后成功構建的版本:1.2.1 # 包可以重命名 - bar1 = pack("bar", "1.*.*") # [INFO] 最后成功构建的版本:1.2.0 - bar2 = pack("bar", "2.*.*") # [INFO] 最后成功构建的版本:2.0.0 + bar1 = pack("bar", "1.*.*") # [INFO] 最后成功構建的版本:1.2.0 + bar2 = pack("bar", "2.*.*") # [INFO] 最后成功構建的版本:2.0.0 baz = pack("baz", "1.1.0") } deprecated=False -successors = [] # 替代包(当一个包被弃用时) +successors = [] # 替代包(當一個包被棄用時) ``` -## 语义版本控制 +## 語義版本控制 -Erg 包是基于 [语义版本控制](https://semver.org/lang/en/) 进行版本控制的。 -语义版本控制大致以“x.y.z”格式指定(x、y、z 是大于或等于 0 的整数)。 -每个数字的含义如下。 +Erg 包是基于 [語義版本控制](https://semver.org/lang/en/) 進行版本控制的。 +語義版本控制大致以“x.y.z”格式指定(x、y、z 是大于或等于 0 的整數)。 +每個數字的含義如下。 -* x:主要版本(更新破坏兼容性时增加 1) -* y:次要版本(执行兼容更新时增加1(API添加,弃用等),错误修复等由补丁版本升级处理) -* z:补丁版本(当进行小的更改以修复错误或保持兼容性时增加1,破坏兼容性的严重修复由主要版本升级处理) +* x:主要版本(更新破壞兼容性時增加 1) +* y:次要版本(執行兼容更新時增加1(API添加,棄用等),錯誤修復等由補丁版本升級處理) +* z:補丁版本(當進行小的更改以修復錯誤或保持兼容性時增加1,破壞兼容性的嚴重修復由主要版本升級處理) -但是,默认情况下,版本 `0.*.*` 中的更改始终是不兼容的。如果要在保持兼容性的同时升级,请在其后指定 `-compatible`(Erg 自己的规则)。例如,如果要在保持与 0.2.1 兼容的同时添加功能,即要升级到 0.3.0,则指定 0.3.0-compatible。如果您已修复错误,还请指定“0.2.2-compatible”。 -该版本将被视为与以前的版本兼容。 -即使您想将 `0.*.*` 升级到 `1.0.0`,这仍然有效。也就是说,`1.0.0-compatible` 与之前的版本 `0.y.z` 兼容。 +但是,默認情況下,版本 `0.*.*` 中的更改始終是不兼容的。如果要在保持兼容性的同時升級,請在其后指定 `-compatible`(Erg 自己的規則)。例如,如果要在保持與 0.2.1 兼容的同時添加功能,即要升級到 0.3.0,則指定 0.3.0-compatible。如果您已修復錯誤,還請指定“0.2.2-compatible”。 +該版本將被視為與以前的版本兼容。 +即使您想將 `0.*.*` 升級到 `1.0.0`,這仍然有效。也就是說,`1.0.0-compatible` 與之前的版本 `0.y.z` 兼容。 -生成锁文件时,语义版本控制非常重要。锁定文件是为保持依赖项兼容而生成的文件,因此除非明确更新,否则较新版本的依赖项依赖于较旧的包。 -当多人开发具有依赖包的包时,锁定文件很有用。它还通过允许依赖于它们的包在兼容的情况下重用包来节省本地存储。 +生成鎖文件時,語義版本控制非常重要。鎖定文件是為保持依賴項兼容而生成的文件,因此除非明確更新,否則較新版本的依賴項依賴于較舊的包。 +當多人開發具有依賴包的包時,鎖定文件很有用。它還通過允許依賴于它們的包在兼容的情況下重用包來節省本地存儲。 -Erg 的包管理器严格执行这些规则,并将拒绝违反这些规则的包更新。 -Erg 包管理器与版本控制系统(例如 git)一起使用,以检测代码差异并在发布包时验证版本控制的正确性。 -具体来说,包管理器会查看 API 的类型。如果类型是旧版本的子类型,则认为更改是兼容的(请注意,这不是完整的验证;类型兼容但语义上不兼容的重大更改是可能的,这是开发人员的工作来确定这一点)。 +Erg 的包管理器嚴格執行這些規則,并將拒絕違反這些規則的包更新。 +Erg 包管理器與版本控制系統(例如 git)一起使用,以檢測代碼差異并在發布包時驗證版本控制的正確性。 +具體來說,包管理器會查看 API 的類型。如果類型是舊版本的子類型,則認為更改是兼容的(請注意,這不是完整的驗證;類型兼容但語義上不兼容的重大更改是可能的,這是開發人員的工作來確定這一點)。 -此外,由于整个包存储库都在注册表中注册,即使是开发人员也无法在不通过包管理器的情况下更新包。 -此外,包可以被弃用但不能被删除。 +此外,由于整個包存儲庫都在注冊表中注冊,即使是開發人員也無法在不通過包管理器的情況下更新包。 +此外,包可以被棄用但不能被刪除。 -### 附录:语义版本控制问题和对策 +### 附錄:語義版本控制問題和對策 -语义版本控制存在(至少)两个已知问题。 -首先,语义版本控制可能过于严格。 -使用语义版本控制,单个不兼容的 API 更改会增加整个包的主要版本。 -发生这种情况时,诸如“我想尝试一个新的 API,但我必须处理另一个不兼容的 API 更改,所以我不会升级”之类的事情。 -其次,语义版本控制可以承诺太多。 -如上一节所述,对 API 的“兼容更改”在理论上是不可证明的。如果您指定要使用版本为 `1.0.1` 的包,则可以在语义版本控制方面使用 `1.0.1` 和 `2.0.0` 之间的任何包(`1.0.0` 不能被使用,因为错误已被修复),但由于包开发人员无意使用 API,构建可能不会成功。 +語義版本控制存在(至少)兩個已知問題。 +首先,語義版本控制可能過于嚴格。 +使用語義版本控制,單個不兼容的 API 更改會增加整個包的主要版本。 +發生這種情況時,諸如“我想嘗試一個新的 API,但我必須處理另一個不兼容的 API 更改,所以我不會升級”之類的事情。 +其次,語義版本控制可以承諾太多。 +如上一節所述,對 API 的“兼容更改”在理論上是不可證明的。如果您指定要使用版本為 `1.0.1` 的包,則可以在語義版本控制方面使用 `1.0.1` 和 `2.0.0` 之間的任何包(`1.0.0` 不能被使用,因為錯誤已被修復),但由于包開發人員無意使用 API,構建可能不會成功。 -Erg 通过允许同时使用不同版本的包(通过重命名)解决了这个问题。这使得在部分引入 ver2 API 的同时继续使用 ver1 API 成为可能。 -此外,虽然这不是一个非常理想的状态,但如果只能使用 API 的某个次要版本而没有错误,则可以不理会它并继续前进到下一个版本。 +Erg 通過允許同時使用不同版本的包(通過重命名)解決了這個問題。這使得在部分引入 ver2 API 的同時繼續使用 ver1 API 成為可能。 +此外,雖然這不是一個非常理想的狀態,但如果只能使用 API 的某個次要版本而沒有錯誤,則可以不理會它并繼續前進到下一個版本。 -## 发布 +## 發布 -可以使用 `publish` 子命令发布包。发布需要 GitHub 帐户。 -默认情况下,包使用 `(owner_name)/(package_name)` 注册。如果满足一定条件(下载次数、维护频率等),可以申请注册一个省略所有者名称的别名。 -请注意,包名称不区分大小写,并且不区分诸如 `_` 和 `-` 之类的分隔符。 \ No newline at end of file +可以使用 `publish` 子命令發布包。發布需要 GitHub 帳戶。 +默認情況下,包使用 `(owner_name)/(package_name)` 注冊。如果滿足一定條件(下載次數、維護頻率等),可以申請注冊一個省略所有者名稱的別名。 +請注意,包名稱不區分大小寫,并且不區分諸如 `_` 和 `-` 之類的分隔符。 \ No newline at end of file diff --git a/doc/zh_TW/tools/repl.md b/doc/zh_TW/tools/repl.md index 94fab78f..2f02a483 100644 --- a/doc/zh_TW/tools/repl.md +++ b/doc/zh_TW/tools/repl.md @@ -1,9 +1,9 @@ # REPL -运行不带参数的 `erg` 命令会调用 REPL。 它也可以用 `repl` 子命令调用。 -此外,您可以指定以下标志: +運行不帶參數的 `erg` 命令會調用 REPL。 它也可以用 `repl` 子命令調用。 +此外,您可以指定以下標志: -* typed:显示对象及其类型。 +* typed:顯示對象及其類型。 ```console $ erg repl --typed diff --git a/doc/zh_TW/tools/test.md b/doc/zh_TW/tools/test.md index 278035c4..237826e8 100644 --- a/doc/zh_TW/tools/test.md +++ b/doc/zh_TW/tools/test.md @@ -1,11 +1,11 @@ -# 测试子命令 +# 測試子命令 -erg 命令有一个名为 test 的子命令,它支持测试的实现和执行。 +erg 命令有一個名為 test 的子命令,它支持測試的實現和執行。 -## 测试装饰器 (@Test) +## 測試裝飾器 (@Test) -Erg 使用 `erg test` 命令测试包中 `tests` 目录或 `*.test.er` 文件中的 `@Test` 子例程。 -`tests` 子例程负责黑盒测试(不测试私有函数),`*.test.er` 子例程负责白盒测试(也测试私有函数)。 +Erg 使用 `erg test` 命令測試包中 `tests` 目錄或 `*.test.er` 文件中的 `@Test` 子例程。 +`tests` 子例程負責黑盒測試(不測試私有函數),`*.test.er` 子例程負責白盒測試(也測試私有函數)。 ```python # tests/test1.er @@ -16,13 +16,13 @@ test_1_plus_n(n: Nat) = assert add(1, n) == n + 1 ``` -执行结果以摘要形式显示,可以以各种文件格式(.md、.csv 等)输出。 +執行結果以摘要形式顯示,可以以各種文件格式(.md、.csv 等)輸出。 -## 文档测试 +## 文檔測試 -在 Erg 中,`#` 和 `#[` 是注释行,但 `##` 和 `#[[` 是 doc 注释,并且注释可以从 VSCode 等编辑器显示为 markdown。 -此外,如果指定了 erg,则使用 erg test 命令自动测试文档注释中的源代码。 -下面是一个示例测试。 +在 Erg 中,`#` 和 `#[` 是注釋行,但 `##` 和 `#[[` 是 doc 注釋,并且注釋可以從 VSCode 等編輯器顯示為 markdown。 +此外,如果指定了 erg,則使用 erg test 命令自動測試文檔注釋中的源代碼。 +下面是一個示例測試。 ```python VMs =... @@ -30,7 +30,7 @@ VMs =... #[[ execute commands. ```python - # 标准配置的虚拟机 + # 標準配置的虛擬機 {vm1; ...} = import "tests/mock" assert vm1.exec!("i = 0") == None @@ -42,4 +42,4 @@ VMs =... ... ``` -用于测试的模拟对象(mock objects)在 `tests/mock` 模块中定义。 \ No newline at end of file +用于測試的模擬對象(mock objects)在 `tests/mock` 模塊中定義。 \ No newline at end of file From 61752a2d836f1a750c448a0d0e7e159110258d21 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Mon, 5 Sep 2022 21:44:59 +0800 Subject: [PATCH 28/42] trifle --- doc/EN/syntax/00_basic.md | 2 -- doc/zh_CN/syntax/00_basic.md | 2 -- doc/zh_TW/syntax/00_basic.md | 2 -- 3 files changed, 6 deletions(-) diff --git a/doc/EN/syntax/00_basic.md b/doc/EN/syntax/00_basic.md index 651caf2f..09b98fb7 100644 --- a/doc/EN/syntax/00_basic.md +++ b/doc/EN/syntax/00_basic.md @@ -2,8 +2,6 @@ > __Warning__: This document is incomplete. It has not been proofread (style, correct links, mistranslation, etc.). Also, Erg's syntax may be change destructively during version 0.*, and the documentation may not have been updated accordingly. Please be aware of this beforehand. > If you find any errors in this document, please report then to [here form](https://forms.gle/HtLYRfYzWCAaeTGb6) or [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new). We would appreciate your suggestions. -> -> [The Erg book original version (Japanese)](http://mtshiba.me/TheErgBook/) This document describes the basic syntax of Erg. The [Standard API](./API/index.md) and [internal documents for Erg contributors](./dev_guide/index.md) are located in another directory. diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md index b640f7fc..bb438d9a 100644 --- a/doc/zh_CN/syntax/00_basic.md +++ b/doc/zh_CN/syntax/00_basic.md @@ -2,8 +2,6 @@ > __Warning__:本文档不完整。 它未经校对(样式、正确链接、误译等)。 此外,Erg 的语法可能在版本 0.* 期间发生破坏性更改,并且文档可能没有相应更新。 请事先了解这一点。 > 如果您在本文档中发现任何错误,请报告至 [此处的表单](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我们将不胜感激您的建议。 -> -> [Erg原版(日文)](http://mtshiba.me/TheErgBook/) 本文档描述 Erg 的基本语法。 [标准 API](./API/index.md) 和 [Erg 贡献者的内部文档](./dev_guide/index.md) 位于另一个目录中。 diff --git a/doc/zh_TW/syntax/00_basic.md b/doc/zh_TW/syntax/00_basic.md index 0353c0fa..21a26fd2 100644 --- a/doc/zh_TW/syntax/00_basic.md +++ b/doc/zh_TW/syntax/00_basic.md @@ -2,8 +2,6 @@ > __Warning__:本文檔不完整。 它未經校對(樣式、正確鏈接、誤譯等)。 此外,Erg 的語法可能在版本 0.* 期間發生破壞性更改,并且文檔可能沒有相應更新。 請事先了解這一點。 > 如果您在本文檔中發現任何錯誤,請報告至 [此處的表單](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我們將不勝感激您的建議。 -> -> [Erg原版(日文)](http://mtshiba.me/TheErgBook/) 本文檔描述 Erg 的基本語法。 [標準 API](./API/index.md) 和 [Erg 貢獻者的內部文檔](./dev_guide/index.md) 位于另一個目錄中。 From 7172fccca066d4a1d6d3fc18f4045476f6ff01e3 Mon Sep 17 00:00:00 2001 From: GreasySlug <9619abgoni@gmail.com> Date: Tue, 6 Sep 2022 09:27:02 +0900 Subject: [PATCH 29/42] Fixed to change hash value of README --- README_JA.md | 4 ++-- README_zh-CN.md | 4 ++-- README_zh-TW.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README_JA.md b/README_JA.md index 9a626107..c51931a2 100644 --- a/README_JA.md +++ b/README_JA.md @@ -13,8 +13,8 @@ English | 日本語 | 简体中文 | 繁體中文

-[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D46ffc45c6890d939b97fb5aa18338d554d3a8696) -](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=46ffc45c6890d939b97fb5aa18338d554d3a8696) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D585ebe9d59fb2190c8c3aeca49d53385a5f7e256) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=585ebe9d59fb2190c8c3aeca49d53385a5f7e256) ## Ergはこんな人におすすめです: diff --git a/README_zh-CN.md b/README_zh-CN.md index a28be190..51c678a0 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -13,8 +13,8 @@ English | 日本語 | 简体中文 | 繁體中文

-[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D46ffc45c6890d939b97fb5aa18338d554d3a8696) -](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=46ffc45c6890d939b97fb5aa18338d554d3a8696) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D585ebe9d59fb2190c8c3aeca49d53385a5f7e256) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=585ebe9d59fb2190c8c3aeca49d53385a5f7e256) ## Erg可以推荐给以下人员: diff --git a/README_zh-TW.md b/README_zh-TW.md index 639055ab..c649ded3 100644 --- a/README_zh-TW.md +++ b/README_zh-TW.md @@ -13,8 +13,8 @@ English | 日本語 | 简体中文 | 繁體中文

-[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D46ffc45c6890d939b97fb5aa18338d554d3a8696) -](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=46ffc45c6890d939b97fb5aa18338d554d3a8696) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D585ebe9d59fb2190c8c3aeca49d53385a5f7e256) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=585ebe9d59fb2190c8c3aeca49d53385a5f7e256) ## Erg可以推薦給以下人員: From 538789cd5fdd1411c1c5706371f6e4279db484e9 Mon Sep 17 00:00:00 2001 From: GreasySlug <9619abgoni@gmail.com> Date: Tue, 6 Sep 2022 09:27:46 +0900 Subject: [PATCH 30/42] Update to ja doc to put translation badges --- doc/JA/API/consts.md | 2 ++ doc/JA/API/funcs.md | 2 ++ doc/JA/API/index.md | 2 ++ doc/JA/API/modules/external/alstruct.md | 2 ++ doc/JA/API/modules/repl.md | 2 ++ doc/JA/API/modules/status.md | 2 ++ doc/JA/API/modules/unit.md | 2 ++ doc/JA/API/modules/unsound.md | 2 ++ doc/JA/API/operators.md | 2 ++ doc/JA/API/procs.md | 2 ++ doc/JA/API/special.md | 2 ++ doc/JA/API/types.md | 2 ++ doc/JA/API/types/classes/Array!(T).md | 2 ++ doc/JA/API/types/classes/Array(T).md | 2 ++ doc/JA/API/types/classes/ArrayWithLen(T,N).md | 2 ++ doc/JA/API/types/classes/ArrayWithMutLength!(T,N).md | 2 ++ doc/JA/API/types/classes/Class.md | 2 ++ doc/JA/API/types/classes/Complex.md | 2 ++ doc/JA/API/types/classes/Dict!.md | 2 ++ doc/JA/API/types/classes/Either.md | 2 ++ doc/JA/API/types/classes/Float.md | 2 ++ doc/JA/API/types/classes/Function(N).md | 2 ++ doc/JA/API/types/classes/Inf.md | 2 ++ doc/JA/API/types/classes/Int.md | 2 ++ doc/JA/API/types/classes/IntRange.md | 2 ++ doc/JA/API/types/classes/Interval.md | 2 ++ doc/JA/API/types/classes/Iterator.md | 2 ++ doc/JA/API/types/classes/Kind(N).md | 2 ++ doc/JA/API/types/classes/Matrix.md | 2 ++ doc/JA/API/types/classes/Module.md | 2 ++ doc/JA/API/types/classes/Nat.md | 2 ++ doc/JA/API/types/classes/Neg.md | 2 ++ doc/JA/API/types/classes/Never.md | 2 ++ doc/JA/API/types/classes/NonZero.md | 2 ++ doc/JA/API/types/classes/Object.md | 2 ++ doc/JA/API/types/classes/Operator.md | 2 ++ doc/JA/API/types/classes/Option.md | 2 ++ doc/JA/API/types/classes/Pos.md | 2 ++ doc/JA/API/types/classes/Ratio.md | 2 ++ doc/JA/API/types/classes/Record.md | 2 ++ doc/JA/API/types/classes/Result.md | 2 ++ doc/JA/API/types/classes/Str!.md | 2 ++ doc/JA/API/types/classes/Str.md | 2 ++ doc/JA/API/types/classes/StrWithLen.md | 2 ++ doc/JA/API/types/classes/Subroutine.md | 2 ++ doc/JA/API/types/classes/Tensor.md | 2 ++ doc/JA/API/types/classes/TransCell(T).md | 2 ++ doc/JA/API/types/classes/Tuple.md | 2 ++ doc/JA/API/types/classes/Type.md | 2 ++ doc/JA/API/types/classes/Vector.md | 2 ++ doc/JA/API/types/patches/BinOp.md | 2 ++ doc/JA/API/types/patches/UnaryOp.md | 2 ++ doc/JA/API/types/traits/Add(R,O).md | 2 ++ doc/JA/API/types/traits/Div(R,O).md | 2 ++ doc/JA/API/types/traits/Eq.md | 2 ++ doc/JA/API/types/traits/Into.md | 2 ++ doc/JA/API/types/traits/Iterable.md | 2 ++ doc/JA/API/types/traits/Num.md | 2 ++ doc/JA/API/types/traits/Ord.md | 2 ++ doc/JA/API/types/traits/SafeDiv(R,O).md | 2 ++ doc/JA/API/types/traits/Sample.md | 2 ++ doc/JA/API/types/traits/Seq.md | 2 ++ doc/JA/API/types/traits/Show.md | 2 ++ doc/JA/API/types/traits/Unpack.md | 2 ++ doc/JA/compiler/TODO_hint.md | 2 ++ doc/JA/compiler/TODO_recov_suggest.md | 2 ++ doc/JA/compiler/TODO_warn.md | 2 ++ doc/JA/compiler/abandoned.md | 2 ++ doc/JA/compiler/architecture.md | 2 ++ doc/JA/compiler/errors.md | 2 ++ doc/JA/compiler/hir.md | 2 ++ doc/JA/compiler/index.md | 2 ++ doc/JA/compiler/inference.md | 2 ++ doc/JA/compiler/overview.md | 2 ++ doc/JA/compiler/parsing.md | 2 ++ doc/JA/compiler/refinement_subtyping.md | 2 ++ doc/JA/compiler/trait_method_resolving.md | 2 ++ doc/JA/compiler/transpile.md | 2 ++ doc/JA/compiler/type_var_normalization.md | 2 ++ doc/JA/dev_guide/branches.md | 2 ++ doc/JA/dev_guide/build_features.md | 2 ++ doc/JA/dev_guide/directories.md | 2 ++ doc/JA/dev_guide/doc_guideline.md | 2 ++ doc/JA/dev_guide/env.md | 2 ++ doc/JA/dev_guide/faq_syntax.md | 2 ++ doc/JA/dev_guide/i18n_messages.md | 2 ++ doc/JA/dev_guide/index.md | 2 ++ doc/JA/dev_guide/rust_code_guideline.md | 2 ++ doc/JA/dev_guide/terms.md | 2 ++ doc/JA/dev_guide/unify_terms.md | 2 ++ doc/JA/faq_general.md | 2 ++ doc/JA/faq_technical.md | 2 ++ doc/JA/improved_points.md | 2 ++ doc/JA/index.md | 2 ++ doc/JA/migration_from_py.md | 2 ++ doc/JA/python/bytecode_instructions.md | 2 ++ doc/JA/python/bytecode_specification.md | 2 ++ doc/JA/python/class_system.md | 2 ++ doc/JA/python/index.md | 2 ++ doc/JA/syntax/00_basic.md | 2 ++ doc/JA/syntax/01_literal.md | 2 ++ doc/JA/syntax/02_name.md | 2 ++ doc/JA/syntax/03_declaration.md | 2 ++ doc/JA/syntax/04_function.md | 2 ++ doc/JA/syntax/05_builtin_funcs.md | 2 ++ doc/JA/syntax/06_operator.md | 2 ++ doc/JA/syntax/07_side_effect.md | 2 ++ doc/JA/syntax/08_procedure.md | 2 ++ doc/JA/syntax/09_builtin_procs.md | 2 ++ doc/JA/syntax/10_array.md | 2 ++ doc/JA/syntax/11_tuple.md | 2 ++ doc/JA/syntax/12_dict.md | 2 ++ doc/JA/syntax/13_record.md | 2 ++ doc/JA/syntax/14_set.md | 2 ++ doc/JA/syntax/15_type.md | 2 ++ doc/JA/syntax/16_iterator.md | 2 ++ doc/JA/syntax/17_mutability.md | 2 ++ doc/JA/syntax/18_ownership.md | 2 ++ doc/JA/syntax/19_visibility.md | 2 ++ doc/JA/syntax/20_naming_rule.md | 2 ++ doc/JA/syntax/21_lambda.md | 2 ++ doc/JA/syntax/22_subroutine.md | 2 ++ doc/JA/syntax/23_closure.md | 2 ++ doc/JA/syntax/24_module.md | 2 ++ doc/JA/syntax/25_object_system.md | 2 ++ doc/JA/syntax/26_pattern_matching.md | 2 ++ doc/JA/syntax/27_comprehension.md | 2 ++ doc/JA/syntax/28_spread_syntax.md | 2 ++ doc/JA/syntax/29_decorator.md | 2 ++ doc/JA/syntax/30_error_handling.md | 2 ++ doc/JA/syntax/31_pipeline.md | 2 ++ doc/JA/syntax/32_integration_with_Python.md | 2 ++ doc/JA/syntax/33_package_system.md | 2 ++ doc/JA/syntax/34_generator.md | 2 ++ doc/JA/syntax/SUMMARY.md | 2 ++ doc/JA/syntax/container_ownership.md | 2 ++ doc/JA/syntax/indexes.md | 2 ++ doc/JA/syntax/quick_tour.md | 2 ++ doc/JA/syntax/type/01_type_system.md | 2 ++ doc/JA/syntax/type/02_basic.md | 2 ++ doc/JA/syntax/type/03_trait.md | 2 ++ doc/JA/syntax/type/04_class.md | 2 ++ doc/JA/syntax/type/05_inheritance.md | 2 ++ doc/JA/syntax/type/06_nst_vs_sst.md | 2 ++ doc/JA/syntax/type/07_patch.md | 2 ++ doc/JA/syntax/type/08_value.md | 2 ++ doc/JA/syntax/type/09_attributive.md | 2 ++ doc/JA/syntax/type/10_interval.md | 2 ++ doc/JA/syntax/type/11_enum.md | 2 ++ doc/JA/syntax/type/12_refinement.md | 2 ++ doc/JA/syntax/type/13_algebraic.md | 2 ++ doc/JA/syntax/type/14_dependent.md | 2 ++ doc/JA/syntax/type/15_quantified.md | 2 ++ doc/JA/syntax/type/16_subtyping.md | 2 ++ doc/JA/syntax/type/17_type_casting.md | 2 ++ doc/JA/syntax/type/18_mut.md | 2 ++ doc/JA/syntax/type/19_bound.md | 2 ++ doc/JA/syntax/type/advanced.md | 2 ++ doc/JA/syntax/type/advanced/GADTs.md | 2 ++ doc/JA/syntax/type/advanced/_rank2type.md | 2 ++ doc/JA/syntax/type/advanced/default_param.md | 2 ++ doc/JA/syntax/type/advanced/erasure.md | 2 ++ doc/JA/syntax/type/advanced/existential.md | 2 ++ doc/JA/syntax/type/advanced/keyword_param.md | 2 ++ doc/JA/syntax/type/advanced/kind.md | 2 ++ doc/JA/syntax/type/advanced/marker_trait.md | 2 ++ doc/JA/syntax/type/advanced/mut_struct.md | 2 ++ doc/JA/syntax/type/advanced/newtype.md | 2 ++ doc/JA/syntax/type/advanced/overloading.md | 2 ++ doc/JA/syntax/type/advanced/phantom.md | 2 ++ doc/JA/syntax/type/advanced/projection.md | 2 ++ doc/JA/syntax/type/advanced/quantified_dependent.md | 2 ++ doc/JA/syntax/type/advanced/shared.md | 2 ++ doc/JA/syntax/type/advanced/special.md | 2 ++ doc/JA/syntax/type/advanced/typeof.md | 2 ++ doc/JA/syntax/type/advanced/variance.md | 2 ++ doc/JA/syntax/type/advanced/widening.md | 2 ++ doc/JA/tips.md | 2 ++ doc/JA/tools/build.md | 2 ++ doc/JA/tools/env.md | 2 ++ doc/JA/tools/fmt.md | 2 ++ doc/JA/tools/index.md | 2 ++ doc/JA/tools/install.md | 2 ++ doc/JA/tools/pack.md | 2 ++ doc/JA/tools/repl.md | 2 ++ doc/JA/tools/test.md | 2 ++ 186 files changed, 372 insertions(+) diff --git a/doc/JA/API/consts.md b/doc/JA/API/consts.md index 60453cd8..d208c55c 100644 --- a/doc/JA/API/consts.md +++ b/doc/JA/API/consts.md @@ -1,5 +1,7 @@ # 組み込み定数 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/consts.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/consts.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## True ## False diff --git a/doc/JA/API/funcs.md b/doc/JA/API/funcs.md index 671a7e99..e96b00cd 100644 --- a/doc/JA/API/funcs.md +++ b/doc/JA/API/funcs.md @@ -1,5 +1,7 @@ # 関数 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/funcs.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/funcs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 基本関数 ### if|T; U|(cond: Bool, then: T, else: U) -> T or U diff --git a/doc/JA/API/index.md b/doc/JA/API/index.md index e69de29b..77223195 100644 --- a/doc/JA/API/index.md +++ b/doc/JA/API/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/index.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/API/modules/external/alstruct.md b/doc/JA/API/modules/external/alstruct.md index ce7573f8..70f194e4 100644 --- a/doc/JA/API/modules/external/alstruct.md +++ b/doc/JA/API/modules/external/alstruct.md @@ -1,5 +1,7 @@ # alstruct +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/external/alstruct.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/external/alstruct.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 代数的構造を表すトレイトや、それにかかるパッチを提供するモジュール。 * member diff --git a/doc/JA/API/modules/repl.md b/doc/JA/API/modules/repl.md index 696fee1e..5199ad86 100644 --- a/doc/JA/API/modules/repl.md +++ b/doc/JA/API/modules/repl.md @@ -1,5 +1,7 @@ # module `repl` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/repl.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/repl.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + provides REPL(Read-Eval-Print-Loop)-related APIs. ## functions diff --git a/doc/JA/API/modules/status.md b/doc/JA/API/modules/status.md index 345da026..a08c1c87 100644 --- a/doc/JA/API/modules/status.md +++ b/doc/JA/API/modules/status.md @@ -1,5 +1,7 @@ # module `status` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/status.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/status.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 状態を表す型が定義されています。状況に応じて選択肢を外したりして使用してください。 * ExecResult = {"success", "warning", "failure", "fatal", "unknown"} diff --git a/doc/JA/API/modules/unit.md b/doc/JA/API/modules/unit.md index 2672ff06..36b90682 100644 --- a/doc/JA/API/modules/unit.md +++ b/doc/JA/API/modules/unit.md @@ -1,5 +1,7 @@ # module `unit` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/unit.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unit.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `unit`モジュールは数値計算でよく使われる単位を型として定義したモジュールです。 Ergの数値型は`Nat`, `Int`, `Ratio`などがあります。しかしこれらの型は「何を意味する数値なのか」という情報を持っておらず、メートルとヤード同士の足し算などといったナンセンスな計算を行えてしまいます。 `unit`モジュールを使うことにより、単位の違う数値を関数に渡すといったミスを防げます。 diff --git a/doc/JA/API/modules/unsound.md b/doc/JA/API/modules/unsound.md index 592b4222..ad026aa6 100644 --- a/doc/JA/API/modules/unsound.md +++ b/doc/JA/API/modules/unsound.md @@ -1,5 +1,7 @@ # module `unsound` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/unsound.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unsound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Provides APIs perform unsound and unsafe operations that cannot be guaranteed safe in Erg's type system. ## `unsafe!` diff --git a/doc/JA/API/operators.md b/doc/JA/API/operators.md index 66dbade4..37de6705 100644 --- a/doc/JA/API/operators.md +++ b/doc/JA/API/operators.md @@ -1,5 +1,7 @@ # 演算子 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/operators.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/operators.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## 中置演算子 ### `_+_`|R; O; A <: Add(R, O)|(x: A, y: R) -> O diff --git a/doc/JA/API/procs.md b/doc/JA/API/procs.md index 999b30c4..a0cb26a3 100644 --- a/doc/JA/API/procs.md +++ b/doc/JA/API/procs.md @@ -1,5 +1,7 @@ # プロシージャ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/procs.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/procs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## print! ```python diff --git a/doc/JA/API/special.md b/doc/JA/API/special.md index 766adffc..7841e142 100644 --- a/doc/JA/API/special.md +++ b/doc/JA/API/special.md @@ -1,5 +1,7 @@ # 特殊形式(Special form) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/special.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 特殊形式は、Ergの型システムでは表現ができない演算子、サブルーチン(のようなもの)である。``で囲っているが、実際は捕捉できない。 また、`Pattern`や`Body`, `Conv`といった型が便宜上登場するが、そのような型が存在するわけではない。その意味もコンテクストによって異なる。 diff --git a/doc/JA/API/types.md b/doc/JA/API/types.md index 60b7e9d0..b8208f26 100644 --- a/doc/JA/API/types.md +++ b/doc/JA/API/types.md @@ -1,5 +1,7 @@ # Erg組み込み型一覧 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 型自体の属性は`.__dict__`の中には格納されていないので、インスタンスからは参照できない ## 汎用型 (Fundamental types) diff --git a/doc/JA/API/types/classes/Array!(T).md b/doc/JA/API/types/classes/Array!(T).md index 76044b45..74b46f12 100644 --- a/doc/JA/API/types/classes/Array!(T).md +++ b/doc/JA/API/types/classes/Array!(T).md @@ -1,4 +1,6 @@ # Array! T +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Array!(T).md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array!(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 可変長配列を表す型。コンパイル時に長さがわからない場合に使う。`[T]!`という糖衣構文がある。 `Array! T = ArrayWithMutLength! T, !_`で定義される。 diff --git a/doc/JA/API/types/classes/Array(T).md b/doc/JA/API/types/classes/Array(T).md index 59cae131..e594de2d 100644 --- a/doc/JA/API/types/classes/Array(T).md +++ b/doc/JA/API/types/classes/Array(T).md @@ -1,3 +1,5 @@ # Array T: Type +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Array(T).md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + `Array T = ArrayWithLen T, _`で定義される。`[T]`という糖衣構文がある。 diff --git a/doc/JA/API/types/classes/ArrayWithLen(T,N).md b/doc/JA/API/types/classes/ArrayWithLen(T,N).md index 7b21972d..35be9e60 100644 --- a/doc/JA/API/types/classes/ArrayWithLen(T,N).md +++ b/doc/JA/API/types/classes/ArrayWithLen(T,N).md @@ -1,5 +1,7 @@ # ArrayWithLen T: Type, N: Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/ArrayWithLen(T,N).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithLen(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `[T; N]`は糖衣構文。長さを省いた[`Array`型](./Array.md)もある。 ## methods diff --git a/doc/JA/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/JA/API/types/classes/ArrayWithMutLength!(T,N).md index 1012d84e..b0e2032b 100644 --- a/doc/JA/API/types/classes/ArrayWithMutLength!(T,N).md +++ b/doc/JA/API/types/classes/ArrayWithMutLength!(T,N).md @@ -1,5 +1,7 @@ # ArrayWithMutLength! T: Type, N: Nat! +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/ArrayWithMutLength!(T,N).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + コンパイル時に長さのわかる可変長配列。`ArrayWithMutLength(T, !N) == [T; !N]`という糖衣構文もある。 ## methods diff --git a/doc/JA/API/types/classes/Class.md b/doc/JA/API/types/classes/Class.md index e69de29b..8cad7741 100644 --- a/doc/JA/API/types/classes/Class.md +++ b/doc/JA/API/types/classes/Class.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Class.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Class.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/API/types/classes/Complex.md b/doc/JA/API/types/classes/Complex.md index 10dcb3cd..f4e5f39c 100644 --- a/doc/JA/API/types/classes/Complex.md +++ b/doc/JA/API/types/classes/Complex.md @@ -1,5 +1,7 @@ # Complex +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Complex.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Complex.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 複素数を表す型です。Ergで数字を表す型、例えばFloatやInt、Natなどは、大抵この型を上位に持ちます。 ## supers diff --git a/doc/JA/API/types/classes/Dict!.md b/doc/JA/API/types/classes/Dict!.md index 302af630..611f1bcb 100644 --- a/doc/JA/API/types/classes/Dict!.md +++ b/doc/JA/API/types/classes/Dict!.md @@ -1,5 +1,7 @@ # Dict! K, V +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Dict!.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Dict!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 辞書(ハッシュマップ)を表す型。`{K: V}`という構文糖が存在する。 ## methods diff --git a/doc/JA/API/types/classes/Either.md b/doc/JA/API/types/classes/Either.md index bcde0468..08118628 100644 --- a/doc/JA/API/types/classes/Either.md +++ b/doc/JA/API/types/classes/Either.md @@ -1,5 +1,7 @@ # Either L, R = L or R +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Either.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Either.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 「LかRかどちらか」を表す型。Or型の2つ限定形と考えて良い。 ## methods diff --git a/doc/JA/API/types/classes/Float.md b/doc/JA/API/types/classes/Float.md index a874c3cf..2129c03a 100644 --- a/doc/JA/API/types/classes/Float.md +++ b/doc/JA/API/types/classes/Float.md @@ -1,5 +1,7 @@ # Float size +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Float.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Float.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 実数(小数を含む数)を表す型です。IEEE 754に準拠した浮動小数点数を表し、他の言語では一般的にfloatに相当する型です。 Float sizeのsizeは、8(1byte)~128(16byte)となります。単にFloatとした場合`Float 64`を表します。 Ergでの0.1は実はFloat型ではなく、Ratio型に属します。Float型のリテラルは存在せず、`(Ratioオブジェクト)f64`(e.g. (1/2)f64, 15f64)で生成します。f64は実数の1に対応します。 diff --git a/doc/JA/API/types/classes/Function(N).md b/doc/JA/API/types/classes/Function(N).md index 24195350..12bfbc21 100644 --- a/doc/JA/API/types/classes/Function(N).md +++ b/doc/JA/API/types/classes/Function(N).md @@ -1,5 +1,7 @@ # Function N: Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Function(N).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Function(N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## methods of Function 1 * then(self, g: Self) -> Self diff --git a/doc/JA/API/types/classes/Inf.md b/doc/JA/API/types/classes/Inf.md index 45e579bc..ff37119e 100644 --- a/doc/JA/API/types/classes/Inf.md +++ b/doc/JA/API/types/classes/Inf.md @@ -1,5 +1,7 @@ # Inf +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Inf.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Inf.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Infはinfただひとつをインスタンスとするクラスである。 infの主な使いみちは、区間型での使用である。 例えば、2以上の整数型は`2.. Type ``` diff --git a/doc/JA/API/types/classes/Matrix.md b/doc/JA/API/types/classes/Matrix.md index a4803e45..ec17e2f3 100644 --- a/doc/JA/API/types/classes/Matrix.md +++ b/doc/JA/API/types/classes/Matrix.md @@ -1,5 +1,7 @@ # Matrix T: Num, Shape: [M, N] +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Matrix.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Matrix.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 行列を表す型です。Tensor [M, N]を継承しています。 ## def diff --git a/doc/JA/API/types/classes/Module.md b/doc/JA/API/types/classes/Module.md index 03b89e9f..98d15409 100644 --- a/doc/JA/API/types/classes/Module.md +++ b/doc/JA/API/types/classes/Module.md @@ -1,3 +1,5 @@ # Module +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Module.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Module.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## methods diff --git a/doc/JA/API/types/classes/Nat.md b/doc/JA/API/types/classes/Nat.md index 1ea213e2..cba3e242 100644 --- a/doc/JA/API/types/classes/Nat.md +++ b/doc/JA/API/types/classes/Nat.md @@ -1,5 +1,7 @@ # Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Nat.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Nat.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 自然数を表す型。配列のインデックスや範囲型などで使われる。 ## def diff --git a/doc/JA/API/types/classes/Neg.md b/doc/JA/API/types/classes/Neg.md index f11db34f..ed0cc039 100644 --- a/doc/JA/API/types/classes/Neg.md +++ b/doc/JA/API/types/classes/Neg.md @@ -1,5 +1,7 @@ # Neg +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Neg.md%26commit_hash%3D290c43b09f7c3036112a164bed5fd07a1f6a5cda)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Neg.md&commit_hash=290c43b09f7c3036112a164bed5fd07a1f6a5cda) + 負の整数を表す型です。Pos and Neg and {0} == Intとなります。 ゼロ除算が起きない、Neg * Neg == Posとなるなど、いくつか特筆すべき性質も持っています。 diff --git a/doc/JA/API/types/classes/Never.md b/doc/JA/API/types/classes/Never.md index a403d83e..c4c2fc5c 100644 --- a/doc/JA/API/types/classes/Never.md +++ b/doc/JA/API/types/classes/Never.md @@ -1,5 +1,7 @@ # Never +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Never.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Never.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 全ての型の下位型である。全てのメソッドを持っており、当然`.new`も持っているため`Class`である。しかしインスタンスは持たず、生成されそうになった瞬間にErgは停止する。 `Panic`という同じくインスタンスを持たない型が存在するが、正常に終了する際や意図的な無限ループの際は`Never`、異常終了する際には`Panic`を使う。 diff --git a/doc/JA/API/types/classes/NonZero.md b/doc/JA/API/types/classes/NonZero.md index d6e3c41e..345271d5 100644 --- a/doc/JA/API/types/classes/NonZero.md +++ b/doc/JA/API/types/classes/NonZero.md @@ -1,5 +1,7 @@ # NonZero N +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/NonZero.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/NonZero.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ゼロではない数を表すクラスです。ゼロ除算の安全性が保証されます。 ```mermaid diff --git a/doc/JA/API/types/classes/Object.md b/doc/JA/API/types/classes/Object.md index 26935cb4..c61d25cf 100644 --- a/doc/JA/API/types/classes/Object.md +++ b/doc/JA/API/types/classes/Object.md @@ -1,5 +1,7 @@ # Object +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Object.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Object.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 全ての型の上位型である。 ## methods diff --git a/doc/JA/API/types/classes/Operator.md b/doc/JA/API/types/classes/Operator.md index 9c45b70b..21caabb0 100644 --- a/doc/JA/API/types/classes/Operator.md +++ b/doc/JA/API/types/classes/Operator.md @@ -1,5 +1,7 @@ # Operator [...T], O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Operator.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Operator.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 演算子の型です。 ## def diff --git a/doc/JA/API/types/classes/Option.md b/doc/JA/API/types/classes/Option.md index 8bfa15e2..847225ab 100644 --- a/doc/JA/API/types/classes/Option.md +++ b/doc/JA/API/types/classes/Option.md @@ -1,5 +1,7 @@ # Option T = T or NoneType +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Option.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Option.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 「失敗するかもしれない」を表す型。 ## methods diff --git a/doc/JA/API/types/classes/Pos.md b/doc/JA/API/types/classes/Pos.md index dbade292..9be74c6b 100644 --- a/doc/JA/API/types/classes/Pos.md +++ b/doc/JA/API/types/classes/Pos.md @@ -1,5 +1,7 @@ # Pos +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Pos.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Pos.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Posは正数(1以上の整数)を表す型です。 0が入らないので、ゼロ除算の可能性を排除できるなどのメリットがあります。 diff --git a/doc/JA/API/types/classes/Ratio.md b/doc/JA/API/types/classes/Ratio.md index 70e5f8d7..d4bd5dd1 100644 --- a/doc/JA/API/types/classes/Ratio.md +++ b/doc/JA/API/types/classes/Ratio.md @@ -1,5 +1,7 @@ # Ratio +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Ratio.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Ratio.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 有理数を表す型です。主に、分数を使いたいときに使います。 実はErgでの/演算子はRatioを返します。1/3などは0.33333...とは評価されず1/3のまま処理されます。また、0.1は1/10と等価です。なので、`0.1 + 0.2 == 0.3`となります。当たり前のように聞こえますが、PythonではなんとFalseになります。 とはいえ、Ratio型はFloat型に比べて若干効率が下がる傾向があります。そこまで正確な数値は要らず、かつ実行速度が重要となるポイントではFloat型を使用するといいでしょう。とはいえ、Rob Pikeが言うように早すぎる最適化は諸悪の根源です。Ratio型を捨ててFloat型を使用するのは実際にパフォーマンステストを行ってからにしましょう。素人ほど無条件に軽量な型を好みます。 diff --git a/doc/JA/API/types/classes/Record.md b/doc/JA/API/types/classes/Record.md index 6babe571..f5956e5b 100644 --- a/doc/JA/API/types/classes/Record.md +++ b/doc/JA/API/types/classes/Record.md @@ -1,5 +1,7 @@ # Record +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Record.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Record.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + レコードの属するクラス。例えば`{i = 1}`は`Structural {i = Int}`型などの要素であり、`{i = Int}`クラスのインスタンスである。 他のクラスのインスタンスはレコード型の要素であってもレコードクラスのインスタンスではないことに注意。 diff --git a/doc/JA/API/types/classes/Result.md b/doc/JA/API/types/classes/Result.md index c4c4dc00..98b4ef50 100644 --- a/doc/JA/API/types/classes/Result.md +++ b/doc/JA/API/types/classes/Result.md @@ -1,5 +1,7 @@ # Result T, E +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Result.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Result.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python Result T, E <: Error = Either T, E ``` diff --git a/doc/JA/API/types/classes/Str!.md b/doc/JA/API/types/classes/Str!.md index 7e4bd67b..22a97976 100644 --- a/doc/JA/API/types/classes/Str!.md +++ b/doc/JA/API/types/classes/Str!.md @@ -1,3 +1,5 @@ # StrWithLen! N: Nat! = Inherit StrWithLen N +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Str!.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 可変長文字列を表す型。 diff --git a/doc/JA/API/types/classes/Str.md b/doc/JA/API/types/classes/Str.md index 7adcc18c..5735aac2 100644 --- a/doc/JA/API/types/classes/Str.md +++ b/doc/JA/API/types/classes/Str.md @@ -1,5 +1,7 @@ # Str +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Str.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + (不変長)文字列を表す型。単なる`Str`型は`StrWithLen N`型から文字数の情報を落とした型である(`Str = StrWithLen _`)。 ## methods diff --git a/doc/JA/API/types/classes/StrWithLen.md b/doc/JA/API/types/classes/StrWithLen.md index e69de29b..67caca65 100644 --- a/doc/JA/API/types/classes/StrWithLen.md +++ b/doc/JA/API/types/classes/StrWithLen.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/StrWithLen.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/StrWithLen.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/API/types/classes/Subroutine.md b/doc/JA/API/types/classes/Subroutine.md index 1305de92..2ad5e354 100644 --- a/doc/JA/API/types/classes/Subroutine.md +++ b/doc/JA/API/types/classes/Subroutine.md @@ -1,5 +1,7 @@ # Subroutine +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Subroutine.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Subroutine.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + FuncやProcの基底型です。 ## methods diff --git a/doc/JA/API/types/classes/Tensor.md b/doc/JA/API/types/classes/Tensor.md index d3468f41..764aa527 100644 --- a/doc/JA/API/types/classes/Tensor.md +++ b/doc/JA/API/types/classes/Tensor.md @@ -1,5 +1,7 @@ # Tensor Shape: [Nat; N] +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Tensor.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tensor.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 多次元配列を効率的に操作するためのクラス。多次元配列に対する積などの演算も定義する。 Matrix, Vectorなどはこの型を継承している。 diff --git a/doc/JA/API/types/classes/TransCell(T).md b/doc/JA/API/types/classes/TransCell(T).md index d23cbde8..14727194 100644 --- a/doc/JA/API/types/classes/TransCell(T).md +++ b/doc/JA/API/types/classes/TransCell(T).md @@ -1,5 +1,7 @@ # TransCell! T: Type! +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/TransCell(T).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/TransCell(T).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 中身を型ごと変えられるセルです。T型のサブタイプとなるので、T型としても振る舞います。 初期化時点ではT型で、ある時点以降はずっとU型、といった場合に便利です。 diff --git a/doc/JA/API/types/classes/Tuple.md b/doc/JA/API/types/classes/Tuple.md index 891b9bae..542aae1e 100644 --- a/doc/JA/API/types/classes/Tuple.md +++ b/doc/JA/API/types/classes/Tuple.md @@ -1,5 +1,7 @@ # Tuple T: ...Type +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Tuple.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tuple.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 複数の型のオブジェクトを保持するコレクション。 ## methods diff --git a/doc/JA/API/types/classes/Type.md b/doc/JA/API/types/classes/Type.md index e69de29b..dae4a5c2 100644 --- a/doc/JA/API/types/classes/Type.md +++ b/doc/JA/API/types/classes/Type.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Type.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/API/types/classes/Vector.md b/doc/JA/API/types/classes/Vector.md index cfe0337e..3214edd2 100644 --- a/doc/JA/API/types/classes/Vector.md +++ b/doc/JA/API/types/classes/Vector.md @@ -1,3 +1,5 @@ # Vector T: Num, N: Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Vector.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Vector.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ベクトルを表す型です。RustやC++などの同名の型と違い、この型が扱うのは数値専用です。 diff --git a/doc/JA/API/types/patches/BinOp.md b/doc/JA/API/types/patches/BinOp.md index 85ee08dd..0a647266 100644 --- a/doc/JA/API/types/patches/BinOp.md +++ b/doc/JA/API/types/patches/BinOp.md @@ -1,5 +1,7 @@ # BinOp L, R, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/patches/BinOp.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/BinOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 二項演算子の型です。 ## Patches diff --git a/doc/JA/API/types/patches/UnaryOp.md b/doc/JA/API/types/patches/UnaryOp.md index 8128dab2..1abb984f 100644 --- a/doc/JA/API/types/patches/UnaryOp.md +++ b/doc/JA/API/types/patches/UnaryOp.md @@ -1,5 +1,7 @@ # UnaryOp T, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/patches/UnaryOp.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/UnaryOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 単項演算子の型です。 ## def diff --git a/doc/JA/API/types/traits/Add(R,O).md b/doc/JA/API/types/traits/Add(R,O).md index 003a0936..7cbf0690 100644 --- a/doc/JA/API/types/traits/Add(R,O).md +++ b/doc/JA/API/types/traits/Add(R,O).md @@ -1,5 +1,7 @@ # Add R +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Add(R,O).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Add(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python Add R = Trait { .AddO = Type diff --git a/doc/JA/API/types/traits/Div(R,O).md b/doc/JA/API/types/traits/Div(R,O).md index f6e940a3..42f7c065 100644 --- a/doc/JA/API/types/traits/Div(R,O).md +++ b/doc/JA/API/types/traits/Div(R,O).md @@ -1,5 +1,7 @@ # Div R, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Div(R,O).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Div(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ゼロ除算によるエラーがない場合は`SafeDiv`を使ってください。 ```python diff --git a/doc/JA/API/types/traits/Eq.md b/doc/JA/API/types/traits/Eq.md index e69de29b..6aed2ae0 100644 --- a/doc/JA/API/types/traits/Eq.md +++ b/doc/JA/API/types/traits/Eq.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Eq.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Eq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/API/types/traits/Into.md b/doc/JA/API/types/traits/Into.md index 9151f047..a1f7bf31 100644 --- a/doc/JA/API/types/traits/Into.md +++ b/doc/JA/API/types/traits/Into.md @@ -1,5 +1,7 @@ # Into T +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Into.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Into.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + T型に型変換可能であることを示す型です。 SelfとTの間に継承関係などがなくても、互いに変換可能な関係であるときに定義します。 継承と違い暗黙には変換が行われません。必ず`.into`メソッドを呼び出す必要があります。 diff --git a/doc/JA/API/types/traits/Iterable.md b/doc/JA/API/types/traits/Iterable.md index e69de29b..ba458258 100644 --- a/doc/JA/API/types/traits/Iterable.md +++ b/doc/JA/API/types/traits/Iterable.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Iterable.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Iterable.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/API/types/traits/Num.md b/doc/JA/API/types/traits/Num.md index 377da536..e6584efb 100644 --- a/doc/JA/API/types/traits/Num.md +++ b/doc/JA/API/types/traits/Num.md @@ -1,5 +1,7 @@ # Num +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Num.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Num.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## definition ```python diff --git a/doc/JA/API/types/traits/Ord.md b/doc/JA/API/types/traits/Ord.md index e69de29b..3ef5f04a 100644 --- a/doc/JA/API/types/traits/Ord.md +++ b/doc/JA/API/types/traits/Ord.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Ord.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Ord.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/API/types/traits/SafeDiv(R,O).md b/doc/JA/API/types/traits/SafeDiv(R,O).md index 998faf89..03595643 100644 --- a/doc/JA/API/types/traits/SafeDiv(R,O).md +++ b/doc/JA/API/types/traits/SafeDiv(R,O).md @@ -1,5 +1,7 @@ # SafeDiv R, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/SafeDiv(R,O).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/SafeDiv(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python SafeDiv R, O = Subsume Div, { @Override diff --git a/doc/JA/API/types/traits/Sample.md b/doc/JA/API/types/traits/Sample.md index cfb8a954..450a4cee 100644 --- a/doc/JA/API/types/traits/Sample.md +++ b/doc/JA/API/types/traits/Sample.md @@ -1,5 +1,7 @@ # Sample +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Sample.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Sample.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + インスタンスを「適当に」選出する`sample`メソッドと`sample!`メソッドを持つトレイト。`sample`メソッドは常に同じインスタンスを返し、`sample!`メソッドは呼び出しごとに変わる適当なインスタンスを返す。 これはテストなどで適当なインスタンスがほしい場合を想定したトレイトであり、必ずしも無作為ではないことに注意が必要である。無作為抽出が必要な場合は`random`モジュールを使用する。 diff --git a/doc/JA/API/types/traits/Seq.md b/doc/JA/API/types/traits/Seq.md index e69de29b..007f7134 100644 --- a/doc/JA/API/types/traits/Seq.md +++ b/doc/JA/API/types/traits/Seq.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Seq.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Seq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/API/types/traits/Show.md b/doc/JA/API/types/traits/Show.md index e69de29b..30763e02 100644 --- a/doc/JA/API/types/traits/Show.md +++ b/doc/JA/API/types/traits/Show.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Show.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Show.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/API/types/traits/Unpack.md b/doc/JA/API/types/traits/Unpack.md index 0d259217..3b705fb8 100644 --- a/doc/JA/API/types/traits/Unpack.md +++ b/doc/JA/API/types/traits/Unpack.md @@ -1,5 +1,7 @@ # Unpack +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Unpack.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Unpack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + マーカートレイト。実装すると、レコードのようにパターンマッチで要素を分解できる。 ```python diff --git a/doc/JA/compiler/TODO_hint.md b/doc/JA/compiler/TODO_hint.md index 3844f83f..76edb2cd 100644 --- a/doc/JA/compiler/TODO_hint.md +++ b/doc/JA/compiler/TODO_hint.md @@ -1,4 +1,6 @@ # Hint (not implemented) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/TODO_hint.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_hint.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * `x is not defined` (x was deleted by `Del`) => `hint: deleted in line X` * patch method duplication: "hint: Specify patch (like `T.foo(1)`) or delete either `.foo` using `Del`" diff --git a/doc/JA/compiler/TODO_recov_suggest.md b/doc/JA/compiler/TODO_recov_suggest.md index a11955fa..92d04c7c 100644 --- a/doc/JA/compiler/TODO_recov_suggest.md +++ b/doc/JA/compiler/TODO_recov_suggest.md @@ -1,5 +1,7 @@ # Error recovery suggestions (not implemented yet) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/TODO_recov_suggest.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_recov_suggest.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * `1 or 2`, `1 and 2` => `{1, 2}`? * `U = Inherit T` => Non-class type cannot be inherited, or `U = Class T`? * `Int and Str` => Multiple inheritance is not allowed, or `Int or Str`? diff --git a/doc/JA/compiler/TODO_warn.md b/doc/JA/compiler/TODO_warn.md index 0ba2ebf2..e03ffd4f 100644 --- a/doc/JA/compiler/TODO_warn.md +++ b/doc/JA/compiler/TODO_warn.md @@ -1,5 +1,7 @@ # warnings (not implemented yet) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/TODO_warn.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_warn.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * `t = {(record type)}` => `T = {(record type)}`? (only types defined as constants can be used for type specification) * `{I: Int | ...}!` => `{I: Int! | ...}` * `return x`(`x != ()`) in for/while block => `f::return` (outer block)? diff --git a/doc/JA/compiler/abandoned.md b/doc/JA/compiler/abandoned.md index 19bfe876..623476d9 100644 --- a/doc/JA/compiler/abandoned.md +++ b/doc/JA/compiler/abandoned.md @@ -1,5 +1,7 @@ # 放棄・却下された言語仕様 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/abandoned.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/abandoned.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## オーバーロード(アドホック多相) パラメトリック+サブタイピング多相で代替できること、Pythonの意味論との相性の悪さなどを理由に放棄された。詳しくは[overload](../syntax/type/overloading.md)の記事を参照。 diff --git a/doc/JA/compiler/architecture.md b/doc/JA/compiler/architecture.md index bbed005d..abafdcef 100644 --- a/doc/JA/compiler/architecture.md +++ b/doc/JA/compiler/architecture.md @@ -1,5 +1,7 @@ # ergc のアーキテクチャ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/architecture.md%26commit_hash%3Da711efa99b325ba1012f6897e7b0e2bdb947d8a1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/architecture.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1) + ## 1. Erg スクリプト (.er) をスキャンし、`TokenStream` (parser/lex.rs) を生成する * parser/lexer/Lexer が `TokenStream` を生成する (これは `Token` のイテレータである。`TokenStream` は `Lexer::collect()` によって生成できる) diff --git a/doc/JA/compiler/errors.md b/doc/JA/compiler/errors.md index 8a583dca..5cfbe4c6 100644 --- a/doc/JA/compiler/errors.md +++ b/doc/JA/compiler/errors.md @@ -1,5 +1,7 @@ # Erg Compiler Errors +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/errors.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/errors.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## AssignError イミュータブル変数を書き換えようとすると発生します。 diff --git a/doc/JA/compiler/hir.md b/doc/JA/compiler/hir.md index 20ca1bf2..0e8b5262 100644 --- a/doc/JA/compiler/hir.md +++ b/doc/JA/compiler/hir.md @@ -1,5 +1,7 @@ # 高レベル中間表現(HIR, High-level Intermediate Representation) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/hir.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/hir.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + HIRはErgコンパイラがASTから生成する構造体です。 この構造体にはソースコード中のあらゆる式の完全な型情報が含まれており、また構文糖が脱糖されています。 ASTは(プレーンテキストとしての)ソースコードと一対一対応しますが、HIRは不要なコードの情報が除去されていたり、また省略された型情報が付記されたりしているため、HIRからソースコードを復元することは困難です。 diff --git a/doc/JA/compiler/index.md b/doc/JA/compiler/index.md index e69de29b..33522b77 100644 --- a/doc/JA/compiler/index.md +++ b/doc/JA/compiler/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/index.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/compiler/inference.md b/doc/JA/compiler/inference.md index 3a6cb04e..c189965c 100644 --- a/doc/JA/compiler/inference.md +++ b/doc/JA/compiler/inference.md @@ -1,5 +1,7 @@ # 型推論アルゴリズム +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/inference.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/inference.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + > __Warning__: この項は編集中であり、一部に間違いを含む可能性があります。 以下で用いる表記方法を示します。 diff --git a/doc/JA/compiler/overview.md b/doc/JA/compiler/overview.md index 0536bfce..d64ad9d5 100644 --- a/doc/JA/compiler/overview.md +++ b/doc/JA/compiler/overview.md @@ -1,5 +1,7 @@ # `erg`の概観 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/overview.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/overview.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 各レイヤーの働きと特に重要な関数、メソッドを紹介します。 ## 1. 字句解析 diff --git a/doc/JA/compiler/parsing.md b/doc/JA/compiler/parsing.md index 815b6624..f9cc8989 100644 --- a/doc/JA/compiler/parsing.md +++ b/doc/JA/compiler/parsing.md @@ -1,5 +1,7 @@ # Erg言語の構文解析 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/parsing.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/parsing.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 空白の扱い Ergの文法において特異なのは、space-sensitive(空白による区別がある)である点である。 diff --git a/doc/JA/compiler/refinement_subtyping.md b/doc/JA/compiler/refinement_subtyping.md index 82cd8341..16646bca 100644 --- a/doc/JA/compiler/refinement_subtyping.md +++ b/doc/JA/compiler/refinement_subtyping.md @@ -1,5 +1,7 @@ # 篩型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/refinement_subtyping.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/refinement_subtyping.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 篩型とは、以下のような型である。 ```python diff --git a/doc/JA/compiler/trait_method_resolving.md b/doc/JA/compiler/trait_method_resolving.md index 723aeb64..3b4cf570 100644 --- a/doc/JA/compiler/trait_method_resolving.md +++ b/doc/JA/compiler/trait_method_resolving.md @@ -1,5 +1,7 @@ # パッチメソッドの解決 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/trait_method_resolving.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/trait_method_resolving.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `Nat`は0以上の`Int`、つまり`Int`のサブタイプである。 本来`Nat`はPythonのクラス階層には存在しない。Ergはこのパッチのメソッドをどうやって解決するのだろうか? diff --git a/doc/JA/compiler/transpile.md b/doc/JA/compiler/transpile.md index aab468fa..61cd54fe 100644 --- a/doc/JA/compiler/transpile.md +++ b/doc/JA/compiler/transpile.md @@ -1,5 +1,7 @@ # ErgコードはPythonコードにどのようにトランスパイルされるか? +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/transpile.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/transpile.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 正確には、ErgコードはPythonバイトコードにトランスパイルされます。 しかしPythonバイトコードはほぼPythonコードに復元できるので、ここでは等価なPythonコードを例として上げています。 ちなみに、ここで紹介する例は最適化レベルの低いものです。 diff --git a/doc/JA/compiler/type_var_normalization.md b/doc/JA/compiler/type_var_normalization.md index 66bb2962..2a2e46cc 100644 --- a/doc/JA/compiler/type_var_normalization.md +++ b/doc/JA/compiler/type_var_normalization.md @@ -1,5 +1,7 @@ # 正規化 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/type_var_normalization.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/type_var_normalization.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * Ergの型引数正規化はSymPyのsimplify関数を参考にしています。 例えば`concat: |T, M, N|([T; M], [T; N] -> [T; M+N])`を定義するとき、型変数・引数を具体化せずに一致判定を行わなくてはならない。 diff --git a/doc/JA/dev_guide/branches.md b/doc/JA/dev_guide/branches.md index 600efce5..12d422b6 100644 --- a/doc/JA/dev_guide/branches.md +++ b/doc/JA/dev_guide/branches.md @@ -1,5 +1,7 @@ # ブランチの命名と運用方針 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/branches.md%26commit_hash%3Da711efa99b325ba1012f6897e7b0e2bdb947d8a1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/branches.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1) + * 基本的に開発は`main`ブランチ一本で行う(モノレポ開発)。どうしてもブランチを切らないと作業しにくい場合のみ`feature-*`ブランチか`issue-*`ブランチを作成する。 ## main diff --git a/doc/JA/dev_guide/build_features.md b/doc/JA/dev_guide/build_features.md index c78abb3e..77d7a93a 100644 --- a/doc/JA/dev_guide/build_features.md +++ b/doc/JA/dev_guide/build_features.md @@ -1,5 +1,7 @@ # `erg` build features +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/build_features.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/build_features.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## debug デバッグモードにする。これにより、Erg内部での挙動が逐次ログ表示される。 diff --git a/doc/JA/dev_guide/directories.md b/doc/JA/dev_guide/directories.md index 1eb0c60c..8f0e5b6d 100644 --- a/doc/JA/dev_guide/directories.md +++ b/doc/JA/dev_guide/directories.md @@ -1,5 +1,7 @@ # Ergリポジトリのディレクトリ構造 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/directories.md%26commit_hash%3Da711efa99b325ba1012f6897e7b0e2bdb947d8a1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/directories.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1) + ```console └─┬ assets: 画像など ├─ CODE_OF_CONDUCT: 行動規範 diff --git a/doc/JA/dev_guide/doc_guideline.md b/doc/JA/dev_guide/doc_guideline.md index abcc87a2..1af3a61b 100644 --- a/doc/JA/dev_guide/doc_guideline.md +++ b/doc/JA/dev_guide/doc_guideline.md @@ -1,5 +1,7 @@ # 書式 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/doc_guideline.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/doc_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 以下のルールに従っていないドキュメントはすべて修正の対象となる。 * コードコメント、または内部用のドキュメントは、である調で書く。 diff --git a/doc/JA/dev_guide/env.md b/doc/JA/dev_guide/env.md index c85aa280..1d4bdb77 100644 --- a/doc/JA/dev_guide/env.md +++ b/doc/JA/dev_guide/env.md @@ -1,5 +1,7 @@ # 開発環境 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/env.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## インストールが必要なもの * Rust (installed with rustup) diff --git a/doc/JA/dev_guide/faq_syntax.md b/doc/JA/dev_guide/faq_syntax.md index 8dea551e..59456aeb 100644 --- a/doc/JA/dev_guide/faq_syntax.md +++ b/doc/JA/dev_guide/faq_syntax.md @@ -1,5 +1,7 @@ # Erg design's "Why" and Answers +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/faq_syntax.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/faq_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## なぜ所有権システムがあるのにGCも共存させているのですか? Ergが所有権システムを導入した動機は、Rustのような「GCに頼らないメモリ管理」のためではないからです。 diff --git a/doc/JA/dev_guide/i18n_messages.md b/doc/JA/dev_guide/i18n_messages.md index 51fd8fb5..312d2553 100644 --- a/doc/JA/dev_guide/i18n_messages.md +++ b/doc/JA/dev_guide/i18n_messages.md @@ -1,5 +1,7 @@ # メッセージの多言語化 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/i18n_messages.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/i18n_messages.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Ergはメッセージ(スタート、オプション、ドキュメント、ヒント、警告、エラーメッセージなど)の多言語化を進めています。 このプロジェクトは、RustやErgの詳しい知識がなくても参加することができます。ぜひ協力をお願いします。 diff --git a/doc/JA/dev_guide/index.md b/doc/JA/dev_guide/index.md index 8b137891..5406f3f8 100644 --- a/doc/JA/dev_guide/index.md +++ b/doc/JA/dev_guide/index.md @@ -1 +1,3 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/index.md%26commit_hash%3D7d43acdf0e2b71528b038b9a8e70be6c93831f96)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/index.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96) + diff --git a/doc/JA/dev_guide/rust_code_guideline.md b/doc/JA/dev_guide/rust_code_guideline.md index cf090732..01f62696 100644 --- a/doc/JA/dev_guide/rust_code_guideline.md +++ b/doc/JA/dev_guide/rust_code_guideline.md @@ -1,5 +1,7 @@ # Rustコードに関するガイドライン +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/rust_code_guideline.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/rust_code_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## ローカルルール * デバッグ用の出力には`log!`を使用する(release時にも必要な出力処理は`println!`等を使用する)。 diff --git a/doc/JA/dev_guide/terms.md b/doc/JA/dev_guide/terms.md index 7d5677f6..c47fd4e2 100644 --- a/doc/JA/dev_guide/terms.md +++ b/doc/JA/dev_guide/terms.md @@ -1,5 +1,7 @@ # 用語辞典 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/terms.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 記号 ### ! diff --git a/doc/JA/dev_guide/unify_terms.md b/doc/JA/dev_guide/unify_terms.md index e6e71220..a85fe9e4 100644 --- a/doc/JA/dev_guide/unify_terms.md +++ b/doc/JA/dev_guide/unify_terms.md @@ -1,5 +1,7 @@ # 用語の統一 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/unify_terms.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/unify_terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## Accessibility, Visibility (参照性、可視性) Visibility(可視性)を使用する。 diff --git a/doc/JA/faq_general.md b/doc/JA/faq_general.md index 9d2b4fac..f950b405 100644 --- a/doc/JA/faq_general.md +++ b/doc/JA/faq_general.md @@ -1,5 +1,7 @@ # Erg FAQ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/faq_general.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_general.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + このFAQは一般のErg入門者向けです。 個別の(よくある)技術的な問題については[こちら](./faq_technical.md)を、文法の決定経緯(なぜこのような文法になったのか)などについては [こちら](./dev_guide/why.md)を参照してください。 diff --git a/doc/JA/faq_technical.md b/doc/JA/faq_technical.md index affbc713..70a42fde 100644 --- a/doc/JA/faq_technical.md +++ b/doc/JA/faq_technical.md @@ -1,5 +1,7 @@ # 技術的なFAQ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/faq_technical.md%26commit_hash%3Dc120700585fdb1d655255c8e2817bb13cc8d369e)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_technical.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e) + 本項はErg言語を使用する上での技術的な質問に答えるものです。すなわち、WhatやWhichで始まる質問、Yes/Noで答えられる質問を載せています。 根本的な文法の決定経緯については[こちら](./dev_guide/faq_syntax.md)を、なぜこの言語を作ったのか、この機能はどのように実装されているのかなど、より大きな話題は[こちら](./dev_guide/../faq_general.md)を参照してください。 diff --git a/doc/JA/improved_points.md b/doc/JA/improved_points.md index eb3d7f51..1bf003ca 100644 --- a/doc/JA/improved_points.md +++ b/doc/JA/improved_points.md @@ -1,5 +1,7 @@ # Pythonから改良された点 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/improved_points.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/improved_points.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## 静的解析を行う(静的型チェック、変数・プロパティチェック) 静的型チェックの恩恵は今更強調するまでもないほどですが、変数・プロパティの存在チェックもかなり効いてくる部分です。 diff --git a/doc/JA/index.md b/doc/JA/index.md index db3516f8..fa32a045 100644 --- a/doc/JA/index.md +++ b/doc/JA/index.md @@ -1,5 +1,7 @@ # Index +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/index.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/index.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## [API/](./API/index.md) Ergの組み込みまたは標準ライブラリで提供されるサブルーチン、型、定数等の仕様が記述されている。 diff --git a/doc/JA/migration_from_py.md b/doc/JA/migration_from_py.md index 4f1daf8c..f04421f0 100644 --- a/doc/JA/migration_from_py.md +++ b/doc/JA/migration_from_py.md @@ -1,5 +1,7 @@ # PythonからErgへの移行に関してのTips +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/migration_from_py.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/migration_from_py.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 文字列をint等に変換したい `Str`クラスの`parse`メソッドを使用してください。これは`Result`型を返します。 diff --git a/doc/JA/python/bytecode_instructions.md b/doc/JA/python/bytecode_instructions.md index 6e625360..6724701a 100644 --- a/doc/JA/python/bytecode_instructions.md +++ b/doc/JA/python/bytecode_instructions.md @@ -1,5 +1,7 @@ # Python Bytecode Instructions +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/bytecode_instructions.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_instructions.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Python bytecodeの変数操作系の命令はnamei (name index)を通してアクセスされる。これは、Pythonの動的変数アクセス(evalなどを使い、文字列でアクセスできる)を実現するためである。 1命令は2byteで、命令、引数がlittle endianで格納されている。 引数を取らない命令も2byte使っている(引数部は0)。 diff --git a/doc/JA/python/bytecode_specification.md b/doc/JA/python/bytecode_specification.md index cf52911d..80306797 100644 --- a/doc/JA/python/bytecode_specification.md +++ b/doc/JA/python/bytecode_specification.md @@ -1,5 +1,7 @@ # Python bytecode specification +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/bytecode_specification.md%26commit_hash%3D9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_specification.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4) + ## Format * 0~3 byte(u32): magic number (see common/bytecode.rs for details) diff --git a/doc/JA/python/class_system.md b/doc/JA/python/class_system.md index 8bed4851..158a5340 100644 --- a/doc/JA/python/class_system.md +++ b/doc/JA/python/class_system.md @@ -1,5 +1,7 @@ # Pythonのクラスシステム(Ergとの比較) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/class_system.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/class_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## メソッド メソッドは前方参照していてもかまわないが、これは特別なテクニックが使われているわけではなく、 diff --git a/doc/JA/python/index.md b/doc/JA/python/index.md index e69de29b..2168ad9d 100644 --- a/doc/JA/python/index.md +++ b/doc/JA/python/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/index.md%26commit_hash%3D9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/index.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4) + diff --git a/doc/JA/syntax/00_basic.md b/doc/JA/syntax/00_basic.md index d2cb5332..21aada11 100644 --- a/doc/JA/syntax/00_basic.md +++ b/doc/JA/syntax/00_basic.md @@ -1,5 +1,7 @@ # 基本事項 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/00_basic.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + > __Warning__: 本ドキュメントは未完成です。校正(文体、正しいリンクが張られているか、など)がなされていません。また、Ergの文法はバージョン0.*の間に破壊的変更が加えられる可能性があり、それに伴うドキュメントの更新が追いついていない可能性があります。予めご了承ください。 > また、本ドキュメントの誤りを見つけた場合は、[こちらのフォーム](https://forms.gle/HtLYRfYzWCAaeTGb6)または[GitHubリポジトリ](https://github.com/mtshiba/TheErgBook/issues/new)から修正の提案をしていただけると幸いです。 diff --git a/doc/JA/syntax/01_literal.md b/doc/JA/syntax/01_literal.md index 6db8d8a5..06161971 100644 --- a/doc/JA/syntax/01_literal.md +++ b/doc/JA/syntax/01_literal.md @@ -1,5 +1,7 @@ # Literal +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/01_literal.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/01_literal.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 基本的なリテラル ### 整数リテラル(Int Literal) diff --git a/doc/JA/syntax/02_name.md b/doc/JA/syntax/02_name.md index 7bb732d9..17a5056d 100644 --- a/doc/JA/syntax/02_name.md +++ b/doc/JA/syntax/02_name.md @@ -1,5 +1,7 @@ # 変数 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/02_name.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 変数は代数の一種です。Ergにおける代数―紛れがなければ単に変数と呼ばれることもあります―とは、オブジェクトを名前付けしてコード中の別の場所から利用できるようにする機能を指します。 変数は以下のように定義します。 diff --git a/doc/JA/syntax/03_declaration.md b/doc/JA/syntax/03_declaration.md index 2278a3dc..cf17bf5d 100644 --- a/doc/JA/syntax/03_declaration.md +++ b/doc/JA/syntax/03_declaration.md @@ -1,5 +1,7 @@ # Declaration(宣言) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/03_declaration.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/03_declaration.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 宣言は、使用する変数の型を指定する構文です。 宣言はコード中のどこでも可能ですが、宣言しただけでその変数を参照することはできません。必ず初期化する必要があります。 代入後の宣言では、代入されたオブジェクトと型が適合するかをチェック可能です。 diff --git a/doc/JA/syntax/04_function.md b/doc/JA/syntax/04_function.md index e0262688..0f756cba 100644 --- a/doc/JA/syntax/04_function.md +++ b/doc/JA/syntax/04_function.md @@ -1,5 +1,7 @@ # 関数 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/04_function.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/04_function.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 関数は「引数」を受け取ってそれを加工し、「戻り値」として返すブロックです。以下のように定義します。 ```python diff --git a/doc/JA/syntax/05_builtin_funcs.md b/doc/JA/syntax/05_builtin_funcs.md index e0f973e0..37f3e091 100644 --- a/doc/JA/syntax/05_builtin_funcs.md +++ b/doc/JA/syntax/05_builtin_funcs.md @@ -1,5 +1,7 @@ # 組み込み関数 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/05_builtin_funcs.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/05_builtin_funcs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## if `if`は条件に応じて処理を変える関数です。 diff --git a/doc/JA/syntax/06_operator.md b/doc/JA/syntax/06_operator.md index 6747385d..7a00011b 100644 --- a/doc/JA/syntax/06_operator.md +++ b/doc/JA/syntax/06_operator.md @@ -1,5 +1,7 @@ # 演算子 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/06_operator.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/06_operator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 演算子(オペレーター)は、演算を表す記号です。被演算子(オペランド)は演算子の(左)右にあるもので、Ergでは専らオブジェクトです。 演算子は関数の一種であり、したがってそれ自体も第一級オブジェクトで変数に束縛できます。束縛の際は``で囲む必要があります。 diff --git a/doc/JA/syntax/07_side_effect.md b/doc/JA/syntax/07_side_effect.md index 7c1e5b76..a7fcfe57 100644 --- a/doc/JA/syntax/07_side_effect.md +++ b/doc/JA/syntax/07_side_effect.md @@ -1,5 +1,7 @@ # 副作用とプロシージャ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/07_side_effect.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/07_side_effect.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + これまで`print!`の`!`の意味を説明せずにいましたが、いよいよその意味が明かされます。この!は、ズバリこのオブジェクトが「副作用」のある「プロシージャ」であることを示しています。プロシージャは関数に「副作用」という効果を与えたものです。 ```python diff --git a/doc/JA/syntax/08_procedure.md b/doc/JA/syntax/08_procedure.md index 1cddedc9..03292f40 100644 --- a/doc/JA/syntax/08_procedure.md +++ b/doc/JA/syntax/08_procedure.md @@ -1,5 +1,7 @@ # プロシージャ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/08_procedure.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/08_procedure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + プロシージャは可変オブジェクトを取り扱う際に必要となりますが、可変オブジェクトを引数に持てばプロシージャであるとは限りません。 ```python diff --git a/doc/JA/syntax/09_builtin_procs.md b/doc/JA/syntax/09_builtin_procs.md index d360673d..a7d55dab 100644 --- a/doc/JA/syntax/09_builtin_procs.md +++ b/doc/JA/syntax/09_builtin_procs.md @@ -1,5 +1,7 @@ # 組み込みプロシージャ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/09_builtin_procs.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/09_builtin_procs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## id! オブジェクトのユニークな識別番号を返します。 diff --git a/doc/JA/syntax/10_array.md b/doc/JA/syntax/10_array.md index 73706278..8181897f 100644 --- a/doc/JA/syntax/10_array.md +++ b/doc/JA/syntax/10_array.md @@ -1,5 +1,7 @@ # 配列 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/10_array.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/10_array.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 配列はもっとも基本的な __コレクション(集約)__ です。 コレクションとは、内部にオブジェクトを複数保持できるオブジェクトのことです。 diff --git a/doc/JA/syntax/11_tuple.md b/doc/JA/syntax/11_tuple.md index b395a601..fef7c7b4 100644 --- a/doc/JA/syntax/11_tuple.md +++ b/doc/JA/syntax/11_tuple.md @@ -1,5 +1,7 @@ # タプル +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/11_tuple.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/11_tuple.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + タプルは配列と似ていますが、違う型のオブジェクトを保持できます。 このようなコレクションを非等質なコレクションと呼びます。対して等質なコレクションには配列、セットなどがあります。 diff --git a/doc/JA/syntax/12_dict.md b/doc/JA/syntax/12_dict.md index 8918200b..f5d7701b 100644 --- a/doc/JA/syntax/12_dict.md +++ b/doc/JA/syntax/12_dict.md @@ -1,5 +1,7 @@ # Dict +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/12_dict.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/12_dict.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Dictはキーと値のペアを持つコレクションです。 ```python diff --git a/doc/JA/syntax/13_record.md b/doc/JA/syntax/13_record.md index ff2ba75f..c0db8c64 100644 --- a/doc/JA/syntax/13_record.md +++ b/doc/JA/syntax/13_record.md @@ -1,5 +1,7 @@ # レコード +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/13_record.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/13_record.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + レコードは、キーでアクセスするDictとコンパイル時にアクセスが検査されるタプルの性質を併せ持つコレクションです。 JavaScriptをやったことがある方ならば、オブジェクトリテラル記法の(より強化された)ようなものと考えてください。 diff --git a/doc/JA/syntax/14_set.md b/doc/JA/syntax/14_set.md index 4a69f085..5537d9f3 100644 --- a/doc/JA/syntax/14_set.md +++ b/doc/JA/syntax/14_set.md @@ -1,5 +1,7 @@ # セット(Set) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/14_set.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/14_set.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + セットは集合を表し、データ構造的には重複、順序のない配列です。 ```python diff --git a/doc/JA/syntax/15_type.md b/doc/JA/syntax/15_type.md index 840b24fc..2c4e0204 100644 --- a/doc/JA/syntax/15_type.md +++ b/doc/JA/syntax/15_type.md @@ -1,5 +1,7 @@ # 型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/15_type.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/15_type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 型はErgにおいて非常に重要な機能ですので、[専用のセクション](./type/01_type_system.md)を用意しています。そちらをご覧ください。

diff --git a/doc/JA/syntax/16_iterator.md b/doc/JA/syntax/16_iterator.md index affcb68e..29ae4a3e 100644 --- a/doc/JA/syntax/16_iterator.md +++ b/doc/JA/syntax/16_iterator.md @@ -1,5 +1,7 @@ # イテレータ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/16_iterator.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/16_iterator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + イテレータは、コンテナの要素を取り出すためのオブジェクトです。 ```python diff --git a/doc/JA/syntax/17_mutability.md b/doc/JA/syntax/17_mutability.md index 2271632e..df26eb7e 100644 --- a/doc/JA/syntax/17_mutability.md +++ b/doc/JA/syntax/17_mutability.md @@ -1,5 +1,7 @@ # Mutability +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/17_mutability.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/17_mutability.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + すでに見たように、Ergの変数は全て不変です。しかし、Ergのオブジェクトには可変性という概念があります。 以下のコードを例にします。 diff --git a/doc/JA/syntax/18_ownership.md b/doc/JA/syntax/18_ownership.md index 4970db77..c140705b 100644 --- a/doc/JA/syntax/18_ownership.md +++ b/doc/JA/syntax/18_ownership.md @@ -1,5 +1,7 @@ # 所有権システム +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/18_ownership.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/18_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ErgはPythonをホスト言語にした言語であるため、メモリ管理の方法はPythonの処理系に依存しています。 しかし、意味論的にはErgのメモリ管理はPythonのそれとは別物です。顕著な違いは、所有権システムと循環参照の禁止に現れています。 diff --git a/doc/JA/syntax/19_visibility.md b/doc/JA/syntax/19_visibility.md index 489cce62..9c9c3b40 100644 --- a/doc/JA/syntax/19_visibility.md +++ b/doc/JA/syntax/19_visibility.md @@ -1,5 +1,7 @@ # 可視性(Visibility) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/19_visibility.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/19_visibility.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Ergの変数には __可視性__ という概念が存在します。 今まで見てきた変数は全て __プライベート変数(非公開変数)__ と呼ばれます。これは、外部から不可視の変数です。 例えば`foo`モジュールで定義したプライベート変数は、別のモジュールから参照できないのです。 diff --git a/doc/JA/syntax/20_naming_rule.md b/doc/JA/syntax/20_naming_rule.md index 5b8617de..bb6913e8 100644 --- a/doc/JA/syntax/20_naming_rule.md +++ b/doc/JA/syntax/20_naming_rule.md @@ -1,5 +1,7 @@ # 命名規則 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/20_naming_rule.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/20_naming_rule.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 変数を定数式として使いたい場合は、必ず大文字で始めます。二文字以降は小文字でもよいです。 ```python diff --git a/doc/JA/syntax/21_lambda.md b/doc/JA/syntax/21_lambda.md index 7a29084f..b8fd0543 100644 --- a/doc/JA/syntax/21_lambda.md +++ b/doc/JA/syntax/21_lambda.md @@ -1,5 +1,7 @@ # 無名関数(anonymous function) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/21_lambda.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/21_lambda.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 無名関数は、関数オブジェクトを名付けずその場で生成するための文法です。 ```python diff --git a/doc/JA/syntax/22_subroutine.md b/doc/JA/syntax/22_subroutine.md index 6bc287b2..8890c52d 100644 --- a/doc/JA/syntax/22_subroutine.md +++ b/doc/JA/syntax/22_subroutine.md @@ -1,5 +1,7 @@ # Subroutine signatures +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/22_subroutine.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/22_subroutine.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## Func ```python diff --git a/doc/JA/syntax/23_closure.md b/doc/JA/syntax/23_closure.md index f8ff31d8..6e2ddda6 100644 --- a/doc/JA/syntax/23_closure.md +++ b/doc/JA/syntax/23_closure.md @@ -1,5 +1,7 @@ # クロージャ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/23_closure.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/23_closure.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Ergのサブルーチンには、外部変数を捕捉する「クロージャ」という機能があります。 ```python diff --git a/doc/JA/syntax/24_module.md b/doc/JA/syntax/24_module.md index 613f6ee9..5d3942ce 100644 --- a/doc/JA/syntax/24_module.md +++ b/doc/JA/syntax/24_module.md @@ -1,5 +1,7 @@ # モジュール +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/24_module.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/24_module.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Ergでは、ファイル自体を1つのレコードとみなすことができます。これをモジュールと呼びます。 ```python: foo.er diff --git a/doc/JA/syntax/25_object_system.md b/doc/JA/syntax/25_object_system.md index 4a387b0a..144fb5cb 100644 --- a/doc/JA/syntax/25_object_system.md +++ b/doc/JA/syntax/25_object_system.md @@ -1,5 +1,7 @@ # Object(対象体) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/25_object_system.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/25_object_system.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 変数に代入できる全てのデータです。`Object`クラスの持つ属性は以下の通りです。 * `.__repr__`: オブジェクトの(リッチでない)文字列表現を返します diff --git a/doc/JA/syntax/26_pattern_matching.md b/doc/JA/syntax/26_pattern_matching.md index 1c2399a8..83737503 100644 --- a/doc/JA/syntax/26_pattern_matching.md +++ b/doc/JA/syntax/26_pattern_matching.md @@ -1,5 +1,7 @@ # パターンマッチ、論駁可能性 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/26_pattern_matching.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/26_pattern_matching.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## Ergで使用可能なパターン ### 変数パターン diff --git a/doc/JA/syntax/27_comprehension.md b/doc/JA/syntax/27_comprehension.md index 70edab21..2e201462 100644 --- a/doc/JA/syntax/27_comprehension.md +++ b/doc/JA/syntax/27_comprehension.md @@ -1,5 +1,7 @@ # Comprehension(内包表記) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/27_comprehension.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/27_comprehension.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `[expr | (name <- iterable)+ (predicate)*]`で配列、 `{expr | (name <- iterable)+ (predicate)*}`でセット、 `{key: value | (name <- iterable)+ (predicate)*}`でDictが作れます。 diff --git a/doc/JA/syntax/28_spread_syntax.md b/doc/JA/syntax/28_spread_syntax.md index 1c16844d..f201cb2d 100644 --- a/doc/JA/syntax/28_spread_syntax.md +++ b/doc/JA/syntax/28_spread_syntax.md @@ -1,5 +1,7 @@ # Spread assignment (展開代入) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/28_spread_syntax.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/28_spread_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 分解代入において、変数の前に`...`を置くと残りの要素を全てその変数に展開できます。これを展開代入と呼びます。 ```python diff --git a/doc/JA/syntax/29_decorator.md b/doc/JA/syntax/29_decorator.md index 34f02216..2fcc956c 100644 --- a/doc/JA/syntax/29_decorator.md +++ b/doc/JA/syntax/29_decorator.md @@ -1,5 +1,7 @@ # デコレータ(修飾子) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/29_decorator.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/29_decorator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + デコレータは型や関数に特定の状態や振る舞いを追加したり明示するために使われます。 デコレータの文法は以下の通りです。 diff --git a/doc/JA/syntax/30_error_handling.md b/doc/JA/syntax/30_error_handling.md index f870b0d2..57dde72d 100644 --- a/doc/JA/syntax/30_error_handling.md +++ b/doc/JA/syntax/30_error_handling.md @@ -1,5 +1,7 @@ # エラーハンドリングシステム +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/30_error_handling.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/30_error_handling.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 主にResult型を使用します。 ErgではError型オブジェクトを捨てる(トップレベルで対応しない)とエラーが発生します。 diff --git a/doc/JA/syntax/31_pipeline.md b/doc/JA/syntax/31_pipeline.md index ab861a70..4ee29ae6 100644 --- a/doc/JA/syntax/31_pipeline.md +++ b/doc/JA/syntax/31_pipeline.md @@ -1,5 +1,7 @@ # パイプライン演算子 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/31_pipeline.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/31_pipeline.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + パイプライン演算子は、次のように使います。 ```python diff --git a/doc/JA/syntax/32_integration_with_Python.md b/doc/JA/syntax/32_integration_with_Python.md index 473d4334..997f5504 100644 --- a/doc/JA/syntax/32_integration_with_Python.md +++ b/doc/JA/syntax/32_integration_with_Python.md @@ -1,5 +1,7 @@ # Pythonとの連携 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/32_integration_with_Python.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/32_integration_with_Python.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## Pythonへのexport Ergスクリプトをコンパイルすると.pycファイルが生成されますが、これは単純にPythonのモジュールとして読み込むことができます。 diff --git a/doc/JA/syntax/33_package_system.md b/doc/JA/syntax/33_package_system.md index 79a1229e..b54956d5 100644 --- a/doc/JA/syntax/33_package_system.md +++ b/doc/JA/syntax/33_package_system.md @@ -1,5 +1,7 @@ # パッケージシステム +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/33_package_system.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/33_package_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Ergのパッケージはアプリケーションであるappパッケージとライブラリであるlibパッケージに大別できます。 appパッケージのエントリポイントは`src/app.er`です。`app.er`内に定義された`main`関数が実行されます。 libパッケージのエントリポイントは`src/lib.er`です。パッケージをインポートすることは`lib.er`をインポートすることと等価になります。 diff --git a/doc/JA/syntax/34_generator.md b/doc/JA/syntax/34_generator.md index 8d883748..0cfdc690 100644 --- a/doc/JA/syntax/34_generator.md +++ b/doc/JA/syntax/34_generator.md @@ -1,5 +1,7 @@ # ジェネレータ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/34_generator.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/34_generator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ジェネレータは、ブロック中で`yield!`プロシージャを使う特殊なプロシージャです。 ```python diff --git a/doc/JA/syntax/SUMMARY.md b/doc/JA/syntax/SUMMARY.md index 774c354b..de5dfd3d 100644 --- a/doc/JA/syntax/SUMMARY.md +++ b/doc/JA/syntax/SUMMARY.md @@ -1,5 +1,7 @@ # Summary +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/SUMMARY.md%26commit_hash%3D2ce482b1c8407332b3b74f4c3e5596f373f9a657)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/SUMMARY.md&commit_hash=2ce482b1c8407332b3b74f4c3e5596f373f9a657) + - [Basics](./00_basic.md) - [Literal](./01_literal.md) - [Name](02_name.md) diff --git a/doc/JA/syntax/container_ownership.md b/doc/JA/syntax/container_ownership.md index c464e579..65c514be 100644 --- a/doc/JA/syntax/container_ownership.md +++ b/doc/JA/syntax/container_ownership.md @@ -1,5 +1,7 @@ # Subscript(添字アクセス) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/container_ownership.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/container_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `[]`は通常のメソッドとは異なっています。 ```python diff --git a/doc/JA/syntax/indexes.md b/doc/JA/syntax/indexes.md index 0db44b64..07066223 100644 --- a/doc/JA/syntax/indexes.md +++ b/doc/JA/syntax/indexes.md @@ -1,5 +1,7 @@ # 索引 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/indexes.md%26commit_hash%3D438bcb89ea692f219b30f3a3ba107888b23eae98)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/indexes.md&commit_hash=438bcb89ea692f219b30f3a3ba107888b23eae98) + この索引にないAPIについては[こちら](../API/index.md)を参照してください。 用語の意味については[こちら](../dev_guide/terms.md)を参照。 diff --git a/doc/JA/syntax/quick_tour.md b/doc/JA/syntax/quick_tour.md index 414803d2..b93bc059 100644 --- a/doc/JA/syntax/quick_tour.md +++ b/doc/JA/syntax/quick_tour.md @@ -1,5 +1,7 @@ # Quick Tour +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/quick_tour.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/quick_tour.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `syntax`以下のドキュメントは、概ねプログラミング初心者でも理解できることを目指して書かれています。 すでにPythonやRust, Haskellなどの言語を習得されている方にとっては、少し冗長であるかもしれません。 diff --git a/doc/JA/syntax/type/01_type_system.md b/doc/JA/syntax/type/01_type_system.md index 238af1bc..c6d5d35d 100644 --- a/doc/JA/syntax/type/01_type_system.md +++ b/doc/JA/syntax/type/01_type_system.md @@ -1,5 +1,7 @@ # Ergの型システム +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/01_type_system.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/01_type_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 以下では、Ergの型システムを概略的に説明します。詳細については他の項で解説します。 ## 定義方法 diff --git a/doc/JA/syntax/type/02_basic.md b/doc/JA/syntax/type/02_basic.md index 9eeefc1a..f720880c 100644 --- a/doc/JA/syntax/type/02_basic.md +++ b/doc/JA/syntax/type/02_basic.md @@ -1,5 +1,7 @@ # 型に関する基本的な文法 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/02_basic.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/02_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 型指定 Ergでは以下のように`:`の後に変数の型を指定します。代入と同時に行うこともできます。 diff --git a/doc/JA/syntax/type/03_trait.md b/doc/JA/syntax/type/03_trait.md index 8f794755..ca426ac3 100644 --- a/doc/JA/syntax/type/03_trait.md +++ b/doc/JA/syntax/type/03_trait.md @@ -1,5 +1,7 @@ # トレイト +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/03_trait.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/03_trait.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + トレイトは、レコード型に型属性の要求を追加した記名型です。 Pythonでいう抽象基底クラス(Abstract Base Class, ABC)に類似しますが、代数的演算を行えるという特徴があります。 diff --git a/doc/JA/syntax/type/04_class.md b/doc/JA/syntax/type/04_class.md index 7eff7f0d..9b9e0434 100644 --- a/doc/JA/syntax/type/04_class.md +++ b/doc/JA/syntax/type/04_class.md @@ -1,5 +1,7 @@ # Class +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/04_class.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/04_class.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Ergにおけるクラスは、大まかには自身の要素(インスタンス)を生成できる型と言えます。 以下は単純なクラスの例です。 diff --git a/doc/JA/syntax/type/05_inheritance.md b/doc/JA/syntax/type/05_inheritance.md index eab04bd0..598513e9 100644 --- a/doc/JA/syntax/type/05_inheritance.md +++ b/doc/JA/syntax/type/05_inheritance.md @@ -1,5 +1,7 @@ # 継承(Inheritance) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/05_inheritance.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/05_inheritance.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 継承を使うと、既存のクラスに機能を加えたり特化したりした新しいクラスを定義できます。 継承はトレイトにおける包摂に似ています。継承してできたクラスは、もとのクラスのサブタイプになります。 diff --git a/doc/JA/syntax/type/06_nst_vs_sst.md b/doc/JA/syntax/type/06_nst_vs_sst.md index 20e23b39..c2798a43 100644 --- a/doc/JA/syntax/type/06_nst_vs_sst.md +++ b/doc/JA/syntax/type/06_nst_vs_sst.md @@ -1,5 +1,7 @@ # 記名的部分型 vs. 構造的部分型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/06_nst_vs_sst.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/06_nst_vs_sst.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ```python Months = 0..12 diff --git a/doc/JA/syntax/type/07_patch.md b/doc/JA/syntax/type/07_patch.md index a535d769..6173b9ed 100644 --- a/doc/JA/syntax/type/07_patch.md +++ b/doc/JA/syntax/type/07_patch.md @@ -1,5 +1,7 @@ # Patch +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/07_patch.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/07_patch.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Ergでは、既存の型・クラスに手を加えることはできません。 クラスにメソッドを追加で定義することはできず、特殊化(specialization, 多相に宣言された型を単相化し専用のメソッドを定義する機能。C++などが持つ)も行えません。 しかし、既存の型・クラスに機能を追加したいという状況は多々あり、これを実現するためにパッチという機能があります。 diff --git a/doc/JA/syntax/type/08_value.md b/doc/JA/syntax/type/08_value.md index ae81cd95..2563900b 100644 --- a/doc/JA/syntax/type/08_value.md +++ b/doc/JA/syntax/type/08_value.md @@ -1,5 +1,7 @@ # 値型(Value types) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/08_value.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/08_value.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 値型はErg組み込み型のうちコンパイル時評価が可能な型で、具体的には以下のものです。 ```python diff --git a/doc/JA/syntax/type/09_attributive.md b/doc/JA/syntax/type/09_attributive.md index 96dce87e..b57a8f09 100644 --- a/doc/JA/syntax/type/09_attributive.md +++ b/doc/JA/syntax/type/09_attributive.md @@ -1,5 +1,7 @@ # 属性型(Attributive Type) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/09_attributive.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/09_attributive.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 属性型は、レコードおよびデータクラス、パッチ、モジュールなどが含まれる型です。 属性型に属する型は値型ではありません。 diff --git a/doc/JA/syntax/type/10_interval.md b/doc/JA/syntax/type/10_interval.md index 75c489c5..9ff3a712 100644 --- a/doc/JA/syntax/type/10_interval.md +++ b/doc/JA/syntax/type/10_interval.md @@ -1,5 +1,7 @@ # Interval Type +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/10_interval.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/10_interval.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + `Range`オブジェクトの最も基本的な使い方は、イテレータとしての使用です。 ```python diff --git a/doc/JA/syntax/type/11_enum.md b/doc/JA/syntax/type/11_enum.md index b82dcdc9..51dd9524 100644 --- a/doc/JA/syntax/type/11_enum.md +++ b/doc/JA/syntax/type/11_enum.md @@ -1,5 +1,7 @@ # Enumerative Type(列挙型) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/11_enum.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/11_enum.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 列挙型(Enum type)はSetによって生成されます。 列挙型はそのままでも型指定で使えますが、クラス化したりパッチを定義することで更にメソッドを定義できます。 列挙型による部分型システムを列挙的部分型付けといいます。 diff --git a/doc/JA/syntax/type/12_refinement.md b/doc/JA/syntax/type/12_refinement.md index b49d5774..337cec6c 100644 --- a/doc/JA/syntax/type/12_refinement.md +++ b/doc/JA/syntax/type/12_refinement.md @@ -1,5 +1,7 @@ # 篩型(Refinement Type) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/12_refinement.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/12_refinement.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Refinement type(篩型、ふるいがた)は、述語式によって制約付けられた型です。列挙型や区間型は篩型の一種です。 篩型の標準形は`{Elem: Type | (Pred)*}`です。これは、`Pred`を満たす`Elem`を要素とする型である、という意味です。 diff --git a/doc/JA/syntax/type/13_algebraic.md b/doc/JA/syntax/type/13_algebraic.md index 51238f0d..14c353f6 100644 --- a/doc/JA/syntax/type/13_algebraic.md +++ b/doc/JA/syntax/type/13_algebraic.md @@ -1,5 +1,7 @@ # Algebraic type (代数演算型) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/13_algebraic.md%26commit_hash%3Dc120700585fdb1d655255c8e2817bb13cc8d369e)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/13_algebraic.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e) + 代数演算型は、型を代数のようにみなして演算することで生成される型のことです。 代数演算型が扱う演算は、Union, Intersection, Diff, Complementなどがあります。 通常のクラスはUnionのみが行えて、他の演算は型エラーになります。 diff --git a/doc/JA/syntax/type/14_dependent.md b/doc/JA/syntax/type/14_dependent.md index f8e4f6ae..dbe95180 100644 --- a/doc/JA/syntax/type/14_dependent.md +++ b/doc/JA/syntax/type/14_dependent.md @@ -1,5 +1,7 @@ # 依存型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/14_dependent.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/14_dependent.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 依存型はErgの最大の特徴とも言っても良い機能です。 依存型とは、値を引数に取る型です。通常の多相型は型のみを引数に取れますが、その制限を緩めたのが依存型といえます。 diff --git a/doc/JA/syntax/type/15_quantified.md b/doc/JA/syntax/type/15_quantified.md index 9a134bf3..7fa2bd07 100644 --- a/doc/JA/syntax/type/15_quantified.md +++ b/doc/JA/syntax/type/15_quantified.md @@ -1,5 +1,7 @@ # 型変数(Type Variable)、量化型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/15_quantified.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/15_quantified.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 型変数はサブルーチン引数の型指定などに使用する変数で、その型が任意である(単相化しない)ことを示します。 まず、型変数を導入するモチベーションとして、入力をそのまま返す`id`関数について考えましょう。 diff --git a/doc/JA/syntax/type/16_subtyping.md b/doc/JA/syntax/type/16_subtyping.md index 96d0e1ba..d8d34278 100644 --- a/doc/JA/syntax/type/16_subtyping.md +++ b/doc/JA/syntax/type/16_subtyping.md @@ -1,5 +1,7 @@ # 部分型付け +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/16_subtyping.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/16_subtyping.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Ergでは、クラス同士の包含関係は比較演算子`<`, `>`で判定可能です。 ```python diff --git a/doc/JA/syntax/type/17_type_casting.md b/doc/JA/syntax/type/17_type_casting.md index d30a919b..6571f91f 100644 --- a/doc/JA/syntax/type/17_type_casting.md +++ b/doc/JA/syntax/type/17_type_casting.md @@ -1,5 +1,7 @@ # キャスト +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/17_type_casting.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/17_type_casting.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## アップキャスト Pythonはダックタイピングを採用する言語のため、キャストという概念はありません。アップキャストはする必要がなく、ダウンキャストも基本的にはありません。 diff --git a/doc/JA/syntax/type/18_mut.md b/doc/JA/syntax/type/18_mut.md index 24c97a81..50b24643 100644 --- a/doc/JA/syntax/type/18_mut.md +++ b/doc/JA/syntax/type/18_mut.md @@ -1,5 +1,7 @@ # 可変型(Mutable Type) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/18_mut.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/18_mut.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + > __Warning__: この項の情報は古く、一部に間違いを含みます。 Ergではデフォルトですべての型が不変型、すなわち内部状態を更新できないようになっています。 diff --git a/doc/JA/syntax/type/19_bound.md b/doc/JA/syntax/type/19_bound.md index ea121878..f027dae0 100644 --- a/doc/JA/syntax/type/19_bound.md +++ b/doc/JA/syntax/type/19_bound.md @@ -1,5 +1,7 @@ # 型境界 (Type Bound) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/19_bound.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/19_bound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 型境界は型指定に条件を加えるものである。これを実現する機能がガード(ガード節)である。 関数シグニチャ、無名関数シグニチャのほか、篩型でもこの機能を利用できる。 ガードは戻り値型の後に記述する。 diff --git a/doc/JA/syntax/type/advanced.md b/doc/JA/syntax/type/advanced.md index 11816bd0..9f810e4e 100644 --- a/doc/JA/syntax/type/advanced.md +++ b/doc/JA/syntax/type/advanced.md @@ -1,2 +1,4 @@ 以降は更に高度な型システムを解説します。入門者の方はすべての項を読まなくても問題ありません。 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/syntax/type/advanced/GADTs.md b/doc/JA/syntax/type/advanced/GADTs.md index 6a7d7958..3e5a4f91 100644 --- a/doc/JA/syntax/type/advanced/GADTs.md +++ b/doc/JA/syntax/type/advanced/GADTs.md @@ -1,5 +1,7 @@ # 一般化代数的データ型(Generalized Algebraic Data Types, GADTs) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/GADTs.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/GADTs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ErgはOr型をクラス化することで一般化代数的データ型(GADTs)を作成出来ます。 ```python diff --git a/doc/JA/syntax/type/advanced/_rank2type.md b/doc/JA/syntax/type/advanced/_rank2type.md index e98cdc19..77ef9348 100644 --- a/doc/JA/syntax/type/advanced/_rank2type.md +++ b/doc/JA/syntax/type/advanced/_rank2type.md @@ -1,5 +1,7 @@ # rank-2多相 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/_rank2type.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/_rank2type.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + > __Warning__: このドキュメントは情報が古く、全般に間違いを含みます。 Ergでは`id|T|(x: T): T = x`などのように色々な型を受け取れる関数、すなわち多相関数を定義できる。 diff --git a/doc/JA/syntax/type/advanced/default_param.md b/doc/JA/syntax/type/advanced/default_param.md index 48714c73..33309674 100644 --- a/doc/JA/syntax/type/advanced/default_param.md +++ b/doc/JA/syntax/type/advanced/default_param.md @@ -1,5 +1,7 @@ # デフォルト引数付きの関数型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/default_param.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/default_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + まず、デフォルト引数の使用例を見る。 ```python diff --git a/doc/JA/syntax/type/advanced/erasure.md b/doc/JA/syntax/type/advanced/erasure.md index df15e071..fe58b35d 100644 --- a/doc/JA/syntax/type/advanced/erasure.md +++ b/doc/JA/syntax/type/advanced/erasure.md @@ -1,5 +1,7 @@ # 型消去(Type erasure) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/erasure.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/erasure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 型消去とは、型引数に`_`を指定し、その情報をあえて捨てることです。型消去は多相型を持つ言語の多くが併せて持つ機能ですが、Ergの文法に即して言えば型引数消去といった方が正確でしょう。 もっともよく見られる型消去された型の例は`[T, _]`でしょう。配列はコンパイル時にその長さが分からない場合もあります。例えば、コマンドライン引数を指す`sys.argv`は`[Str, _]`型です。コマンドライン引数の長さをErgのコンパイラは知りようがないため、長さに関する情報は諦めなくてはならないのです。 diff --git a/doc/JA/syntax/type/advanced/existential.md b/doc/JA/syntax/type/advanced/existential.md index fe346e93..d47c5fc8 100644 --- a/doc/JA/syntax/type/advanced/existential.md +++ b/doc/JA/syntax/type/advanced/existential.md @@ -1,5 +1,7 @@ # 存在型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/existential.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/existential.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ∀に対応する全称型があるならば、∃に対応する存在型があると考えるのが自然です。 存在型は難しいものではありません。そうと意識していないだけで、既にあなたは存在型を知っています。 diff --git a/doc/JA/syntax/type/advanced/keyword_param.md b/doc/JA/syntax/type/advanced/keyword_param.md index af031750..e77f06f9 100644 --- a/doc/JA/syntax/type/advanced/keyword_param.md +++ b/doc/JA/syntax/type/advanced/keyword_param.md @@ -1,5 +1,7 @@ # キーワード引数付き関数型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/keyword_param.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/keyword_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python h(f) = f(y: 1, x: 2) h: |T: Type|((y: Int, x: Int) -> T) -> T diff --git a/doc/JA/syntax/type/advanced/kind.md b/doc/JA/syntax/type/advanced/kind.md index 2140a96c..d95aa668 100644 --- a/doc/JA/syntax/type/advanced/kind.md +++ b/doc/JA/syntax/type/advanced/kind.md @@ -1,5 +1,7 @@ # カインド(Kind) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/kind.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/kind.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Ergでは全てが型付けられている。型自体も例外ではない。「型の型」を表すのが __カインド(種)__ である。例えば`1`が`Int`に属しているように、`Int`は`Type`に属している。`Type`は最もシンプルなカインドである __原子カインド(Atomic kind)__ である。型理論的の記法では、`Type`は`*`に対応する。 カインドという概念で実用上重要なのは1項以上のカインド(多項カインド)である。1項のカインドは、例えば`Option`などがそれに属する。1項カインドは`Type -> Type`と表される[1](#1)。`Array`や`Option`などの __コンテナ__ は特に型を引数に取る多項カインドのことなのである。 diff --git a/doc/JA/syntax/type/advanced/marker_trait.md b/doc/JA/syntax/type/advanced/marker_trait.md index 529b8007..93f55f28 100644 --- a/doc/JA/syntax/type/advanced/marker_trait.md +++ b/doc/JA/syntax/type/advanced/marker_trait.md @@ -1,5 +1,7 @@ # Marker Trait +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/marker_trait.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/marker_trait.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + マーカートレイトは、要求属性のないトレイトである。すなわち、メソッドを実装せずにImplすることができる。 要求属性がないと意味がないように思えるが、そのトレイトに属しているという情報が登録されるので、パッチメソッドを使ったり、コンパイラが特別扱いしたりできる。 diff --git a/doc/JA/syntax/type/advanced/mut_struct.md b/doc/JA/syntax/type/advanced/mut_struct.md index b3a5cffb..b963b704 100644 --- a/doc/JA/syntax/type/advanced/mut_struct.md +++ b/doc/JA/syntax/type/advanced/mut_struct.md @@ -1,5 +1,7 @@ # 可変構造型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/mut_struct.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/mut_struct.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + `T!`型は任意の`T`型オブジェクトを入れられて差し替え可能なボックス型であると説明した。 ```python diff --git a/doc/JA/syntax/type/advanced/newtype.md b/doc/JA/syntax/type/advanced/newtype.md index 121cc5ab..943c9478 100644 --- a/doc/JA/syntax/type/advanced/newtype.md +++ b/doc/JA/syntax/type/advanced/newtype.md @@ -1,5 +1,7 @@ # Newtype pattern +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/newtype.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/newtype.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ここでは、Rustでよく使われるnewtypeパターンのErg版を紹介します。 Ergはでは以下のように型のエイリアスを定義できますが、これはあくまで同じ型を指します。 diff --git a/doc/JA/syntax/type/advanced/overloading.md b/doc/JA/syntax/type/advanced/overloading.md index 0fe43edf..8aed76d2 100644 --- a/doc/JA/syntax/type/advanced/overloading.md +++ b/doc/JA/syntax/type/advanced/overloading.md @@ -1,5 +1,7 @@ # オーバーロード +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/overloading.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/overloading.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Ergでは __アドホック多相__ をサポートしない。すなわち、関数・カインドの多重定義(オーバーロード)ができない。が、トレイトクラスとパッチを組み合わせることでオーバーロードの挙動を再現できる。 トレイトクラスのかわりにトレイトを使用しても良いが、その場合`.add1`を実装している型全てが対象になってしまう。 diff --git a/doc/JA/syntax/type/advanced/phantom.md b/doc/JA/syntax/type/advanced/phantom.md index f2df3fed..d7441589 100644 --- a/doc/JA/syntax/type/advanced/phantom.md +++ b/doc/JA/syntax/type/advanced/phantom.md @@ -1,5 +1,7 @@ # 幽霊型(Phantom class) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/phantom.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/phantom.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 幽霊型は、コンパイラに注釈を与えるためだけに存在するマーカートレイトである。 幽霊型の使い方として、リストの構成をみる。 diff --git a/doc/JA/syntax/type/advanced/projection.md b/doc/JA/syntax/type/advanced/projection.md index 119ffe3d..20f47c9d 100644 --- a/doc/JA/syntax/type/advanced/projection.md +++ b/doc/JA/syntax/type/advanced/projection.md @@ -1,5 +1,7 @@ # Projection Type(射影型) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/projection.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/projection.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 射影型は、次のコードにおける`Self.AddO`のような型を表します。 ```python diff --git a/doc/JA/syntax/type/advanced/quantified_dependent.md b/doc/JA/syntax/type/advanced/quantified_dependent.md index 80abf07e..ddbe1943 100644 --- a/doc/JA/syntax/type/advanced/quantified_dependent.md +++ b/doc/JA/syntax/type/advanced/quantified_dependent.md @@ -1,5 +1,7 @@ # 量化依存型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/quantified_dependent.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/quantified_dependent.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Ergには量化型、依存型が存在します。すると当然、その二つを組み合わせた型を作ることができます。それが量化依存型です。 ```python diff --git a/doc/JA/syntax/type/advanced/shared.md b/doc/JA/syntax/type/advanced/shared.md index f3c6d4bb..f2805470 100644 --- a/doc/JA/syntax/type/advanced/shared.md +++ b/doc/JA/syntax/type/advanced/shared.md @@ -1,5 +1,7 @@ # 共有参照(Shared Reference) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/shared.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/shared.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 共有参照は気をつけて扱わねばならない言語機能の一つです。 例えばTypeScriptでは以下のようなコードが型検査を通ってしまいます。 diff --git a/doc/JA/syntax/type/advanced/special.md b/doc/JA/syntax/type/advanced/special.md index 22de410a..a63d1502 100644 --- a/doc/JA/syntax/type/advanced/special.md +++ b/doc/JA/syntax/type/advanced/special.md @@ -1,5 +1,7 @@ # 特殊型(Self, Super) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/special.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `Self`は自身の型を表します。単にエイリアスとして使うことも出来ますが、派生型中では意味が変わる(自身の型を指す)ので注意してください。 ```python diff --git a/doc/JA/syntax/type/advanced/typeof.md b/doc/JA/syntax/type/advanced/typeof.md index b0535cc4..df6b1117 100644 --- a/doc/JA/syntax/type/advanced/typeof.md +++ b/doc/JA/syntax/type/advanced/typeof.md @@ -1,5 +1,7 @@ # Typeof, classof +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/typeof.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/typeof.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `Typeof`はErgの型推論システムを覗くことができる関数であり、その挙動は複雑である。 ```python diff --git a/doc/JA/syntax/type/advanced/variance.md b/doc/JA/syntax/type/advanced/variance.md index 010dbad0..04f16814 100644 --- a/doc/JA/syntax/type/advanced/variance.md +++ b/doc/JA/syntax/type/advanced/variance.md @@ -1,5 +1,7 @@ # 変性(variance) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/variance.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/variance.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Ergは多相型のサブタイピングを行えるが、一部注意しなくてはならない点がある。 まずは通常の多相型の包含関係を考える。一般に、コンテナ`K`と代入する型`A, B`があり、`A < B`のとき、`K A < K B`となる。 diff --git a/doc/JA/syntax/type/advanced/widening.md b/doc/JA/syntax/type/advanced/widening.md index 50f3f40f..2bb2d786 100644 --- a/doc/JA/syntax/type/advanced/widening.md +++ b/doc/JA/syntax/type/advanced/widening.md @@ -1,5 +1,7 @@ # 型拡大(Type Widening) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/widening.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/widening.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 例えば以下のような多相関数を定義する。 ```python diff --git a/doc/JA/tips.md b/doc/JA/tips.md index 700964dc..868f76b0 100644 --- a/doc/JA/tips.md +++ b/doc/JA/tips.md @@ -1,5 +1,7 @@ # Tips +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tips.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tips.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## エラーの表示言語を変えたい 各国語版のergをダウンロードしてください。 diff --git a/doc/JA/tools/build.md b/doc/JA/tools/build.md index 193be4cc..a50a68e8 100644 --- a/doc/JA/tools/build.md +++ b/doc/JA/tools/build.md @@ -1,5 +1,7 @@ # buildサブコマンド +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/build.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/build.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + buildサブコマンドでは、パッケージのビルドを行います。 デフォルトのビルドで行われる工程は、以下の通りです。 diff --git a/doc/JA/tools/env.md b/doc/JA/tools/env.md index 030c373c..d4640d78 100644 --- a/doc/JA/tools/env.md +++ b/doc/JA/tools/env.md @@ -1,5 +1,7 @@ # envサブコマンド +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/env.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + envサブコマンドはerg実行環境の指定を行います。 `erg env new [env name]`で新しい実行環境を作成します。対話ツールが開き、ergのバージョンを指定すると、そのバージョンのergがインストール(すでにあれば流用されます)され、新しい環境として使えるようになります。 `erg env switch [env name]`で環境の切り替えができます。 diff --git a/doc/JA/tools/fmt.md b/doc/JA/tools/fmt.md index adc6165c..1e16f02d 100644 --- a/doc/JA/tools/fmt.md +++ b/doc/JA/tools/fmt.md @@ -1,5 +1,7 @@ # fmt +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/fmt.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/fmt.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + fmtサブコマンドででコードフォーマットが出来ます。 よく使用されるフラッグは以下の通りです。 diff --git a/doc/JA/tools/index.md b/doc/JA/tools/index.md index e69de29b..f08300dc 100644 --- a/doc/JA/tools/index.md +++ b/doc/JA/tools/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/index.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/JA/tools/install.md b/doc/JA/tools/install.md index d8a1cc8f..b5532756 100644 --- a/doc/JA/tools/install.md +++ b/doc/JA/tools/install.md @@ -1,5 +1,7 @@ # installサブコマンド +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/install.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/install.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + installでレジストリサイトに登録されたパッケージをインストールできる。 基本的な使い方はcargoなどのパッケージマネージャと同じ。 diff --git a/doc/JA/tools/pack.md b/doc/JA/tools/pack.md index ee241ab8..9d8cc522 100644 --- a/doc/JA/tools/pack.md +++ b/doc/JA/tools/pack.md @@ -1,5 +1,7 @@ # パッケージマネージャー +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/pack.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/pack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Ergは標準でパッケージマネージャーが付属しており、`pack`サブコマンドで呼び出せる。 以下は典型的なオプションである。 diff --git a/doc/JA/tools/repl.md b/doc/JA/tools/repl.md index 87969a48..69997b88 100644 --- a/doc/JA/tools/repl.md +++ b/doc/JA/tools/repl.md @@ -1,5 +1,7 @@ # REPL +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/repl.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/repl.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + `erg`コマンドを引数を与えず実行すると、REPLが起動されます。また、`repl`サブコマンドを指定して起動することもできます。 さらに以下のフラグを指定できます。 diff --git a/doc/JA/tools/test.md b/doc/JA/tools/test.md index 80073614..82e7faef 100644 --- a/doc/JA/tools/test.md +++ b/doc/JA/tools/test.md @@ -1,5 +1,7 @@ # testサブコマンド +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/test.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/test.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ergコマンドにはtestというサブコマンドがあり、テスト実装、及び実行の支援を行う。 ## Testデコレータ(@Test) From 76160a82f6705e2fcbcfc038d6a63a12d877eb87 Mon Sep 17 00:00:00 2001 From: GreasySlug <9619abgoni@gmail.com> Date: Tue, 6 Sep 2022 09:29:14 +0900 Subject: [PATCH 31/42] Update to zh_cn doc to put translation badges --- doc/zh_CN/API/consts.md | 2 ++ doc/zh_CN/API/funcs.md | 2 ++ doc/zh_CN/API/index.md | 2 ++ doc/zh_CN/API/modules/external/alstruct.md | 2 ++ doc/zh_CN/API/modules/repl.md | 2 ++ doc/zh_CN/API/modules/status.md | 2 ++ doc/zh_CN/API/modules/unit.md | 2 ++ doc/zh_CN/API/modules/unsound.md | 2 ++ doc/zh_CN/API/operators.md | 2 ++ doc/zh_CN/API/procs.md | 2 ++ doc/zh_CN/API/special.md | 2 ++ doc/zh_CN/API/types.md | 2 ++ doc/zh_CN/API/types/classes/Array!(T).md | 2 ++ doc/zh_CN/API/types/classes/Array(T).md | 2 ++ doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md | 2 ++ doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md | 2 ++ doc/zh_CN/API/types/classes/Class.md | 2 ++ doc/zh_CN/API/types/classes/Complex.md | 2 ++ doc/zh_CN/API/types/classes/Dict!.md | 2 ++ doc/zh_CN/API/types/classes/Either.md | 2 ++ doc/zh_CN/API/types/classes/Float.md | 2 ++ doc/zh_CN/API/types/classes/Function(N).md | 2 ++ doc/zh_CN/API/types/classes/Inf.md | 2 ++ doc/zh_CN/API/types/classes/Int.md | 2 ++ doc/zh_CN/API/types/classes/IntRange.md | 2 ++ doc/zh_CN/API/types/classes/Interval.md | 2 ++ doc/zh_CN/API/types/classes/Iterator.md | 2 ++ doc/zh_CN/API/types/classes/Kind(N).md | 2 ++ doc/zh_CN/API/types/classes/Matrix.md | 2 ++ doc/zh_CN/API/types/classes/Module.md | 2 ++ doc/zh_CN/API/types/classes/Nat.md | 2 ++ doc/zh_CN/API/types/classes/Neg.md | 2 ++ doc/zh_CN/API/types/classes/Never.md | 2 ++ doc/zh_CN/API/types/classes/NonZero.md | 2 ++ doc/zh_CN/API/types/classes/Object.md | 2 ++ doc/zh_CN/API/types/classes/Operator.md | 2 ++ doc/zh_CN/API/types/classes/Option.md | 2 ++ doc/zh_CN/API/types/classes/Pos.md | 2 ++ doc/zh_CN/API/types/classes/Ratio.md | 2 ++ doc/zh_CN/API/types/classes/Record.md | 2 ++ doc/zh_CN/API/types/classes/Result.md | 2 ++ doc/zh_CN/API/types/classes/Str!.md | 2 ++ doc/zh_CN/API/types/classes/Str.md | 2 ++ doc/zh_CN/API/types/classes/StrWithLen.md | 2 ++ doc/zh_CN/API/types/classes/Subroutine.md | 2 ++ doc/zh_CN/API/types/classes/Tensor.md | 2 ++ doc/zh_CN/API/types/classes/TransCell(T).md | 2 ++ doc/zh_CN/API/types/classes/Tuple.md | 2 ++ doc/zh_CN/API/types/classes/Type.md | 2 ++ doc/zh_CN/API/types/classes/Vector.md | 2 ++ doc/zh_CN/API/types/patches/BinOp.md | 2 ++ doc/zh_CN/API/types/patches/UnaryOp.md | 2 ++ doc/zh_CN/API/types/traits/Add(R,O).md | 2 ++ doc/zh_CN/API/types/traits/Div(R,O).md | 2 ++ doc/zh_CN/API/types/traits/Eq.md | 2 ++ doc/zh_CN/API/types/traits/Into.md | 2 ++ doc/zh_CN/API/types/traits/Iterable.md | 2 ++ doc/zh_CN/API/types/traits/Num.md | 2 ++ doc/zh_CN/API/types/traits/Ord.md | 2 ++ doc/zh_CN/API/types/traits/SafeDiv(R,O).md | 2 ++ doc/zh_CN/API/types/traits/Sample.md | 2 ++ doc/zh_CN/API/types/traits/Seq.md | 2 ++ doc/zh_CN/API/types/traits/Show.md | 2 ++ doc/zh_CN/API/types/traits/Unpack.md | 2 ++ doc/zh_CN/compiler/TODO_hint.md | 2 ++ doc/zh_CN/compiler/TODO_recov_suggest.md | 2 ++ doc/zh_CN/compiler/TODO_warn.md | 2 ++ doc/zh_CN/compiler/abandoned.md | 2 ++ doc/zh_CN/compiler/architecture.md | 2 ++ doc/zh_CN/compiler/errors.md | 2 ++ doc/zh_CN/compiler/hir.md | 2 ++ doc/zh_CN/compiler/index.md | 2 ++ doc/zh_CN/compiler/inference.md | 2 ++ doc/zh_CN/compiler/overview.md | 2 ++ doc/zh_CN/compiler/parsing.md | 2 ++ doc/zh_CN/compiler/refinement_subtyping.md | 2 ++ doc/zh_CN/compiler/trait_method_resolving.md | 2 ++ doc/zh_CN/compiler/transpile.md | 2 ++ doc/zh_CN/compiler/type_var_normalization.md | 2 ++ doc/zh_CN/dev_guide/branches.md | 2 ++ doc/zh_CN/dev_guide/build_features.md | 2 ++ doc/zh_CN/dev_guide/directories.md | 2 ++ doc/zh_CN/dev_guide/doc_guideline.md | 2 ++ doc/zh_CN/dev_guide/env.md | 2 ++ doc/zh_CN/dev_guide/faq_syntax.md | 2 ++ doc/zh_CN/dev_guide/i18n_messages.md | 2 ++ doc/zh_CN/dev_guide/index.md | 2 ++ doc/zh_CN/dev_guide/rust_code_guideline.md | 2 ++ doc/zh_CN/dev_guide/terms.md | 2 ++ doc/zh_CN/dev_guide/unify_terms.md | 2 ++ doc/zh_CN/faq_general.md | 8 +++++--- doc/zh_CN/faq_technical.md | 2 ++ doc/zh_CN/improved_points.md | 2 ++ doc/zh_CN/index.md | 2 ++ doc/zh_CN/migration_from_py.md | 2 ++ doc/zh_CN/python/bytecode_instructions.md | 2 ++ doc/zh_CN/python/bytecode_specification.md | 2 ++ doc/zh_CN/python/class_system.md | 2 ++ doc/zh_CN/python/index.md | 2 ++ doc/zh_CN/syntax/00_basic.md | 2 ++ doc/zh_CN/syntax/01_literal.md | 2 ++ doc/zh_CN/syntax/02_name.md | 2 ++ doc/zh_CN/syntax/03_declaration.md | 2 ++ doc/zh_CN/syntax/04_function.md | 2 ++ doc/zh_CN/syntax/05_builtin_funcs.md | 2 ++ doc/zh_CN/syntax/06_operator.md | 2 ++ doc/zh_CN/syntax/07_side_effect.md | 2 ++ doc/zh_CN/syntax/08_procedure.md | 2 ++ doc/zh_CN/syntax/09_builtin_procs.md | 2 ++ doc/zh_CN/syntax/10_array.md | 2 ++ doc/zh_CN/syntax/11_tuple.md | 2 ++ doc/zh_CN/syntax/12_dict.md | 2 ++ doc/zh_CN/syntax/13_record.md | 2 ++ doc/zh_CN/syntax/14_set.md | 2 ++ doc/zh_CN/syntax/15_type.md | 2 ++ doc/zh_CN/syntax/16_iterator.md | 2 ++ doc/zh_CN/syntax/17_mutability.md | 2 ++ doc/zh_CN/syntax/18_ownership.md | 2 ++ doc/zh_CN/syntax/19_visibility.md | 2 ++ doc/zh_CN/syntax/20_naming_rule.md | 2 ++ doc/zh_CN/syntax/21_lambda.md | 2 ++ doc/zh_CN/syntax/22_subroutine.md | 2 ++ doc/zh_CN/syntax/23_closure.md | 2 ++ doc/zh_CN/syntax/24_module.md | 2 ++ doc/zh_CN/syntax/25_object_system.md | 2 ++ doc/zh_CN/syntax/26_pattern_matching.md | 2 ++ doc/zh_CN/syntax/27_comprehension.md | 2 ++ doc/zh_CN/syntax/28_spread_syntax.md | 2 ++ doc/zh_CN/syntax/29_decorator.md | 2 ++ doc/zh_CN/syntax/30_error_handling.md | 2 ++ doc/zh_CN/syntax/31_pipeline.md | 2 ++ doc/zh_CN/syntax/32_integration_with_Python.md | 2 ++ doc/zh_CN/syntax/33_package_system.md | 2 ++ doc/zh_CN/syntax/34_generator.md | 2 ++ doc/zh_CN/syntax/SUMMARY.md | 2 ++ doc/zh_CN/syntax/container_ownership.md | 2 ++ doc/zh_CN/syntax/indexes.md | 2 ++ doc/zh_CN/syntax/quick_tour.md | 2 ++ doc/zh_CN/syntax/type/01_type_system.md | 2 ++ doc/zh_CN/syntax/type/02_basic.md | 2 ++ doc/zh_CN/syntax/type/03_trait.md | 2 ++ doc/zh_CN/syntax/type/04_class.md | 2 ++ doc/zh_CN/syntax/type/05_inheritance.md | 2 ++ doc/zh_CN/syntax/type/06_nst_vs_sst.md | 2 ++ doc/zh_CN/syntax/type/07_patch.md | 2 ++ doc/zh_CN/syntax/type/08_value.md | 2 ++ doc/zh_CN/syntax/type/09_attributive.md | 2 ++ doc/zh_CN/syntax/type/10_interval.md | 2 ++ doc/zh_CN/syntax/type/11_enum.md | 2 ++ doc/zh_CN/syntax/type/12_refinement.md | 2 ++ doc/zh_CN/syntax/type/13_algebraic.md | 2 ++ doc/zh_CN/syntax/type/14_dependent.md | 2 ++ doc/zh_CN/syntax/type/15_quantified.md | 2 ++ doc/zh_CN/syntax/type/16_subtyping.md | 2 ++ doc/zh_CN/syntax/type/17_type_casting.md | 2 ++ doc/zh_CN/syntax/type/18_mut.md | 2 ++ doc/zh_CN/syntax/type/19_bound.md | 2 ++ doc/zh_CN/syntax/type/advanced.md | 3 ++- doc/zh_CN/syntax/type/advanced/GADTs.md | 2 ++ doc/zh_CN/syntax/type/advanced/_rank2type.md | 2 ++ doc/zh_CN/syntax/type/advanced/default_param.md | 2 ++ doc/zh_CN/syntax/type/advanced/erasure.md | 2 ++ doc/zh_CN/syntax/type/advanced/existential.md | 2 ++ doc/zh_CN/syntax/type/advanced/keyword_param.md | 2 ++ doc/zh_CN/syntax/type/advanced/kind.md | 2 ++ doc/zh_CN/syntax/type/advanced/marker_trait.md | 2 ++ doc/zh_CN/syntax/type/advanced/mut_struct.md | 2 ++ doc/zh_CN/syntax/type/advanced/newtype.md | 2 ++ doc/zh_CN/syntax/type/advanced/overloading.md | 2 ++ doc/zh_CN/syntax/type/advanced/phantom.md | 2 ++ doc/zh_CN/syntax/type/advanced/projection.md | 2 ++ doc/zh_CN/syntax/type/advanced/quantified_dependent.md | 2 ++ doc/zh_CN/syntax/type/advanced/shared.md | 2 ++ doc/zh_CN/syntax/type/advanced/special.md | 2 ++ doc/zh_CN/syntax/type/advanced/typeof.md | 2 ++ doc/zh_CN/syntax/type/advanced/variance.md | 2 ++ doc/zh_CN/syntax/type/advanced/widening.md | 2 ++ doc/zh_CN/tips.md | 2 ++ doc/zh_CN/tools/build.md | 2 ++ doc/zh_CN/tools/env.md | 2 ++ doc/zh_CN/tools/fmt.md | 2 ++ doc/zh_CN/tools/index.md | 2 ++ doc/zh_CN/tools/install.md | 2 ++ doc/zh_CN/tools/pack.md | 2 ++ doc/zh_CN/tools/repl.md | 2 ++ doc/zh_CN/tools/test.md | 2 ++ 186 files changed, 375 insertions(+), 4 deletions(-) diff --git a/doc/zh_CN/API/consts.md b/doc/zh_CN/API/consts.md index b42e2f5b..93936329 100644 --- a/doc/zh_CN/API/consts.md +++ b/doc/zh_CN/API/consts.md @@ -1,5 +1,7 @@ # 内置常量 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/consts.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/consts.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## True ## False diff --git a/doc/zh_CN/API/funcs.md b/doc/zh_CN/API/funcs.md index 0a97634e..25f57506 100644 --- a/doc/zh_CN/API/funcs.md +++ b/doc/zh_CN/API/funcs.md @@ -1,5 +1,7 @@ # 功能 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/funcs.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/funcs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 基本功能 ### if|T; U|(cond: Bool, then: T, else: U) -> T or U diff --git a/doc/zh_CN/API/index.md b/doc/zh_CN/API/index.md index e69de29b..77223195 100644 --- a/doc/zh_CN/API/index.md +++ b/doc/zh_CN/API/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/index.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/API/modules/external/alstruct.md b/doc/zh_CN/API/modules/external/alstruct.md index bfbf7a1b..bf8dd4f5 100644 --- a/doc/zh_CN/API/modules/external/alstruct.md +++ b/doc/zh_CN/API/modules/external/alstruct.md @@ -1,5 +1,7 @@ # 结构 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/external/alstruct.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/external/alstruct.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 模块为它们提供代表代数结构和补丁的特征 * 成员 diff --git a/doc/zh_CN/API/modules/repl.md b/doc/zh_CN/API/modules/repl.md index 0395afcb..9e87ca63 100644 --- a/doc/zh_CN/API/modules/repl.md +++ b/doc/zh_CN/API/modules/repl.md @@ -1,5 +1,7 @@ # 模块`repl` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/repl.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/repl.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 提供REPL(Read-Eval-Print-Loop)相关的API。 ## 功能 diff --git a/doc/zh_CN/API/modules/status.md b/doc/zh_CN/API/modules/status.md index 1e65ebd8..b6750b75 100644 --- a/doc/zh_CN/API/modules/status.md +++ b/doc/zh_CN/API/modules/status.md @@ -1,5 +1,7 @@ # 模块`status` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/status.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/status.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 定义了一个类型来表示状态。请根据情况删除选项来使用它 * ExecResult = {"success", "warning", "failure", "fatal", "unknown"} diff --git a/doc/zh_CN/API/modules/unit.md b/doc/zh_CN/API/modules/unit.md index 179b55f0..62b52bb3 100644 --- a/doc/zh_CN/API/modules/unit.md +++ b/doc/zh_CN/API/modules/unit.md @@ -1,5 +1,7 @@ # 模块`unit` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/unit.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unit.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `unit` 模块是将数值计算中经常使用的单位定义为类型的模块。 Erg 数值类型包括 `Nat`、`Int`、`Ratio` 等。但是,这些类型没有关于“数字的含义”的信息,因此可以执行诸如添加米和码之类的无意义计算。 通过使用 `unit` 模块,您可以避免错误,例如将不同单位的数字传递给函数。 diff --git a/doc/zh_CN/API/modules/unsound.md b/doc/zh_CN/API/modules/unsound.md index adfe6ccf..bfea9285 100644 --- a/doc/zh_CN/API/modules/unsound.md +++ b/doc/zh_CN/API/modules/unsound.md @@ -1,5 +1,7 @@ # 模块 `unsound` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/unsound.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unsound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 让 API 执行在 Erg 的类型系统中无法保证的不健全和不安全的操作。 ## `unsafe!` diff --git a/doc/zh_CN/API/operators.md b/doc/zh_CN/API/operators.md index 82c43c93..e8086f5f 100644 --- a/doc/zh_CN/API/operators.md +++ b/doc/zh_CN/API/operators.md @@ -1,5 +1,7 @@ # 操作员 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/operators.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/operators.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## 中缀运算符 ### `_+_`|R; O; A <: Add(R, O)|(x: A, y: R) -> O diff --git a/doc/zh_CN/API/procs.md b/doc/zh_CN/API/procs.md index e527f5fb..96bcfa6e 100644 --- a/doc/zh_CN/API/procs.md +++ b/doc/zh_CN/API/procs.md @@ -1,5 +1,7 @@ # 过程 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/procs.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/procs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## print! ```python diff --git a/doc/zh_CN/API/special.md b/doc/zh_CN/API/special.md index 6de5fc48..0d164838 100644 --- a/doc/zh_CN/API/special.md +++ b/doc/zh_CN/API/special.md @@ -1,5 +1,7 @@ # 特殊形式 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/special.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 特殊形式是不能在 Erg 类型系统中表达的运算符、子程序(等等)。它被`包围,但实际上无法捕获。 此外,为方便起见,还出现了“Pattern”、“Body”和“Conv”等类型,但不存在此类类型。它的含义也取决于上下文。 diff --git a/doc/zh_CN/API/types.md b/doc/zh_CN/API/types.md index 68f525a0..8358b78c 100644 --- a/doc/zh_CN/API/types.md +++ b/doc/zh_CN/API/types.md @@ -1,5 +1,7 @@ # 内置 Erg 类型列表 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 类型本身的属性不存储在 `.__dict__` 中,不能从实例中引用 ## 基本类型 diff --git a/doc/zh_CN/API/types/classes/Array!(T).md b/doc/zh_CN/API/types/classes/Array!(T).md index 1d020183..e89d474b 100644 --- a/doc/zh_CN/API/types/classes/Array!(T).md +++ b/doc/zh_CN/API/types/classes/Array!(T).md @@ -1,3 +1,5 @@ # Array! T +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Array!(T).md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array!(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示可变长度数组的类型。在编译时长度未知时使用。 有一个语法糖叫做` [t]!`。在`Array! T = ArrayWithMutLength! T, !_`中被定义 \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/Array(T).md b/doc/zh_CN/API/types/classes/Array(T).md index c186d029..e8e7c3e9 100644 --- a/doc/zh_CN/API/types/classes/Array(T).md +++ b/doc/zh_CN/API/types/classes/Array(T).md @@ -1,3 +1,5 @@ # Array T: Type +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Array(T).md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 由`Array T = ArrayWithLen T, _`定义。 有一种语法糖叫做`[T]`。 \ No newline at end of file diff --git a/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md b/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md index 074bbe5d..012c97b5 100644 --- a/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md +++ b/doc/zh_CN/API/types/classes/ArrayWithLen(T,N).md @@ -1,5 +1,7 @@ # ArrayWithLen T: Type, N: Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/ArrayWithLen(T,N).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithLen(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `[T; N]`是语法糖。还有一个[`Array` 类型](./Array.md)省略了长度。 ## 方法 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 842084ca..848c5047 100644 --- a/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md +++ b/doc/zh_CN/API/types/classes/ArrayWithMutLength!(T,N).md @@ -1,5 +1,7 @@ # ArrayWithMutLength! T: Type, N: Nat! +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/ArrayWithMutLength!(T,N).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 一个可变长度数组,其长度在编译时已知。还有语法糖`ArrayWithMutLength(T, !N) == [T; !N]` ## 方法 diff --git a/doc/zh_CN/API/types/classes/Class.md b/doc/zh_CN/API/types/classes/Class.md index e69de29b..8cad7741 100644 --- a/doc/zh_CN/API/types/classes/Class.md +++ b/doc/zh_CN/API/types/classes/Class.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Class.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Class.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/API/types/classes/Complex.md b/doc/zh_CN/API/types/classes/Complex.md index e9e8b49a..6356d002 100644 --- a/doc/zh_CN/API/types/classes/Complex.md +++ b/doc/zh_CN/API/types/classes/Complex.md @@ -1,5 +1,7 @@ # Complex +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Complex.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Complex.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示复数的类型。在 Erg 中表示数字的类型,例如 Float、Int和Nat,通常派生于Complex ## 父类 diff --git a/doc/zh_CN/API/types/classes/Dict!.md b/doc/zh_CN/API/types/classes/Dict!.md index 20e33c4c..01405abd 100644 --- a/doc/zh_CN/API/types/classes/Dict!.md +++ b/doc/zh_CN/API/types/classes/Dict!.md @@ -1,5 +1,7 @@ # Dict! K, V +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Dict!.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Dict!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示字典(哈希Map)的类型。 有一个语法糖叫做`{K: V}` ## 方法 diff --git a/doc/zh_CN/API/types/classes/Either.md b/doc/zh_CN/API/types/classes/Either.md index 43a45deb..71b10f77 100644 --- a/doc/zh_CN/API/types/classes/Either.md +++ b/doc/zh_CN/API/types/classes/Either.md @@ -1,5 +1,7 @@ # Either L, R = L or R +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Either.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Either.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示L或R的类型。 您可以将其视为Or类型的二元形式 ## 方法 diff --git a/doc/zh_CN/API/types/classes/Float.md b/doc/zh_CN/API/types/classes/Float.md index 06479f12..d4969334 100644 --- a/doc/zh_CN/API/types/classes/Float.md +++ b/doc/zh_CN/API/types/classes/Float.md @@ -1,5 +1,7 @@ # Float size +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Float.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Float.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示实数(包含小数的数)的类型。符合IEEE 754的浮点数,在其他语言中一般是float的类型。 Float的大小为8(1byte)~128(16byte)。如果只是Float,则表示`Float64`。 Erg 中的 0.1 实际上属于 Ratio 类型,而不是 Float 类型。没有浮点类型字面量,它是由 `(Ratio object)f64` 生成的(例如 (1/2)f64, 15f64)。 f64 对应实数 1 diff --git a/doc/zh_CN/API/types/classes/Function(N).md b/doc/zh_CN/API/types/classes/Function(N).md index 4317a8ea..08d6b7b0 100644 --- a/doc/zh_CN/API/types/classes/Function(N).md +++ b/doc/zh_CN/API/types/classes/Function(N).md @@ -1,5 +1,7 @@ # Function N: Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Function(N).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Function(N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## Function 1 的方法 * then(self, g: Self) -> Self diff --git a/doc/zh_CN/API/types/classes/Inf.md b/doc/zh_CN/API/types/classes/Inf.md index 0e7e02b9..006ff76c 100644 --- a/doc/zh_CN/API/types/classes/Inf.md +++ b/doc/zh_CN/API/types/classes/Inf.md @@ -1,5 +1,7 @@ # Inf +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Inf.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Inf.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Inf是一个类,其唯一实例是inf。 inf的主要用途是用于区间类型。 例如,大于等于 2 的整数类型是 `2.. Type ``` diff --git a/doc/zh_CN/API/types/classes/Matrix.md b/doc/zh_CN/API/types/classes/Matrix.md index bbb43b4f..2778181b 100644 --- a/doc/zh_CN/API/types/classes/Matrix.md +++ b/doc/zh_CN/API/types/classes/Matrix.md @@ -1,5 +1,7 @@ # Matrix T: Num, Shape: [M, N] +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Matrix.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Matrix.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示矩阵的类型。 它继承自 Tensor[M, N] ## 定义 diff --git a/doc/zh_CN/API/types/classes/Module.md b/doc/zh_CN/API/types/classes/Module.md index 547f7253..135a64da 100644 --- a/doc/zh_CN/API/types/classes/Module.md +++ b/doc/zh_CN/API/types/classes/Module.md @@ -1,3 +1,5 @@ # Module +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Module.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Module.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## 方法 diff --git a/doc/zh_CN/API/types/classes/Nat.md b/doc/zh_CN/API/types/classes/Nat.md index 05911648..248a54c4 100644 --- a/doc/zh_CN/API/types/classes/Nat.md +++ b/doc/zh_CN/API/types/classes/Nat.md @@ -1,5 +1,7 @@ # Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Nat.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Nat.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 表示自然数的类型。 用于数组索引和范围类型 ## 定义 diff --git a/doc/zh_CN/API/types/classes/Neg.md b/doc/zh_CN/API/types/classes/Neg.md index 7298453f..4d76e168 100644 --- a/doc/zh_CN/API/types/classes/Neg.md +++ b/doc/zh_CN/API/types/classes/Neg.md @@ -1,5 +1,7 @@ # Neg +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Neg.md%26commit_hash%3D290c43b09f7c3036112a164bed5fd07a1f6a5cda)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Neg.md&commit_hash=290c43b09f7c3036112a164bed5fd07a1f6a5cda) + 表示负整数的类型。 Pos和Neg和{0} == Int 它还具有一些值得注意的属性,例如不被零除和 Neg * Neg == Pos diff --git a/doc/zh_CN/API/types/classes/Never.md b/doc/zh_CN/API/types/classes/Never.md index 0336f19c..bfd755d3 100644 --- a/doc/zh_CN/API/types/classes/Never.md +++ b/doc/zh_CN/API/types/classes/Never.md @@ -1,5 +1,7 @@ # Never +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Never.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Never.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 它是所有类型的子类型。 它是一个`Class`,因为它拥有所有的方法,当然还有 `.new`。但是,它没有实例,并且Erg会在即将创建的那一刻停止。 还有一种叫做`Panic`的类型没有实例,但是`Never`用于正常终止或故意无限循环,`Panic`用于异常终止。 diff --git a/doc/zh_CN/API/types/classes/NonZero.md b/doc/zh_CN/API/types/classes/NonZero.md index b73422a0..84457444 100644 --- a/doc/zh_CN/API/types/classes/NonZero.md +++ b/doc/zh_CN/API/types/classes/NonZero.md @@ -1,5 +1,7 @@ # NonZero N +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/NonZero.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/NonZero.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示非零数的类。 保证除零的安全性 ```mermaid diff --git a/doc/zh_CN/API/types/classes/Object.md b/doc/zh_CN/API/types/classes/Object.md index 79a6e635..17e0656c 100644 --- a/doc/zh_CN/API/types/classes/Object.md +++ b/doc/zh_CN/API/types/classes/Object.md @@ -1,5 +1,7 @@ # Object +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Object.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Object.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 它是所有类型的超类型 ## 方法 diff --git a/doc/zh_CN/API/types/classes/Operator.md b/doc/zh_CN/API/types/classes/Operator.md index 581e7ac5..006d7dab 100644 --- a/doc/zh_CN/API/types/classes/Operator.md +++ b/doc/zh_CN/API/types/classes/Operator.md @@ -1,5 +1,7 @@ # Operator [...T], O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Operator.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Operator.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 是运算符的类型 ## 定义 diff --git a/doc/zh_CN/API/types/classes/Option.md b/doc/zh_CN/API/types/classes/Option.md index bbcefdf9..2775da7c 100644 --- a/doc/zh_CN/API/types/classes/Option.md +++ b/doc/zh_CN/API/types/classes/Option.md @@ -1,5 +1,7 @@ # Option T = T or NoneType +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Option.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Option.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 表示“可能失败”的类型。 ## 方法 diff --git a/doc/zh_CN/API/types/classes/Pos.md b/doc/zh_CN/API/types/classes/Pos.md index 404b30ae..12632e37 100644 --- a/doc/zh_CN/API/types/classes/Pos.md +++ b/doc/zh_CN/API/types/classes/Pos.md @@ -1,5 +1,7 @@ # Pos +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Pos.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Pos.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Pos是一种表示正数(大于或等于1的整数)的类型。 由于不包括0,因此具有消除被零除的可能性等优点。 diff --git a/doc/zh_CN/API/types/classes/Ratio.md b/doc/zh_CN/API/types/classes/Ratio.md index 58b4211b..dfa56634 100644 --- a/doc/zh_CN/API/types/classes/Ratio.md +++ b/doc/zh_CN/API/types/classes/Ratio.md @@ -1,5 +1,7 @@ # Ratio +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Ratio.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Ratio.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示有理数的类型。 它主要用于当您要使用分数时。 实际上,Erg中的/运算符返回 Ratio。1/3等不被评估为 0.33333... 并且被处理为1/3。 此外,0.1 相当于 1/10。 所以`0.1 + 0.2 == 0.3`。 这听起来很明显,但在 Python中它是False。 但是,Ratio类型的效率往往比Float类型略低。 在执行速度很重要且不需要精确数值的地方应该使用浮点类型。 然而,正如Rob Pike所说,过早优化是万恶之源。 在丢弃Ratio类型并使用Float类型之前,请进行真实的性能测试。 业余爱好者无条件偏爱较轻的模具。 diff --git a/doc/zh_CN/API/types/classes/Record.md b/doc/zh_CN/API/types/classes/Record.md index 7dc5f93f..c1223a0e 100644 --- a/doc/zh_CN/API/types/classes/Record.md +++ b/doc/zh_CN/API/types/classes/Record.md @@ -1,5 +1,7 @@ # Record +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Record.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Record.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 记录所属的类。例如,`{i = 1}` 是`Structural {i = Int}` 类型的元素,并且是`{i = Int}` 类的实例 请注意,其他类的实例是记录类型的元素,而不是记录类的实例 diff --git a/doc/zh_CN/API/types/classes/Result.md b/doc/zh_CN/API/types/classes/Result.md index 67134e03..64515cd0 100644 --- a/doc/zh_CN/API/types/classes/Result.md +++ b/doc/zh_CN/API/types/classes/Result.md @@ -1,5 +1,7 @@ # Result T, E +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Result.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Result.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python Result T, E <: Error = Either T, E ``` diff --git a/doc/zh_CN/API/types/classes/Str!.md b/doc/zh_CN/API/types/classes/Str!.md index af0f1ee7..59a22a69 100644 --- a/doc/zh_CN/API/types/classes/Str!.md +++ b/doc/zh_CN/API/types/classes/Str!.md @@ -1,3 +1,5 @@ # StrWithLen! N: Nat! = Inherit StrWithLen N +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Str!.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示可变长度字符串的类型 diff --git a/doc/zh_CN/API/types/classes/Str.md b/doc/zh_CN/API/types/classes/Str.md index 269ea06a..b496517f 100644 --- a/doc/zh_CN/API/types/classes/Str.md +++ b/doc/zh_CN/API/types/classes/Str.md @@ -1,5 +1,7 @@ # Str +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Str.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + (不变长度)表示字符串的类型。 简单的 `Str` 类型是删除了字符数的 `StrWithLen N` 类型(`Str = StrWithLen _`) ## 方法 diff --git a/doc/zh_CN/API/types/classes/StrWithLen.md b/doc/zh_CN/API/types/classes/StrWithLen.md index e69de29b..67caca65 100644 --- a/doc/zh_CN/API/types/classes/StrWithLen.md +++ b/doc/zh_CN/API/types/classes/StrWithLen.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/StrWithLen.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/StrWithLen.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/API/types/classes/Subroutine.md b/doc/zh_CN/API/types/classes/Subroutine.md index 60bd76de..0c2ee7ab 100644 --- a/doc/zh_CN/API/types/classes/Subroutine.md +++ b/doc/zh_CN/API/types/classes/Subroutine.md @@ -1,5 +1,7 @@ # Subroutine +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Subroutine.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Subroutine.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Func和Proc的基本类型。 ## 方法 diff --git a/doc/zh_CN/API/types/classes/Tensor.md b/doc/zh_CN/API/types/classes/Tensor.md index 2fa51a80..53eb1970 100644 --- a/doc/zh_CN/API/types/classes/Tensor.md +++ b/doc/zh_CN/API/types/classes/Tensor.md @@ -1,5 +1,7 @@ # Tensor Shape: [Nat; N] +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Tensor.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tensor.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 用于有效操作多维数组的类。 它还定义了诸如多维数组上的乘法之类的操作 Matrix、Vector 等都继承自该类型 diff --git a/doc/zh_CN/API/types/classes/TransCell(T).md b/doc/zh_CN/API/types/classes/TransCell(T).md index afb24e2c..a801e8b7 100644 --- a/doc/zh_CN/API/types/classes/TransCell(T).md +++ b/doc/zh_CN/API/types/classes/TransCell(T).md @@ -1,5 +1,7 @@ # TransCell! T: Type! +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/TransCell(T).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/TransCell(T).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 它是一个单元格,其内容可以针对每个模具进行更改。 由于它是T类型的子类型,因此它也表现为T类型 当它在初始化时输入T时很有用,并且在某个点之后总是输入U diff --git a/doc/zh_CN/API/types/classes/Tuple.md b/doc/zh_CN/API/types/classes/Tuple.md index 6ee22bb4..498c1dd1 100644 --- a/doc/zh_CN/API/types/classes/Tuple.md +++ b/doc/zh_CN/API/types/classes/Tuple.md @@ -1,5 +1,7 @@ # Tuple T: ...Type +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Tuple.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tuple.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 包含多种类型对象的集合 ## 方法 diff --git a/doc/zh_CN/API/types/classes/Type.md b/doc/zh_CN/API/types/classes/Type.md index e69de29b..dae4a5c2 100644 --- a/doc/zh_CN/API/types/classes/Type.md +++ b/doc/zh_CN/API/types/classes/Type.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Type.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/API/types/classes/Vector.md b/doc/zh_CN/API/types/classes/Vector.md index f9a159ed..97e73f1e 100644 --- a/doc/zh_CN/API/types/classes/Vector.md +++ b/doc/zh_CN/API/types/classes/Vector.md @@ -1,3 +1,5 @@ # Vector T: Num, N: Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Vector.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Vector.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示向量的类型。与同名的Rust和C++类型不同,这种类型只处理数字。 \ No newline at end of file diff --git a/doc/zh_CN/API/types/patches/BinOp.md b/doc/zh_CN/API/types/patches/BinOp.md index 8494aa4f..63146d8b 100644 --- a/doc/zh_CN/API/types/patches/BinOp.md +++ b/doc/zh_CN/API/types/patches/BinOp.md @@ -1,5 +1,7 @@ # BinOp L, R, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/patches/BinOp.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/BinOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 二元运算符的类型 ## 修补程序 diff --git a/doc/zh_CN/API/types/patches/UnaryOp.md b/doc/zh_CN/API/types/patches/UnaryOp.md index 6b56481a..d38d1f25 100644 --- a/doc/zh_CN/API/types/patches/UnaryOp.md +++ b/doc/zh_CN/API/types/patches/UnaryOp.md @@ -1,5 +1,7 @@ # UnaryOp T, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/patches/UnaryOp.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/UnaryOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 一元运算符的类型 ## 定义 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 4d8b6220..cf36f359 100644 --- a/doc/zh_CN/API/types/traits/Add(R,O).md +++ b/doc/zh_CN/API/types/traits/Add(R,O).md @@ -1,5 +1,7 @@ # Add R +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Add(R,O).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Add(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python Add R = Trait { .AddO = Type 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 020acba5..8aa4af87 100644 --- a/doc/zh_CN/API/types/traits/Div(R,O).md +++ b/doc/zh_CN/API/types/traits/Div(R,O).md @@ -1,5 +1,7 @@ # Div R, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Div(R,O).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Div(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 如果除以零没有错误,请使用“SafeDiv” ```python diff --git a/doc/zh_CN/API/types/traits/Eq.md b/doc/zh_CN/API/types/traits/Eq.md index e69de29b..6aed2ae0 100644 --- a/doc/zh_CN/API/types/traits/Eq.md +++ b/doc/zh_CN/API/types/traits/Eq.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Eq.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Eq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/API/types/traits/Into.md b/doc/zh_CN/API/types/traits/Into.md index de92a824..1cafc6b4 100644 --- a/doc/zh_CN/API/types/traits/Into.md +++ b/doc/zh_CN/API/types/traits/Into.md @@ -1,5 +1,7 @@ # Into T +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Into.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Into.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 一种类型,表明它可以被类型转换为类型T。 即使Self和T之间没有继承关系,也是在关系可以相互转换的时候定义的。 与继承不同,没有隐式转换。您必须始终调用 `.into` 方法。 diff --git a/doc/zh_CN/API/types/traits/Iterable.md b/doc/zh_CN/API/types/traits/Iterable.md index e69de29b..ba458258 100644 --- a/doc/zh_CN/API/types/traits/Iterable.md +++ b/doc/zh_CN/API/types/traits/Iterable.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Iterable.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Iterable.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/API/types/traits/Num.md b/doc/zh_CN/API/types/traits/Num.md index d5e3b2d8..71b5cabb 100644 --- a/doc/zh_CN/API/types/traits/Num.md +++ b/doc/zh_CN/API/types/traits/Num.md @@ -1,5 +1,7 @@ # Num +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Num.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Num.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 定义初始化 ```python diff --git a/doc/zh_CN/API/types/traits/Ord.md b/doc/zh_CN/API/types/traits/Ord.md index e69de29b..3ef5f04a 100644 --- a/doc/zh_CN/API/types/traits/Ord.md +++ b/doc/zh_CN/API/types/traits/Ord.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Ord.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Ord.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/API/types/traits/SafeDiv(R,O).md b/doc/zh_CN/API/types/traits/SafeDiv(R,O).md index 998faf89..03595643 100644 --- a/doc/zh_CN/API/types/traits/SafeDiv(R,O).md +++ b/doc/zh_CN/API/types/traits/SafeDiv(R,O).md @@ -1,5 +1,7 @@ # SafeDiv R, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/SafeDiv(R,O).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/SafeDiv(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python SafeDiv R, O = Subsume Div, { @Override diff --git a/doc/zh_CN/API/types/traits/Sample.md b/doc/zh_CN/API/types/traits/Sample.md index 5d2a6cdb..5eb0a24c 100644 --- a/doc/zh_CN/API/types/traits/Sample.md +++ b/doc/zh_CN/API/types/traits/Sample.md @@ -1,5 +1,7 @@ # Sample +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Sample.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Sample.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 具有“随机”选择实例的`sample`和`sample!`方法的特征。`sample`方法总是返回相同的实例,而`sample!`方法返回一个随机实例,该实例随调用而变化 请注意,这是一个假设您想要一个适当的实例进行测试等的特征,并且它不一定是随机的。 如果您想要随机抽样,请使用“随机”模块。 diff --git a/doc/zh_CN/API/types/traits/Seq.md b/doc/zh_CN/API/types/traits/Seq.md index e69de29b..007f7134 100644 --- a/doc/zh_CN/API/types/traits/Seq.md +++ b/doc/zh_CN/API/types/traits/Seq.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Seq.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Seq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/API/types/traits/Show.md b/doc/zh_CN/API/types/traits/Show.md index e69de29b..30763e02 100644 --- a/doc/zh_CN/API/types/traits/Show.md +++ b/doc/zh_CN/API/types/traits/Show.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Show.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Show.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/API/types/traits/Unpack.md b/doc/zh_CN/API/types/traits/Unpack.md index 7c721151..dabbd429 100644 --- a/doc/zh_CN/API/types/traits/Unpack.md +++ b/doc/zh_CN/API/types/traits/Unpack.md @@ -1,5 +1,7 @@ # Unpack +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Unpack.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Unpack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 标记性状。实现时,元素可以像记录一样通过模式匹配来分解 ```python diff --git a/doc/zh_CN/compiler/TODO_hint.md b/doc/zh_CN/compiler/TODO_hint.md index 790ce1f7..5f949d02 100644 --- a/doc/zh_CN/compiler/TODO_hint.md +++ b/doc/zh_CN/compiler/TODO_hint.md @@ -1,4 +1,6 @@ # 提示(未实现) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/TODO_hint.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_hint.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * `x 未定义`(x 已被`Del` 删除)=> `提示:在第 X 行删除` *补丁方法重复:“提示:指定补丁(如`T.foo(1)`)或使用`Del`删除任何`.foo`” \ No newline at end of file diff --git a/doc/zh_CN/compiler/TODO_recov_suggest.md b/doc/zh_CN/compiler/TODO_recov_suggest.md index 93a193b1..68a5164c 100644 --- a/doc/zh_CN/compiler/TODO_recov_suggest.md +++ b/doc/zh_CN/compiler/TODO_recov_suggest.md @@ -1,5 +1,7 @@ # 错误恢复建议(尚未实现) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/TODO_recov_suggest.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_recov_suggest.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * `1 or 2`, `1 and 2` => `{1, 2}`? * `U = Inherit T` => 非类类型不能被继承,或者`U = Class T`? * `Int and Str` => 不允许多重继承,或者`Int or Str`? diff --git a/doc/zh_CN/compiler/TODO_warn.md b/doc/zh_CN/compiler/TODO_warn.md index 9f1fcf23..1b25747f 100644 --- a/doc/zh_CN/compiler/TODO_warn.md +++ b/doc/zh_CN/compiler/TODO_warn.md @@ -1,5 +1,7 @@ # 警告(尚未实现) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/TODO_warn.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_warn.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * `t = {(record type)}` => `T = {(record type)}`?(只有定义为常量的类型才能用于类型说明) * `{I: Int | ...}!` => `{I: Int! | ...}` * for/while 块中的`return x`(`x != ()`) => `f::return`(外部块)? \ No newline at end of file diff --git a/doc/zh_CN/compiler/abandoned.md b/doc/zh_CN/compiler/abandoned.md index dc120306..547012b8 100644 --- a/doc/zh_CN/compiler/abandoned.md +++ b/doc/zh_CN/compiler/abandoned.md @@ -1,5 +1,7 @@ # 废弃/拒绝的语言规范 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/abandoned.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/abandoned.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## 重载(临时多态性) 被放弃了,因为它可以用参数+子类型多态来代替,并且与Python的语义不兼容。 有关详细信息,请参阅 [overload](../syntax/type/overloading.md) 文章。 diff --git a/doc/zh_CN/compiler/architecture.md b/doc/zh_CN/compiler/architecture.md index f33fdfaf..04135067 100644 --- a/doc/zh_CN/compiler/architecture.md +++ b/doc/zh_CN/compiler/architecture.md @@ -1,5 +1,7 @@ # `ergc` 的架构 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/architecture.md%26commit_hash%3Da711efa99b325ba1012f6897e7b0e2bdb947d8a1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/architecture.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1) + ## 1. 扫描 Erg 脚本 (.er) 并生成 `TokenStream` (parser/lex.rs) * parser/lexer/Lexer 生成`TokenStream`(这是一个Token的迭代器,TokenStream可以通过lexer.collect()生成) diff --git a/doc/zh_CN/compiler/errors.md b/doc/zh_CN/compiler/errors.md index 722d1339..444187d7 100644 --- a/doc/zh_CN/compiler/errors.md +++ b/doc/zh_CN/compiler/errors.md @@ -1,5 +1,7 @@ # Erg Compiler Errors +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/errors.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/errors.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## AssignError 尝试重写不可变变量时发生 diff --git a/doc/zh_CN/compiler/hir.md b/doc/zh_CN/compiler/hir.md index 748cc4d6..b95ecb81 100644 --- a/doc/zh_CN/compiler/hir.md +++ b/doc/zh_CN/compiler/hir.md @@ -1,5 +1,7 @@ # 高级中间表示(HIR, High-level Intermediate Representation) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/hir.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/hir.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + HIR 是 Erg 编译器从 AST 生成的结构 此结构包含源代码中每个表达式的完整类型信息,并且在语法上已脱糖 AST与源代码一一对应(纯文本),但是HIR去掉了不必要的代码信息,添加了省略的类型信息,所以HIR可以转换为源代码很难恢复 diff --git a/doc/zh_CN/compiler/index.md b/doc/zh_CN/compiler/index.md index e69de29b..33522b77 100644 --- a/doc/zh_CN/compiler/index.md +++ b/doc/zh_CN/compiler/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/index.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/compiler/inference.md b/doc/zh_CN/compiler/inference.md index d40a5298..40b05ec8 100644 --- a/doc/zh_CN/compiler/inference.md +++ b/doc/zh_CN/compiler/inference.md @@ -1,5 +1,7 @@ # 类型推断算法 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/inference.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/inference.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + > __Warning__:此部分正在编辑中,可能包含一些错误 显示了下面使用的符号 diff --git a/doc/zh_CN/compiler/overview.md b/doc/zh_CN/compiler/overview.md index e5e5c7f8..933d2021 100644 --- a/doc/zh_CN/compiler/overview.md +++ b/doc/zh_CN/compiler/overview.md @@ -1,5 +1,7 @@ # `erg` 概览 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/overview.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/overview.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 我们将介绍每一层的功能以及特别重要的功能和方法。 ## 1. 词法分析 diff --git a/doc/zh_CN/compiler/parsing.md b/doc/zh_CN/compiler/parsing.md index aa540a33..1db31cde 100644 --- a/doc/zh_CN/compiler/parsing.md +++ b/doc/zh_CN/compiler/parsing.md @@ -1,5 +1,7 @@ # 解析 Erg 语言 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/parsing.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/parsing.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 空格的处理 Erg语法的一个特点是它对空间敏感。 diff --git a/doc/zh_CN/compiler/refinement_subtyping.md b/doc/zh_CN/compiler/refinement_subtyping.md index 631a9da8..de5b0c36 100644 --- a/doc/zh_CN/compiler/refinement_subtyping.md +++ b/doc/zh_CN/compiler/refinement_subtyping.md @@ -1,5 +1,7 @@ # 筛子类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/refinement_subtyping.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/refinement_subtyping.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python {I: Int | I >= 0} {S: StrWithLen N | N >= 1} diff --git a/doc/zh_CN/compiler/trait_method_resolving.md b/doc/zh_CN/compiler/trait_method_resolving.md index 66574713..fff36fad 100644 --- a/doc/zh_CN/compiler/trait_method_resolving.md +++ b/doc/zh_CN/compiler/trait_method_resolving.md @@ -1,5 +1,7 @@ # 解决补丁方法 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/trait_method_resolving.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/trait_method_resolving.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `Nat` 是零个或多个`Int`,`Int` 的子类型。 `Nat` 在 Python 类层次结构中不存在。 我想知道 Erg 是如何解决这个补丁方法的? diff --git a/doc/zh_CN/compiler/transpile.md b/doc/zh_CN/compiler/transpile.md index 396c72d7..2027f17b 100644 --- a/doc/zh_CN/compiler/transpile.md +++ b/doc/zh_CN/compiler/transpile.md @@ -1,5 +1,7 @@ # Erg 代码如何转译成 Python 代码? +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/transpile.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/transpile.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 准确地说,Erg 代码被转译为 Python 字节码。 但是,由于 Python 字节码几乎可以重构为 Python 代码,因此这里以等效的 Python 代码为例。 顺便说一句,这里展示的示例是低优化级别。 diff --git a/doc/zh_CN/compiler/type_var_normalization.md b/doc/zh_CN/compiler/type_var_normalization.md index fded3f21..31f4785e 100644 --- a/doc/zh_CN/compiler/type_var_normalization.md +++ b/doc/zh_CN/compiler/type_var_normalization.md @@ -1,5 +1,7 @@ # 归一化 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/type_var_normalization.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/type_var_normalization.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * Erg 的类型参数规范化基于 SymPy 的简化函数。 例如,当您定义 `concat: |T, M, N|([T; M], [T; N] -> [T; M+N])` 时,您可以匹配类型变量和参数而无需实例化它们.必须作出判断。 diff --git a/doc/zh_CN/dev_guide/branches.md b/doc/zh_CN/dev_guide/branches.md index c4380f04..e7f01c04 100644 --- a/doc/zh_CN/dev_guide/branches.md +++ b/doc/zh_CN/dev_guide/branches.md @@ -1,5 +1,7 @@ # 分支机构命名和运营策略 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/branches.md%26commit_hash%3Da711efa99b325ba1012f6897e7b0e2bdb947d8a1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/branches.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1) + ## main * 主要开发分支 diff --git a/doc/zh_CN/dev_guide/build_features.md b/doc/zh_CN/dev_guide/build_features.md index 0de6c136..507b6b48 100644 --- a/doc/zh_CN/dev_guide/build_features.md +++ b/doc/zh_CN/dev_guide/build_features.md @@ -1,5 +1,7 @@ # `erg` 构建功能 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/build_features.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/build_features.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 调试 进入调试模式。结果,Erg 内部的行为顺序显示在日志中。 diff --git a/doc/zh_CN/dev_guide/directories.md b/doc/zh_CN/dev_guide/directories.md index a44615e3..7f8a7867 100644 --- a/doc/zh_CN/dev_guide/directories.md +++ b/doc/zh_CN/dev_guide/directories.md @@ -1,5 +1,7 @@ # Erg存储表结构 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/directories.md%26commit_hash%3Da711efa99b325ba1012f6897e7b0e2bdb947d8a1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/directories.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1) + ```console └─┬ assets:图片等 ├─ CODE_OF_CONDUCT:行为准则 diff --git a/doc/zh_CN/dev_guide/doc_guideline.md b/doc/zh_CN/dev_guide/doc_guideline.md index 56899909..07749069 100644 --- a/doc/zh_CN/dev_guide/doc_guideline.md +++ b/doc/zh_CN/dev_guide/doc_guideline.md @@ -1,5 +1,7 @@ # 格式 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/doc_guideline.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/doc_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 任何不符合以下规则的文件都将得到更正。 * 以某种语气写代码注释或内部文档。 diff --git a/doc/zh_CN/dev_guide/env.md b/doc/zh_CN/dev_guide/env.md index 3c98f96d..ab2a43a1 100644 --- a/doc/zh_CN/dev_guide/env.md +++ b/doc/zh_CN/dev_guide/env.md @@ -1,5 +1,7 @@ # 开发环境 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/env.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## 你需要安装什么 * Rust(与 rustup 一起安装) diff --git a/doc/zh_CN/dev_guide/faq_syntax.md b/doc/zh_CN/dev_guide/faq_syntax.md index 23bcb495..5f236bfe 100644 --- a/doc/zh_CN/dev_guide/faq_syntax.md +++ b/doc/zh_CN/dev_guide/faq_syntax.md @@ -1,5 +1,7 @@ # Erg design's "Why" and Answers +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/faq_syntax.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/faq_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 当我们有所有权系统时,为什么要与 GC 共存? 因为 Erg 推出所有权系统的动机并不是为了 Rust 那样的“不依赖 GC 的内存管理”。最初,由于 Erg 是一种语言,目前使用 Python VM,因此最终仍使用 GC。Erg 引入产权系统的目标是“可变状态的局部化”。在 Erg 中,可变对象具有所有权概念。这是根据共享可变状态容易成为 bug 的温床,甚至是类型安全性的侵犯(详见)来判断的。 diff --git a/doc/zh_CN/dev_guide/i18n_messages.md b/doc/zh_CN/dev_guide/i18n_messages.md index 7a2fdbb5..96f6eceb 100644 --- a/doc/zh_CN/dev_guide/i18n_messages.md +++ b/doc/zh_CN/dev_guide/i18n_messages.md @@ -1,5 +1,7 @@ # 多语言错误信息 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/i18n_messages.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/i18n_messages.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Erg 正在推动消息(开始、选项、文档、提示、警告、错误消息等)的多语言化。如果你不熟悉 Rust 或 Erg,也可以参与此项目。请务必配合。 以下是多语种方法的说明。 diff --git a/doc/zh_CN/dev_guide/index.md b/doc/zh_CN/dev_guide/index.md index e69de29b..0e41be9e 100644 --- a/doc/zh_CN/dev_guide/index.md +++ b/doc/zh_CN/dev_guide/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/index.md%26commit_hash%3D7d43acdf0e2b71528b038b9a8e70be6c93831f96)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/index.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96) + diff --git a/doc/zh_CN/dev_guide/rust_code_guideline.md b/doc/zh_CN/dev_guide/rust_code_guideline.md index 0c15a9f7..24c4e3e4 100644 --- a/doc/zh_CN/dev_guide/rust_code_guideline.md +++ b/doc/zh_CN/dev_guide/rust_code_guideline.md @@ -1,5 +1,7 @@ # Rust 代码指南 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/rust_code_guideline.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/rust_code_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## 本地规则 * 使用 `log!` 进行调试输出(使用 `println!` 等进行输出处理,这也是发布所必需的)。 diff --git a/doc/zh_CN/dev_guide/terms.md b/doc/zh_CN/dev_guide/terms.md index 8dc55e6e..eb31fb2b 100644 --- a/doc/zh_CN/dev_guide/terms.md +++ b/doc/zh_CN/dev_guide/terms.md @@ -1,5 +1,7 @@ # 词汇表 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/terms.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 象征 ### ! diff --git a/doc/zh_CN/dev_guide/unify_terms.md b/doc/zh_CN/dev_guide/unify_terms.md index 1a8a2dba..1161bf5b 100644 --- a/doc/zh_CN/dev_guide/unify_terms.md +++ b/doc/zh_CN/dev_guide/unify_terms.md @@ -1,5 +1,7 @@ # 术语统一 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/unify_terms.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/unify_terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 可访问性,可见性 使用可见性。 diff --git a/doc/zh_CN/faq_general.md b/doc/zh_CN/faq_general.md index 8d1166e1..92293ab9 100644 --- a/doc/zh_CN/faq_general.md +++ b/doc/zh_CN/faq_general.md @@ -1,8 +1,10 @@ # Erg常见问题 -此常见问题解答适用于一般 Erg 初学者。 -对于个别(常见)技术问题,请参阅 [此处](./faq_technical.md) 了解个别(常见)技术问题,以及 -[这里](./dev_guide/faq_syntax.md) 了解更多信息。 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/faq_general.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_general.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + +This FAQ is intended for the general Erg beginner. +For individual (common) technical issues, please refer to [here](./faq_technical.md) for individual (common) technical issues, and +[Here](./dev_guide/faq_syntax.md) for more information. ## Erg 是 Python 兼容语言是什么意思? diff --git a/doc/zh_CN/faq_technical.md b/doc/zh_CN/faq_technical.md index ec04e3a3..2af1fe74 100644 --- a/doc/zh_CN/faq_technical.md +++ b/doc/zh_CN/faq_technical.md @@ -1,5 +1,7 @@ # 技术常见问题 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/faq_technical.md%26commit_hash%3Dc120700585fdb1d655255c8e2817bb13cc8d369e)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_technical.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e) + 本节回答有关使用 Erg 语言的技术问题。换句话说,它包含以 What 或 Which 开头的问题,以及可以用 Yes/No 回答的问题。 有关如何确定语法的更多信息,请参阅 [此处](./dev_guide/faq_syntax.md) 了解基础语法决策,以及 [此处](./dev_guide/../faq_general.md)。 diff --git a/doc/zh_CN/improved_points.md b/doc/zh_CN/improved_points.md index dcea4a90..8bf32e6f 100644 --- a/doc/zh_CN/improved_points.md +++ b/doc/zh_CN/improved_points.md @@ -1,5 +1,7 @@ # Python 的改进 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/improved_points.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/improved_points.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## 执行静态分析(静态类型检查、变量和属性检查) 静态类型检查的好处现在怎么强调都不为过,但是检查变量和属性的存在也是相当重要的一部分。 diff --git a/doc/zh_CN/index.md b/doc/zh_CN/index.md index c7d9e9ae..b331eef8 100644 --- a/doc/zh_CN/index.md +++ b/doc/zh_CN/index.md @@ -1,5 +1,7 @@ # 索引 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/index.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/index.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## [API/](./API/index.md) 本节介绍 Erg 的内置或标准库提供的子程序、类型、常量等的规范。 diff --git a/doc/zh_CN/migration_from_py.md b/doc/zh_CN/migration_from_py.md index abb19725..aafb570c 100644 --- a/doc/zh_CN/migration_from_py.md +++ b/doc/zh_CN/migration_from_py.md @@ -1,5 +1,7 @@ # 从 Python 迁移到 Erg 的提示 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/migration_from_py.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/migration_from_py.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 我想将字符串转换为 int 等。 使用 `Str` 类的 `parse` 方法。 它返回一个 `Result` 类型。 diff --git a/doc/zh_CN/python/bytecode_instructions.md b/doc/zh_CN/python/bytecode_instructions.md index c93ec1eb..5b43757b 100644 --- a/doc/zh_CN/python/bytecode_instructions.md +++ b/doc/zh_CN/python/bytecode_instructions.md @@ -1,5 +1,7 @@ # Python 字节码指令 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/bytecode_instructions.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_instructions.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Python 字节码变量操作命令通过 名称索引(名称索引)访问。 这是为了在 Python 中实现动态变量访问(可以使用 eval 等作为字符串访问)。 一条指令为 2 个字节,指令和参数以 little endian 形式存储。 不带参数的指令也使用 2 个字节(参数部分为 0)。 diff --git a/doc/zh_CN/python/bytecode_specification.md b/doc/zh_CN/python/bytecode_specification.md index 036912c0..9f79f3fa 100644 --- a/doc/zh_CN/python/bytecode_specification.md +++ b/doc/zh_CN/python/bytecode_specification.md @@ -1,5 +1,7 @@ # Python bytecode specification +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/bytecode_specification.md%26commit_hash%3D9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_specification.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4) + ## Format * 0~3 byte(u32): magic number (see common/bytecode.rs for details) diff --git a/doc/zh_CN/python/class_system.md b/doc/zh_CN/python/class_system.md index 6623395d..e7e2debc 100644 --- a/doc/zh_CN/python/class_system.md +++ b/doc/zh_CN/python/class_system.md @@ -1,5 +1,7 @@ # Python 类系统(与 Erg 比较) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/class_system.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/class_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 方法 方法可以被前向引用,但这不是一种特殊的技术。 diff --git a/doc/zh_CN/python/index.md b/doc/zh_CN/python/index.md index e69de29b..2168ad9d 100644 --- a/doc/zh_CN/python/index.md +++ b/doc/zh_CN/python/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/index.md%26commit_hash%3D9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/index.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4) + diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md index bb438d9a..d7289f48 100644 --- a/doc/zh_CN/syntax/00_basic.md +++ b/doc/zh_CN/syntax/00_basic.md @@ -1,5 +1,7 @@ # 基本 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/00_basic.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + > __Warning__:本文档不完整。 它未经校对(样式、正确链接、误译等)。 此外,Erg 的语法可能在版本 0.* 期间发生破坏性更改,并且文档可能没有相应更新。 请事先了解这一点。 > 如果您在本文档中发现任何错误,请报告至 [此处的表单](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我们将不胜感激您的建议。 diff --git a/doc/zh_CN/syntax/01_literal.md b/doc/zh_CN/syntax/01_literal.md index 9292471e..8988ca29 100644 --- a/doc/zh_CN/syntax/01_literal.md +++ b/doc/zh_CN/syntax/01_literal.md @@ -1,5 +1,7 @@ # 字面量 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/01_literal.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/01_literal.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 基本字面量 ### 整数字面量 diff --git a/doc/zh_CN/syntax/02_name.md b/doc/zh_CN/syntax/02_name.md index cbb0ef36..321b6fd3 100644 --- a/doc/zh_CN/syntax/02_name.md +++ b/doc/zh_CN/syntax/02_name.md @@ -1,5 +1,7 @@ # 多变的 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/02_name.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 变量是一种代数; Erg 中的代数 - 如果没有混淆,有时简称为变量 - 指的是命名对象并使它们可从代码的其他地方引用的功能。 变量定义如下。 diff --git a/doc/zh_CN/syntax/03_declaration.md b/doc/zh_CN/syntax/03_declaration.md index 458c4097..06e0b5dc 100644 --- a/doc/zh_CN/syntax/03_declaration.md +++ b/doc/zh_CN/syntax/03_declaration.md @@ -1,5 +1,7 @@ # 宣言(Declaration) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/03_declaration.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/03_declaration.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 声明是用于指定要使用的变量类型的语法。 可以在代码中的任何地方进行声明,但单独的声明并不引用变量。 它们必须被初始化。 分配后,可以检查声明以确保类型与分配它的对象兼容。 diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md index 3dd6143c..085e9be2 100644 --- a/doc/zh_CN/syntax/04_function.md +++ b/doc/zh_CN/syntax/04_function.md @@ -1,5 +1,7 @@ # 功能 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/04_function.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/04_function.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 函数是一个块,它接受一个“参数”,对其进行处理,并将其作为“返回值”返回。 定义如下。 ```python diff --git a/doc/zh_CN/syntax/05_builtin_funcs.md b/doc/zh_CN/syntax/05_builtin_funcs.md index 9a21013c..6fd87b16 100644 --- a/doc/zh_CN/syntax/05_builtin_funcs.md +++ b/doc/zh_CN/syntax/05_builtin_funcs.md @@ -1,5 +1,7 @@ # 内置函数 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/05_builtin_funcs.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/05_builtin_funcs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 如果 `if` 是一个根据条件改变处理的函数。 diff --git a/doc/zh_CN/syntax/06_operator.md b/doc/zh_CN/syntax/06_operator.md index a7c8955e..f2f9b6cc 100644 --- a/doc/zh_CN/syntax/06_operator.md +++ b/doc/zh_CN/syntax/06_operator.md @@ -1,5 +1,7 @@ # 运算符 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/06_operator.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/06_operator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 运算符是表示操作的符号。 操作数是运算符(左)右侧的东西。 运算符是一种函数,因此它们本身就是可以绑定到变量的一流对象。 绑定时,需要用```括起来。 diff --git a/doc/zh_CN/syntax/07_side_effect.md b/doc/zh_CN/syntax/07_side_effect.md index 3b7d414a..2f53c78f 100644 --- a/doc/zh_CN/syntax/07_side_effect.md +++ b/doc/zh_CN/syntax/07_side_effect.md @@ -1,5 +1,7 @@ # 副作用和程序 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/07_side_effect.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/07_side_effect.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 我们一直忽略了解释“!”的含义,但现在它的含义终于要揭晓了。 这个 `!` 表示这个对象是一个带有“副作用”的“过程”。 过程是具有副作用的函数。 ```python diff --git a/doc/zh_CN/syntax/08_procedure.md b/doc/zh_CN/syntax/08_procedure.md index 3ce9e05a..137b68d0 100644 --- a/doc/zh_CN/syntax/08_procedure.md +++ b/doc/zh_CN/syntax/08_procedure.md @@ -1,5 +1,7 @@ # 程序 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/08_procedure.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/08_procedure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 处理可变对象时需要过程,但将可变对象作为参数并不一定使其成为过程。 这是一个函数接受一个可变对象(不是过程)。 diff --git a/doc/zh_CN/syntax/09_builtin_procs.md b/doc/zh_CN/syntax/09_builtin_procs.md index f2e878c2..837740fb 100644 --- a/doc/zh_CN/syntax/09_builtin_procs.md +++ b/doc/zh_CN/syntax/09_builtin_procs.md @@ -1,5 +1,7 @@ # 内置程序 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/09_builtin_procs.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/09_builtin_procs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## id! 返回对象的唯一标识号。 diff --git a/doc/zh_CN/syntax/10_array.md b/doc/zh_CN/syntax/10_array.md index c77cc7cd..39602e97 100644 --- a/doc/zh_CN/syntax/10_array.md +++ b/doc/zh_CN/syntax/10_array.md @@ -1,5 +1,7 @@ # Array +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/10_array.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/10_array.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 数组是最基本的__collection(聚合)__。 集合是一个可以在其中包含多个对象的对象。 diff --git a/doc/zh_CN/syntax/11_tuple.md b/doc/zh_CN/syntax/11_tuple.md index 95f2502a..ddf8ecad 100644 --- a/doc/zh_CN/syntax/11_tuple.md +++ b/doc/zh_CN/syntax/11_tuple.md @@ -1,5 +1,7 @@ # 元组 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/11_tuple.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/11_tuple.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 元组类似于数组,但可以保存不同类型的对象。 这样的集合称为不等集合。 相比之下,同构集合包括数组、集合等。 diff --git a/doc/zh_CN/syntax/12_dict.md b/doc/zh_CN/syntax/12_dict.md index 08938fcd..ac3cae2f 100644 --- a/doc/zh_CN/syntax/12_dict.md +++ b/doc/zh_CN/syntax/12_dict.md @@ -1,5 +1,7 @@ # 字典 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/12_dict.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/12_dict.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Dict 是键/值对的集合。 ```python diff --git a/doc/zh_CN/syntax/13_record.md b/doc/zh_CN/syntax/13_record.md index 2990ed55..f82431ac 100644 --- a/doc/zh_CN/syntax/13_record.md +++ b/doc/zh_CN/syntax/13_record.md @@ -1,5 +1,7 @@ # 记录(Record) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/13_record.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/13_record.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 记录是一个集合,它结合了通过键访问的 Dict 和在编译时检查其访问的元组的属性。 如果您了解 JavaScript,请将其视为一种(更增强的)对象字面量表示法。 diff --git a/doc/zh_CN/syntax/14_set.md b/doc/zh_CN/syntax/14_set.md index e209411d..d405043c 100644 --- a/doc/zh_CN/syntax/14_set.md +++ b/doc/zh_CN/syntax/14_set.md @@ -1,5 +1,7 @@ # Set +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/14_set.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/14_set.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 一个Set代表一个集合,它在结构上是一个重复的无序数组。 ```python diff --git a/doc/zh_CN/syntax/15_type.md b/doc/zh_CN/syntax/15_type.md index 37dd77c6..06d8b48b 100644 --- a/doc/zh_CN/syntax/15_type.md +++ b/doc/zh_CN/syntax/15_type.md @@ -1,5 +1,7 @@ # 类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/15_type.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/15_type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 类型是 Erg 中一个非常重要的特性,所以我们有一个 [dedicated section](./type/01_type_system.md)。 请看那里。

diff --git a/doc/zh_CN/syntax/16_iterator.md b/doc/zh_CN/syntax/16_iterator.md index a2733c5c..06a05bba 100644 --- a/doc/zh_CN/syntax/16_iterator.md +++ b/doc/zh_CN/syntax/16_iterator.md @@ -1,5 +1,7 @@ # 迭代器 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/16_iterator.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/16_iterator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 迭代器是用于检索容器元素的对象。 ```python diff --git a/doc/zh_CN/syntax/17_mutability.md b/doc/zh_CN/syntax/17_mutability.md index 3d89fad4..8c646504 100644 --- a/doc/zh_CN/syntax/17_mutability.md +++ b/doc/zh_CN/syntax/17_mutability.md @@ -1,5 +1,7 @@ # 可变性 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/17_mutability.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/17_mutability.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 正如我们已经看到的,所有 Erg 变量都是不可变的。 但是,Erg 对象具有可变性的概念。 以下面的代码为例。 diff --git a/doc/zh_CN/syntax/18_ownership.md b/doc/zh_CN/syntax/18_ownership.md index 0f473a8f..890b627e 100644 --- a/doc/zh_CN/syntax/18_ownership.md +++ b/doc/zh_CN/syntax/18_ownership.md @@ -1,5 +1,7 @@ #所有权制度 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/18_ownership.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/18_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 由于 Erg 是一种使用 Python 作为宿主语言的语言,因此内存管理的方法取决于 Python 的实现。 但语义上 Erg 的内存管理与 Python 的不同。 一个显着的区别在于所有权制度和禁止循环引用。 diff --git a/doc/zh_CN/syntax/19_visibility.md b/doc/zh_CN/syntax/19_visibility.md index 0e79c0e0..a11d9879 100644 --- a/doc/zh_CN/syntax/19_visibility.md +++ b/doc/zh_CN/syntax/19_visibility.md @@ -1,5 +1,7 @@ # 可见性 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/19_visibility.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/19_visibility.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg 变量具有 __visibility__ 的概念。 到目前为止,我们看到的所有变量都称为 __private variables__。 这是一个外部不可见的变量。 例如,`foo` 模块中定义的私有变量不能被另一个模块引用。 diff --git a/doc/zh_CN/syntax/20_naming_rule.md b/doc/zh_CN/syntax/20_naming_rule.md index 7847b7ce..7794a217 100644 --- a/doc/zh_CN/syntax/20_naming_rule.md +++ b/doc/zh_CN/syntax/20_naming_rule.md @@ -1,5 +1,7 @@ # 命名约定 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/20_naming_rule.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/20_naming_rule.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 如果要将变量用作常量表达式,请确保它以大写字母开头。 两个或多个字母可能是小写的。 ```python diff --git a/doc/zh_CN/syntax/21_lambda.md b/doc/zh_CN/syntax/21_lambda.md index 33776284..e97ca473 100644 --- a/doc/zh_CN/syntax/21_lambda.md +++ b/doc/zh_CN/syntax/21_lambda.md @@ -1,5 +1,7 @@ # 匿名函数 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/21_lambda.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/21_lambda.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 匿名函数是一种无需命名即可动态创建函数对象的语法。 ```python diff --git a/doc/zh_CN/syntax/22_subroutine.md b/doc/zh_CN/syntax/22_subroutine.md index 38fafc51..c4f34957 100644 --- a/doc/zh_CN/syntax/22_subroutine.md +++ b/doc/zh_CN/syntax/22_subroutine.md @@ -1,5 +1,7 @@ # 子程序签名 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/22_subroutine.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/22_subroutine.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 函数 ```python diff --git a/doc/zh_CN/syntax/23_closure.md b/doc/zh_CN/syntax/23_closure.md index eb3122ac..221214ed 100644 --- a/doc/zh_CN/syntax/23_closure.md +++ b/doc/zh_CN/syntax/23_closure.md @@ -1,5 +1,7 @@ # 关闭 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/23_closure.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/23_closure.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg 子例程有一个称为“闭包”的功能,可以捕获外部变量。 ```python diff --git a/doc/zh_CN/syntax/24_module.md b/doc/zh_CN/syntax/24_module.md index eee8832e..f518c1dc 100644 --- a/doc/zh_CN/syntax/24_module.md +++ b/doc/zh_CN/syntax/24_module.md @@ -1,5 +1,7 @@ # module +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/24_module.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/24_module.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg allows you to think of the file itself as a single record. This is called a module. ```python: foo.er diff --git a/doc/zh_CN/syntax/25_object_system.md b/doc/zh_CN/syntax/25_object_system.md index 116cd662..edf799ba 100644 --- a/doc/zh_CN/syntax/25_object_system.md +++ b/doc/zh_CN/syntax/25_object_system.md @@ -1,5 +1,7 @@ # 目的 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/25_object_system.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/25_object_system.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 可以分配给变量的所有数据。 `Object` 类的属性如下。 * `.__repr__`:返回对象的(非丰富)字符串表示 diff --git a/doc/zh_CN/syntax/26_pattern_matching.md b/doc/zh_CN/syntax/26_pattern_matching.md index 047fc29d..54aa9c25 100644 --- a/doc/zh_CN/syntax/26_pattern_matching.md +++ b/doc/zh_CN/syntax/26_pattern_matching.md @@ -1,5 +1,7 @@ # 模式匹配,可反驳 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/26_pattern_matching.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/26_pattern_matching.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## Erg 中可用的模式 ### 变量模式 diff --git a/doc/zh_CN/syntax/27_comprehension.md b/doc/zh_CN/syntax/27_comprehension.md index 6e301665..3883de17 100644 --- a/doc/zh_CN/syntax/27_comprehension.md +++ b/doc/zh_CN/syntax/27_comprehension.md @@ -1,5 +1,7 @@ # Comprehension +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/27_comprehension.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/27_comprehension.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Array 和 `[expr | (name <- iterable)+ (predicate)*]`, set 和 `{expr | (name <- iterable)+ (predicate)*}`, 你可以创建一个字典 `{key: value | (name <- iterable)+ (predicate)*}`. diff --git a/doc/zh_CN/syntax/28_spread_syntax.md b/doc/zh_CN/syntax/28_spread_syntax.md index 81b98343..4251afb9 100644 --- a/doc/zh_CN/syntax/28_spread_syntax.md +++ b/doc/zh_CN/syntax/28_spread_syntax.md @@ -1,5 +1,7 @@ # 传播赋值 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/28_spread_syntax.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/28_spread_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 在分解赋值中,将 `...` 放在变量前面会将所有剩余元素展开到该变量中。 这称为扩展赋值。 ```python diff --git a/doc/zh_CN/syntax/29_decorator.md b/doc/zh_CN/syntax/29_decorator.md index 9046f20c..7f0c5c0a 100644 --- a/doc/zh_CN/syntax/29_decorator.md +++ b/doc/zh_CN/syntax/29_decorator.md @@ -1,5 +1,7 @@ # 装饰器(修饰符) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/29_decorator.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/29_decorator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 装饰器用于向类型或函数添加或演示特定状态或行为。 装饰器的语法如下。 diff --git a/doc/zh_CN/syntax/30_error_handling.md b/doc/zh_CN/syntax/30_error_handling.md index 5b64a6f8..770493c8 100644 --- a/doc/zh_CN/syntax/30_error_handling.md +++ b/doc/zh_CN/syntax/30_error_handling.md @@ -1,5 +1,7 @@ # 错误处理系统 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/30_error_handling.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/30_error_handling.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 主要使用Result类型。 在 Erg 中,如果您丢弃 Error 类型的对象(顶层不支持),则会发生错误。 diff --git a/doc/zh_CN/syntax/31_pipeline.md b/doc/zh_CN/syntax/31_pipeline.md index acaeef49..aa2f8c03 100644 --- a/doc/zh_CN/syntax/31_pipeline.md +++ b/doc/zh_CN/syntax/31_pipeline.md @@ -1,5 +1,7 @@ # 管道运算符 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/31_pipeline.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/31_pipeline.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 管道运算符的使用方式如下: ```python diff --git a/doc/zh_CN/syntax/32_integration_with_Python.md b/doc/zh_CN/syntax/32_integration_with_Python.md index 25261dd0..0b716866 100644 --- a/doc/zh_CN/syntax/32_integration_with_Python.md +++ b/doc/zh_CN/syntax/32_integration_with_Python.md @@ -1,5 +1,7 @@ # 与 Python 集成 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/32_integration_with_Python.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/32_integration_with_Python.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 导出到 Python 编译 Erg 脚本时,会生成一个 .pyc 文件,可以简单地将其作为 Python 模块导入。 diff --git a/doc/zh_CN/syntax/33_package_system.md b/doc/zh_CN/syntax/33_package_system.md index a2a817fd..6a2b5e3d 100644 --- a/doc/zh_CN/syntax/33_package_system.md +++ b/doc/zh_CN/syntax/33_package_system.md @@ -1,5 +1,7 @@ # 打包系统 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/33_package_system.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/33_package_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Erg包大致可以分为app包,即应用程序,以及lib包,即库。 应用包的入口点是`src/app.er`。 `app.er` 中定义的`main` 函数被执行。 lib 包的入口点是`src/lib.er`。导入包相当于导入 `lib.er`。 diff --git a/doc/zh_CN/syntax/34_generator.md b/doc/zh_CN/syntax/34_generator.md index 8d260ba1..903ca254 100644 --- a/doc/zh_CN/syntax/34_generator.md +++ b/doc/zh_CN/syntax/34_generator.md @@ -1,5 +1,7 @@ # 生成器 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/34_generator.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/34_generator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 生成器是在块中使用 `yield!` 过程的特殊过程。 ```python diff --git a/doc/zh_CN/syntax/SUMMARY.md b/doc/zh_CN/syntax/SUMMARY.md index f9486625..2eebbae2 100644 --- a/doc/zh_CN/syntax/SUMMARY.md +++ b/doc/zh_CN/syntax/SUMMARY.md @@ -1,5 +1,7 @@ # 概括 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/SUMMARY.md%26commit_hash%3D2ce482b1c8407332b3b74f4c3e5596f373f9a657)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/SUMMARY.md&commit_hash=2ce482b1c8407332b3b74f4c3e5596f373f9a657) + - [基础](./00_basic.md) - [文字](./01_literal.md) - [名称](02_name.md) diff --git a/doc/zh_CN/syntax/container_ownership.md b/doc/zh_CN/syntax/container_ownership.md index 09bbfb3c..2e786beb 100644 --- a/doc/zh_CN/syntax/container_ownership.md +++ b/doc/zh_CN/syntax/container_ownership.md @@ -1,5 +1,7 @@ # 下标(索引访问) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/container_ownership.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/container_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `[]` 不同于普通的方法。 ```python diff --git a/doc/zh_CN/syntax/indexes.md b/doc/zh_CN/syntax/indexes.md index b60d9945..100d1c15 100644 --- a/doc/zh_CN/syntax/indexes.md +++ b/doc/zh_CN/syntax/indexes.md @@ -1,5 +1,7 @@ # 指数 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/indexes.md%26commit_hash%3D438bcb89ea692f219b30f3a3ba107888b23eae98)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/indexes.md&commit_hash=438bcb89ea692f219b30f3a3ba107888b23eae98) + 有关不在此索引中的 API,请参阅 [此处](../API/index.md)。 有关术语,请参见 [此处](../dev_guide/terms.md)。 diff --git a/doc/zh_CN/syntax/quick_tour.md b/doc/zh_CN/syntax/quick_tour.md index e891c70f..10124e7b 100644 --- a/doc/zh_CN/syntax/quick_tour.md +++ b/doc/zh_CN/syntax/quick_tour.md @@ -1,5 +1,7 @@ # 快速浏览 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/quick_tour.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/quick_tour.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `syntax` 下面的文档是为了让编程初学者也能理解而编写的。 对于已经掌握 Python、Rust、Haskell 等语言的人来说,可能有点啰嗦。 diff --git a/doc/zh_CN/syntax/type/01_type_system.md b/doc/zh_CN/syntax/type/01_type_system.md index 7ed2b019..79d58268 100644 --- a/doc/zh_CN/syntax/type/01_type_system.md +++ b/doc/zh_CN/syntax/type/01_type_system.md @@ -1,5 +1,7 @@ # Erg 的类型系统 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/01_type_system.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/01_type_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 下面简单介绍一下 Erg 的类型系统。 详细信息在其他部分进行说明。 ## 如何定义 diff --git a/doc/zh_CN/syntax/type/02_basic.md b/doc/zh_CN/syntax/type/02_basic.md index adca8428..e892dea7 100644 --- a/doc/zh_CN/syntax/type/02_basic.md +++ b/doc/zh_CN/syntax/type/02_basic.md @@ -1,5 +1,7 @@ # 类型的基本语法 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/02_basic.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/02_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 类型规范 在 Erg 中,可以在 `:` 之后指定变量的类型,如下所示。这可以与作业同时完成。 diff --git a/doc/zh_CN/syntax/type/03_trait.md b/doc/zh_CN/syntax/type/03_trait.md index 0fbca1ef..98bfc4ac 100644 --- a/doc/zh_CN/syntax/type/03_trait.md +++ b/doc/zh_CN/syntax/type/03_trait.md @@ -1,5 +1,7 @@ # 特质 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/03_trait.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/03_trait.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Trait 是一种名义类型,它将类型属性要求添加到记录类型。 它类似于 Python 中的抽象基类 (ABC),但区别在于能够执行代数运算。 diff --git a/doc/zh_CN/syntax/type/04_class.md b/doc/zh_CN/syntax/type/04_class.md index a95fabe5..1dc74c05 100644 --- a/doc/zh_CN/syntax/type/04_class.md +++ b/doc/zh_CN/syntax/type/04_class.md @@ -1,5 +1,7 @@ # Class +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/04_class.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/04_class.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Erg 中的类大致是一种可以创建自己的元素(实例)的类型。 这是一个简单类的示例。 diff --git a/doc/zh_CN/syntax/type/05_inheritance.md b/doc/zh_CN/syntax/type/05_inheritance.md index c4efa961..92e2e712 100644 --- a/doc/zh_CN/syntax/type/05_inheritance.md +++ b/doc/zh_CN/syntax/type/05_inheritance.md @@ -1,5 +1,7 @@ # 继承 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/05_inheritance.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/05_inheritance.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 继承允许您定义一个新类,为现有类添加功能或专业化。 继承类似于包含在特征中。 继承的类成为原始类的子类型。 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 7d0393eb..496ab445 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,7 @@ # 名义子类型与结构子类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/06_nst_vs_sst.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/06_nst_vs_sst.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ```python Months = 0..12 diff --git a/doc/zh_CN/syntax/type/07_patch.md b/doc/zh_CN/syntax/type/07_patch.md index 20adf0c8..8116131b 100644 --- a/doc/zh_CN/syntax/type/07_patch.md +++ b/doc/zh_CN/syntax/type/07_patch.md @@ -1,5 +1,7 @@ # 修补 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/07_patch.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/07_patch.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Erg 不允许修改现有类型和类。 这意味着,不可能在类中定义额外的方法,也不能执行特化(一种语言特性,单态化多态声明的类型并定义专用方法,如在 C++ 中)。 但是,在许多情况下,您可能希望向现有类型或类添加功能,并且有一个称为“修补”的功能允许您执行此操作。 diff --git a/doc/zh_CN/syntax/type/08_value.md b/doc/zh_CN/syntax/type/08_value.md index 1483139a..fa3eef3f 100644 --- a/doc/zh_CN/syntax/type/08_value.md +++ b/doc/zh_CN/syntax/type/08_value.md @@ -1,5 +1,7 @@ # 值类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/08_value.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/08_value.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 值类型是可以在编译时评估的 Erg 内置类型,具体来说: ```python diff --git a/doc/zh_CN/syntax/type/09_attributive.md b/doc/zh_CN/syntax/type/09_attributive.md index 96cae23e..c56369ad 100644 --- a/doc/zh_CN/syntax/type/09_attributive.md +++ b/doc/zh_CN/syntax/type/09_attributive.md @@ -1,5 +1,7 @@ # 属性类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/09_attributive.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/09_attributive.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 属性类型是包含 Record 和 Dataclass、Patch、Module 等的类型。 属于属性类型的类型不是值类型。 diff --git a/doc/zh_CN/syntax/type/10_interval.md b/doc/zh_CN/syntax/type/10_interval.md index 2ecd67e8..3bbbb1b1 100644 --- a/doc/zh_CN/syntax/type/10_interval.md +++ b/doc/zh_CN/syntax/type/10_interval.md @@ -1,5 +1,7 @@ # 间隔类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/10_interval.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/10_interval.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + `Range` 对象最基本的用途是作为迭代器。 ```python diff --git a/doc/zh_CN/syntax/type/11_enum.md b/doc/zh_CN/syntax/type/11_enum.md index 50fd9fe9..81df11cd 100644 --- a/doc/zh_CN/syntax/type/11_enum.md +++ b/doc/zh_CN/syntax/type/11_enum.md @@ -1,5 +1,7 @@ # 枚举类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/11_enum.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/11_enum.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Set 生成的枚举类型。 枚举类型可以与类型规范一起使用,但可以通过将它们分类为类或定义修复程序来定义进一步的方法。 diff --git a/doc/zh_CN/syntax/type/12_refinement.md b/doc/zh_CN/syntax/type/12_refinement.md index 7c51a5fb..be86096f 100644 --- a/doc/zh_CN/syntax/type/12_refinement.md +++ b/doc/zh_CN/syntax/type/12_refinement.md @@ -1,5 +1,7 @@ # 细化类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/12_refinement.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/12_refinement.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 细化类型是受谓词表达式约束的类型。 枚举类型和区间类型是细化类型的语法糖。 细化类型的标准形式是`{Elem: Type | (预)*}`。 这意味着该类型是其元素为满足 `Pred` 的 `Elem` 的类型。 diff --git a/doc/zh_CN/syntax/type/13_algebraic.md b/doc/zh_CN/syntax/type/13_algebraic.md index ae777027..98156aa3 100644 --- a/doc/zh_CN/syntax/type/13_algebraic.md +++ b/doc/zh_CN/syntax/type/13_algebraic.md @@ -1,5 +1,7 @@ # 代数类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/13_algebraic.md%26commit_hash%3Dc120700585fdb1d655255c8e2817bb13cc8d369e)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/13_algebraic.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e) + 代数类型是通过将类型视为代数来操作类型而生成的类型。 它们处理的操作包括Union、Intersection、Diff、Complement等。 普通类只能进行Union,其他操作会导致类型错误。 diff --git a/doc/zh_CN/syntax/type/14_dependent.md b/doc/zh_CN/syntax/type/14_dependent.md index 70ef8633..64e0c1eb 100644 --- a/doc/zh_CN/syntax/type/14_dependent.md +++ b/doc/zh_CN/syntax/type/14_dependent.md @@ -1,5 +1,7 @@ # 依赖类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/14_dependent.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/14_dependent.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 依赖类型是一个特性,可以说是 Erg 的最大特性。 依赖类型是将值作为参数的类型。 普通的多态类型只能将类型作为参数,但依赖类型放宽了这个限制。 diff --git a/doc/zh_CN/syntax/type/15_quantified.md b/doc/zh_CN/syntax/type/15_quantified.md index fb4af5b7..d6212a30 100644 --- a/doc/zh_CN/syntax/type/15_quantified.md +++ b/doc/zh_CN/syntax/type/15_quantified.md @@ -1,5 +1,7 @@ # 类型变量,量化类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/15_quantified.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/15_quantified.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 类型变量是用于例如指定子程序参数类型的变量,它的类型是任意的(不是单态的)。 首先,作为引入类型变量的动机,考虑 `id` 函数,它按原样返回输入。 diff --git a/doc/zh_CN/syntax/type/16_subtyping.md b/doc/zh_CN/syntax/type/16_subtyping.md index 86c44646..5ca87c63 100644 --- a/doc/zh_CN/syntax/type/16_subtyping.md +++ b/doc/zh_CN/syntax/type/16_subtyping.md @@ -1,5 +1,7 @@ # 子类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/16_subtyping.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/16_subtyping.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 在 Erg 中,可以使用比较运算符 `<`、`>` 确定类包含。 ```python diff --git a/doc/zh_CN/syntax/type/17_type_casting.md b/doc/zh_CN/syntax/type/17_type_casting.md index 5fd31369..2500c346 100644 --- a/doc/zh_CN/syntax/type/17_type_casting.md +++ b/doc/zh_CN/syntax/type/17_type_casting.md @@ -1,5 +1,7 @@ # 投掷 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/17_type_casting.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/17_type_casting.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 向上转型 因为 Python 是一种使用鸭子类型的语言,所以没有强制转换的概念。没有必要向上转型,本质上也没有向下转型。 diff --git a/doc/zh_CN/syntax/type/18_mut.md b/doc/zh_CN/syntax/type/18_mut.md index 30f660a2..d1f11fc8 100644 --- a/doc/zh_CN/syntax/type/18_mut.md +++ b/doc/zh_CN/syntax/type/18_mut.md @@ -1,5 +1,7 @@ # 可变类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/18_mut.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/18_mut.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + > __Warning__:本节中的信息是旧的并且包含一些错误。 默认情况下,Erg 中的所有类型都是不可变的,即它们的内部状态无法更新。 diff --git a/doc/zh_CN/syntax/type/19_bound.md b/doc/zh_CN/syntax/type/19_bound.md index d6aecf50..cba0b9ca 100644 --- a/doc/zh_CN/syntax/type/19_bound.md +++ b/doc/zh_CN/syntax/type/19_bound.md @@ -1,5 +1,7 @@ # 类型绑定 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/19_bound.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/19_bound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 类型边界为类型规范添加条件。 实现这一点的函数是守卫(守卫子句)。 此功能可用于函数签名、匿名函数签名以及筛选类型。 守卫写在返回类型之后。 diff --git a/doc/zh_CN/syntax/type/advanced.md b/doc/zh_CN/syntax/type/advanced.md index 01dd89dc..95724a0c 100644 --- a/doc/zh_CN/syntax/type/advanced.md +++ b/doc/zh_CN/syntax/type/advanced.md @@ -1 +1,2 @@ -下面,我们将讨论更高级的类型系统。 初学者不必阅读所有部分。 \ No newline at end of file +下面,我们将讨论更高级的类型系统。 初学者不必阅读所有部分。[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/syntax/type/advanced/GADTs.md b/doc/zh_CN/syntax/type/advanced/GADTs.md index 8210a9dd..80e00bb5 100644 --- a/doc/zh_CN/syntax/type/advanced/GADTs.md +++ b/doc/zh_CN/syntax/type/advanced/GADTs.md @@ -1,5 +1,7 @@ # 广义代数数据类型 (GADT) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/GADTs.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/GADTs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg 可以通过对 Or 类型进行分类来创建广义代数数据类型 (GADT)。 ```python diff --git a/doc/zh_CN/syntax/type/advanced/_rank2type.md b/doc/zh_CN/syntax/type/advanced/_rank2type.md index 596df334..676743a7 100644 --- a/doc/zh_CN/syntax/type/advanced/_rank2type.md +++ b/doc/zh_CN/syntax/type/advanced/_rank2type.md @@ -1,5 +1,7 @@ # rank-2 多态性 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/_rank2type.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/_rank2type.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + > __Warning__:本文档已过时,一般包含错误。 Erg 允许您定义接受各种类型的函数,例如 `id|T|(x: T): T = x`,即多相关。 diff --git a/doc/zh_CN/syntax/type/advanced/default_param.md b/doc/zh_CN/syntax/type/advanced/default_param.md index 34b2a88d..27d3dc18 100644 --- a/doc/zh_CN/syntax/type/advanced/default_param.md +++ b/doc/zh_CN/syntax/type/advanced/default_param.md @@ -1,5 +1,7 @@ # 带默认参数的函数类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/default_param.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/default_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 首先,让我们看一个使用默认参数的示例。 ```python diff --git a/doc/zh_CN/syntax/type/advanced/erasure.md b/doc/zh_CN/syntax/type/advanced/erasure.md index 99532ba9..3395ecf7 100644 --- a/doc/zh_CN/syntax/type/advanced/erasure.md +++ b/doc/zh_CN/syntax/type/advanced/erasure.md @@ -1,5 +1,7 @@ # 类型擦除 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/erasure.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/erasure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 类型擦除是将类型参数设置为 `_` 并故意丢弃其信息的过程。类型擦除是许多多态语言的特性,但在 Erg 的语法上下文中,将其称为类型参数擦除更为准确。 类型擦除的最常见示例是 `[T, _]`。数组在编译时并不总是知道它们的长度。例如,引用命令行参数的 `sys.argv` 的类型为 `[Str, _]`。由于 Erg 的编译器无法知道命令行参数的长度,因此必须放弃有关其长度的信息。 diff --git a/doc/zh_CN/syntax/type/advanced/existential.md b/doc/zh_CN/syntax/type/advanced/existential.md index f28b67ed..fb829825 100644 --- a/doc/zh_CN/syntax/type/advanced/existential.md +++ b/doc/zh_CN/syntax/type/advanced/existential.md @@ -1,5 +1,7 @@ # 存在类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/existential.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/existential.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 如果存在对应于∀的for-all类型,那么很自然地假设存在对应于∃的存在类型。 存在类型并不难。 你已经知道存在类型,只是没有意识到它本身。 diff --git a/doc/zh_CN/syntax/type/advanced/keyword_param.md b/doc/zh_CN/syntax/type/advanced/keyword_param.md index 0989b952..8b934d23 100644 --- a/doc/zh_CN/syntax/type/advanced/keyword_param.md +++ b/doc/zh_CN/syntax/type/advanced/keyword_param.md @@ -1,5 +1,7 @@ # 带有关键字参数的函数类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/keyword_param.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/keyword_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python h(f) = f(y: 1, x: 2) h: |T: type|((y: Int, x: Int) -> T) -> T diff --git a/doc/zh_CN/syntax/type/advanced/kind.md b/doc/zh_CN/syntax/type/advanced/kind.md index f0da4035..7d881724 100644 --- a/doc/zh_CN/syntax/type/advanced/kind.md +++ b/doc/zh_CN/syntax/type/advanced/kind.md @@ -1,5 +1,7 @@ # Kind +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/kind.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/kind.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 一切都在 Erg 中输入。类型本身也不例外。 __kind__ 表示“类型的类型”。例如,`Int` 属于 `Type`,就像 `1` 属于 `Int`。 `Type` 是最简单的一种,__atomic kind__。在类型论符号中,`Type` 对应于 `*`。 在Kind的概念中,实际上重要的是一种或多种Kind(多项式Kind)。单项类型,例如`Option`,属于它。一元Kind表示为 `Type -> Type` [1](#1)。诸如 `Array` 或 `Option` 之类的 __container__ 特别是一种以类型作为参数的多项式类型。 diff --git a/doc/zh_CN/syntax/type/advanced/marker_trait.md b/doc/zh_CN/syntax/type/advanced/marker_trait.md index 67227598..153b4b1b 100644 --- a/doc/zh_CN/syntax/type/advanced/marker_trait.md +++ b/doc/zh_CN/syntax/type/advanced/marker_trait.md @@ -1,5 +1,7 @@ # 标记特征 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/marker_trait.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/marker_trait.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 标记特征是没有必需属性的特征。 也就是说,您可以在不实现任何方法的情况下实现 Impl。 没有 required 属性似乎没有意义,但由于注册了它属于 trait 的信息,因此可以使用 patch 方法或由编译器进行特殊处理。 diff --git a/doc/zh_CN/syntax/type/advanced/mut_struct.md b/doc/zh_CN/syntax/type/advanced/mut_struct.md index e17faa08..c84bc953 100644 --- a/doc/zh_CN/syntax/type/advanced/mut_struct.md +++ b/doc/zh_CN/syntax/type/advanced/mut_struct.md @@ -1,5 +1,7 @@ # 可变结构类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/mut_struct.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/mut_struct.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + `T!` 类型被描述为可以被任何 `T` 类型对象替换的盒子类型。 ```python diff --git a/doc/zh_CN/syntax/type/advanced/newtype.md b/doc/zh_CN/syntax/type/advanced/newtype.md index 7100c029..d1cb33db 100644 --- a/doc/zh_CN/syntax/type/advanced/newtype.md +++ b/doc/zh_CN/syntax/type/advanced/newtype.md @@ -1,5 +1,7 @@ # 新类型模式 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/newtype.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/newtype.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 这是 Rust 中常用的 newtype 模式的 Erg 版本。 Erg 允许定义类型别名如下,但它们只引用相同的类型。 diff --git a/doc/zh_CN/syntax/type/advanced/overloading.md b/doc/zh_CN/syntax/type/advanced/overloading.md index a0654bc4..db6a3602 100644 --- a/doc/zh_CN/syntax/type/advanced/overloading.md +++ b/doc/zh_CN/syntax/type/advanced/overloading.md @@ -1,5 +1,7 @@ # 重载 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/overloading.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/overloading.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Erg 不支持 __ad hoc 多态性__。 也就是说,函数和种类(重载)的多重定义是不可能的。 但是,您可以通过使用特征和补丁的组合来重现重载行为。 您可以使用特征而不是特征类,但随后将涵盖所有实现 `.add1` 的类型。 diff --git a/doc/zh_CN/syntax/type/advanced/phantom.md b/doc/zh_CN/syntax/type/advanced/phantom.md index 14c95749..df02c8f2 100644 --- a/doc/zh_CN/syntax/type/advanced/phantom.md +++ b/doc/zh_CN/syntax/type/advanced/phantom.md @@ -1,5 +1,7 @@ # 幻影(phantom)类 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/phantom.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/phantom.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 幻像类型是标记特征,其存在仅用于向编译器提供注释。 作为幻像类型的一种用法,让我们看一下列表的结构。 diff --git a/doc/zh_CN/syntax/type/advanced/projection.md b/doc/zh_CN/syntax/type/advanced/projection.md index 9ecaf889..ec90aa23 100644 --- a/doc/zh_CN/syntax/type/advanced/projection.md +++ b/doc/zh_CN/syntax/type/advanced/projection.md @@ -1,5 +1,7 @@ # 投影类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/projection.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/projection.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 投影类型表示如下代码中的“Self.AddO”等类型。 ```python diff --git a/doc/zh_CN/syntax/type/advanced/quantified_dependent.md b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md index c96caca5..69a963d2 100644 --- a/doc/zh_CN/syntax/type/advanced/quantified_dependent.md +++ b/doc/zh_CN/syntax/type/advanced/quantified_dependent.md @@ -1,5 +1,7 @@ # 量化依赖类型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/quantified_dependent.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/quantified_dependent.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Erg 有量化和依赖类型。 那么很自然地,就可以创建一个将两者结合起来的类型。 那是量化的依赖类型。 ```python diff --git a/doc/zh_CN/syntax/type/advanced/shared.md b/doc/zh_CN/syntax/type/advanced/shared.md index ec294166..41678db2 100644 --- a/doc/zh_CN/syntax/type/advanced/shared.md +++ b/doc/zh_CN/syntax/type/advanced/shared.md @@ -1,5 +1,7 @@ # 共享参考 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/shared.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/shared.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 共享引用是必须小心处理的语言特性之一。 例如,在 TypeScript 中,以下代码将通过类型检查。 diff --git a/doc/zh_CN/syntax/type/advanced/special.md b/doc/zh_CN/syntax/type/advanced/special.md index 92cbeb0b..a2c86f07 100644 --- a/doc/zh_CN/syntax/type/advanced/special.md +++ b/doc/zh_CN/syntax/type/advanced/special.md @@ -1,5 +1,7 @@ # 特殊类型(Self、Super) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/special.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `Self` 代表它自己的类型。 您可以将其用作别名,但请注意派生类型的含义会发生变化(指的是自己的类型)。 ```python diff --git a/doc/zh_CN/syntax/type/advanced/typeof.md b/doc/zh_CN/syntax/type/advanced/typeof.md index 7fd520cd..a59fc6e6 100644 --- a/doc/zh_CN/syntax/type/advanced/typeof.md +++ b/doc/zh_CN/syntax/type/advanced/typeof.md @@ -1,5 +1,7 @@ # Typeof, classof +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/typeof.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/typeof.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `Typeof` 是一个可以窥探 Erg 类型推断系统的函数,它的行为很复杂 ```python diff --git a/doc/zh_CN/syntax/type/advanced/variance.md b/doc/zh_CN/syntax/type/advanced/variance.md index 26943813..5bf2d16c 100644 --- a/doc/zh_CN/syntax/type/advanced/variance.md +++ b/doc/zh_CN/syntax/type/advanced/variance.md @@ -1,5 +1,7 @@ # 变化 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/variance.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/variance.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg 可以对多态类型进行子类型化,但有一些注意事项。 首先,考虑普通多态类型的包含关系。一般来说,有一个容器`K`和它分配的类型`A,B`,当`A < B`时,`K A < K B`。 diff --git a/doc/zh_CN/syntax/type/advanced/widening.md b/doc/zh_CN/syntax/type/advanced/widening.md index 91e13f34..8a542a21 100644 --- a/doc/zh_CN/syntax/type/advanced/widening.md +++ b/doc/zh_CN/syntax/type/advanced/widening.md @@ -1,5 +1,7 @@ # 类型加宽 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/widening.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/widening.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 例如,定义多相关系数如下。 ```python diff --git a/doc/zh_CN/tips.md b/doc/zh_CN/tips.md index 7d8264bc..e2e74133 100644 --- a/doc/zh_CN/tips.md +++ b/doc/zh_CN/tips.md @@ -1,5 +1,7 @@ # 提示 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tips.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tips.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 想要更改显示错误的语言 请为您的语言下载 Erg。 diff --git a/doc/zh_CN/tools/build.md b/doc/zh_CN/tools/build.md index 7d28452e..c80f030e 100644 --- a/doc/zh_CN/tools/build.md +++ b/doc/zh_CN/tools/build.md @@ -1,5 +1,7 @@ # 构建子命令 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/build.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/build.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + build 子命令构建包。 默认构建中执行的步骤如下: diff --git a/doc/zh_CN/tools/env.md b/doc/zh_CN/tools/env.md index ada55481..6bcfc01f 100644 --- a/doc/zh_CN/tools/env.md +++ b/doc/zh_CN/tools/env.md @@ -1,5 +1,7 @@ # 环境子命令 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/env.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + env 子命令指定 erg 执行环境。 使用 `erg env new [env name]` 创建一个新的执行环境。 将打开一个交互式工具,当您指定 erg 版本时,将安装该版本的 erg(如果已存在,将使用它),您将能够将其用作新环境。 您可以使用 `erg env switch [env name]` 切换环境。 diff --git a/doc/zh_CN/tools/fmt.md b/doc/zh_CN/tools/fmt.md index b24ecae8..69451162 100644 --- a/doc/zh_CN/tools/fmt.md +++ b/doc/zh_CN/tools/fmt.md @@ -1,5 +1,7 @@ # fmt +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/fmt.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/fmt.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 可以使用 fmt 子命令来完成代码格式化。 常用的标志有: diff --git a/doc/zh_CN/tools/index.md b/doc/zh_CN/tools/index.md index e69de29b..f08300dc 100644 --- a/doc/zh_CN/tools/index.md +++ b/doc/zh_CN/tools/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/index.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_CN/tools/install.md b/doc/zh_CN/tools/install.md index f59145b5..97ac813b 100644 --- a/doc/zh_CN/tools/install.md +++ b/doc/zh_CN/tools/install.md @@ -1,5 +1,7 @@ # 安装子命令 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/install.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/install.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 您可以使用 install 安装在注册表站点上注册的软件包。 基本用法与cargo等包管理器相同。 diff --git a/doc/zh_CN/tools/pack.md b/doc/zh_CN/tools/pack.md index 59f35f19..09e59f2c 100644 --- a/doc/zh_CN/tools/pack.md +++ b/doc/zh_CN/tools/pack.md @@ -1,5 +1,7 @@ # 包管理器 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/pack.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/pack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg 标配有一个包管理器,您可以使用 `pack` 子命令调用它。 以下是典型的选项。 diff --git a/doc/zh_CN/tools/repl.md b/doc/zh_CN/tools/repl.md index 94fab78f..954841b2 100644 --- a/doc/zh_CN/tools/repl.md +++ b/doc/zh_CN/tools/repl.md @@ -1,5 +1,7 @@ # REPL +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/repl.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/repl.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 运行不带参数的 `erg` 命令会调用 REPL。 它也可以用 `repl` 子命令调用。 此外,您可以指定以下标志: diff --git a/doc/zh_CN/tools/test.md b/doc/zh_CN/tools/test.md index 278035c4..93abac45 100644 --- a/doc/zh_CN/tools/test.md +++ b/doc/zh_CN/tools/test.md @@ -1,5 +1,7 @@ # 测试子命令 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/test.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/test.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + erg 命令有一个名为 test 的子命令,它支持测试的实现和执行。 ## 测试装饰器 (@Test) From 53776fc22aac6c98fd5f7e9f6babbdb3bb848d85 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Tue, 6 Sep 2022 20:13:44 +0800 Subject: [PATCH 32/42] Update to zh_TW doc to put translation badges --- doc/zh_TW/API/consts.md | 2 ++ doc/zh_TW/API/funcs.md | 2 ++ doc/zh_TW/API/index.md | 2 ++ doc/zh_TW/API/modules/external/alstruct.md | 2 ++ doc/zh_TW/API/modules/repl.md | 2 ++ doc/zh_TW/API/modules/status.md | 2 ++ doc/zh_TW/API/modules/unit.md | 2 ++ doc/zh_TW/API/modules/unsound.md | 2 ++ doc/zh_TW/API/operators.md | 2 ++ doc/zh_TW/API/procs.md | 2 ++ doc/zh_TW/API/special.md | 2 ++ doc/zh_TW/API/types.md | 2 ++ doc/zh_TW/API/types/classes/Array!(T).md | 2 ++ doc/zh_TW/API/types/classes/Array(T).md | 2 ++ doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md | 2 ++ doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md | 2 ++ doc/zh_TW/API/types/classes/Class.md | 2 ++ doc/zh_TW/API/types/classes/Complex.md | 2 ++ doc/zh_TW/API/types/classes/Dict!.md | 2 ++ doc/zh_TW/API/types/classes/Either.md | 2 ++ doc/zh_TW/API/types/classes/Float.md | 2 ++ doc/zh_TW/API/types/classes/Function(N).md | 2 ++ doc/zh_TW/API/types/classes/Inf.md | 2 ++ doc/zh_TW/API/types/classes/Int.md | 2 ++ doc/zh_TW/API/types/classes/IntRange.md | 2 ++ doc/zh_TW/API/types/classes/Interval.md | 2 ++ doc/zh_TW/API/types/classes/Iterator.md | 2 ++ doc/zh_TW/API/types/classes/Kind(N).md | 2 ++ doc/zh_TW/API/types/classes/Matrix.md | 2 ++ doc/zh_TW/API/types/classes/Module.md | 2 ++ doc/zh_TW/API/types/classes/Nat.md | 2 ++ doc/zh_TW/API/types/classes/Neg.md | 2 ++ doc/zh_TW/API/types/classes/Never.md | 2 ++ doc/zh_TW/API/types/classes/NonZero.md | 2 ++ doc/zh_TW/API/types/classes/Object.md | 2 ++ doc/zh_TW/API/types/classes/Operator.md | 2 ++ doc/zh_TW/API/types/classes/Option.md | 2 ++ doc/zh_TW/API/types/classes/Pos.md | 2 ++ doc/zh_TW/API/types/classes/Ratio.md | 2 ++ doc/zh_TW/API/types/classes/Record.md | 2 ++ doc/zh_TW/API/types/classes/Result.md | 2 ++ doc/zh_TW/API/types/classes/Str!.md | 2 ++ doc/zh_TW/API/types/classes/Str.md | 2 ++ doc/zh_TW/API/types/classes/StrWithLen.md | 2 ++ doc/zh_TW/API/types/classes/Subroutine.md | 2 ++ doc/zh_TW/API/types/classes/Tensor.md | 2 ++ doc/zh_TW/API/types/classes/TransCell(T).md | 2 ++ doc/zh_TW/API/types/classes/Tuple.md | 2 ++ doc/zh_TW/API/types/classes/Type.md | 2 ++ doc/zh_TW/API/types/classes/Vector.md | 2 ++ doc/zh_TW/API/types/patches/BinOp.md | 2 ++ doc/zh_TW/API/types/patches/UnaryOp.md | 2 ++ doc/zh_TW/API/types/traits/Add(R,O).md | 2 ++ doc/zh_TW/API/types/traits/Div(R,O).md | 2 ++ doc/zh_TW/API/types/traits/Eq.md | 2 ++ doc/zh_TW/API/types/traits/Into.md | 2 ++ doc/zh_TW/API/types/traits/Iterable.md | 2 ++ doc/zh_TW/API/types/traits/Num.md | 2 ++ doc/zh_TW/API/types/traits/Ord.md | 2 ++ doc/zh_TW/API/types/traits/SafeDiv(R,O).md | 2 ++ doc/zh_TW/API/types/traits/Sample.md | 2 ++ doc/zh_TW/API/types/traits/Seq.md | 2 ++ doc/zh_TW/API/types/traits/Show.md | 2 ++ doc/zh_TW/API/types/traits/Unpack.md | 2 ++ doc/zh_TW/compiler/TODO_hint.md | 2 ++ doc/zh_TW/compiler/TODO_recov_suggest.md | 2 ++ doc/zh_TW/compiler/TODO_warn.md | 2 ++ doc/zh_TW/compiler/abandoned.md | 2 ++ doc/zh_TW/compiler/architecture.md | 2 ++ doc/zh_TW/compiler/errors.md | 2 ++ doc/zh_TW/compiler/hir.md | 2 ++ doc/zh_TW/compiler/index.md | 2 ++ doc/zh_TW/compiler/inference.md | 2 ++ doc/zh_TW/compiler/overview.md | 2 ++ doc/zh_TW/compiler/parsing.md | 2 ++ doc/zh_TW/compiler/refinement_subtyping.md | 2 ++ doc/zh_TW/compiler/trait_method_resolving.md | 2 ++ doc/zh_TW/compiler/transpile.md | 2 ++ doc/zh_TW/compiler/type_var_normalization.md | 2 ++ doc/zh_TW/dev_guide/branches.md | 2 ++ doc/zh_TW/dev_guide/build_features.md | 2 ++ doc/zh_TW/dev_guide/directories.md | 2 ++ doc/zh_TW/dev_guide/doc_guideline.md | 2 ++ doc/zh_TW/dev_guide/env.md | 2 ++ doc/zh_TW/dev_guide/faq_syntax.md | 4 ++-- doc/zh_TW/dev_guide/i18n_messages.md | 2 ++ doc/zh_TW/dev_guide/index.md | 2 ++ doc/zh_TW/dev_guide/rust_code_guideline.md | 2 ++ doc/zh_TW/dev_guide/terms.md | 2 ++ doc/zh_TW/dev_guide/unify_terms.md | 2 ++ doc/zh_TW/faq_general.md | 8 +++++--- doc/zh_TW/faq_technical.md | 1 + doc/zh_TW/improved_points.md | 2 ++ doc/zh_TW/index.md | 2 ++ doc/zh_TW/migration_from_py.md | 2 ++ doc/zh_TW/python/bytecode_instructions.md | 2 ++ doc/zh_TW/python/bytecode_specification.md | 3 ++- doc/zh_TW/python/class_system.md | 2 ++ doc/zh_TW/python/index.md | 2 ++ doc/zh_TW/syntax/00_basic.md | 2 ++ doc/zh_TW/syntax/01_literal.md | 3 ++- doc/zh_TW/syntax/02_name.md | 2 ++ doc/zh_TW/syntax/03_declaration.md | 2 ++ doc/zh_TW/syntax/04_function.md | 2 ++ doc/zh_TW/syntax/05_builtin_funcs.md | 2 ++ doc/zh_TW/syntax/06_operator.md | 2 ++ doc/zh_TW/syntax/07_side_effect.md | 2 ++ doc/zh_TW/syntax/08_procedure.md | 2 ++ doc/zh_TW/syntax/09_builtin_procs.md | 2 ++ doc/zh_TW/syntax/10_array.md | 2 ++ doc/zh_TW/syntax/11_tuple.md | 2 ++ doc/zh_TW/syntax/12_dict.md | 2 ++ doc/zh_TW/syntax/13_record.md | 2 ++ doc/zh_TW/syntax/14_set.md | 2 ++ doc/zh_TW/syntax/15_type.md | 2 ++ doc/zh_TW/syntax/16_iterator.md | 2 ++ doc/zh_TW/syntax/17_mutability.md | 2 ++ doc/zh_TW/syntax/18_ownership.md | 2 ++ doc/zh_TW/syntax/19_visibility.md | 2 ++ doc/zh_TW/syntax/20_naming_rule.md | 2 ++ doc/zh_TW/syntax/21_lambda.md | 3 ++- doc/zh_TW/syntax/22_subroutine.md | 2 ++ doc/zh_TW/syntax/23_closure.md | 2 ++ doc/zh_TW/syntax/24_module.md | 2 ++ doc/zh_TW/syntax/25_object_system.md | 2 ++ doc/zh_TW/syntax/26_pattern_matching.md | 2 ++ doc/zh_TW/syntax/27_comprehension.md | 2 ++ doc/zh_TW/syntax/28_spread_syntax.md | 2 ++ doc/zh_TW/syntax/29_decorator.md | 2 ++ doc/zh_TW/syntax/30_error_handling.md | 2 ++ doc/zh_TW/syntax/31_pipeline.md | 2 ++ doc/zh_TW/syntax/32_integration_with_Python.md | 3 ++- doc/zh_TW/syntax/33_package_system.md | 2 ++ doc/zh_TW/syntax/34_generator.md | 2 ++ doc/zh_TW/syntax/SUMMARY.md | 2 ++ doc/zh_TW/syntax/container_ownership.md | 2 ++ doc/zh_TW/syntax/indexes.md | 2 ++ doc/zh_TW/syntax/quick_tour.md | 2 ++ doc/zh_TW/syntax/type/01_type_system.md | 2 ++ doc/zh_TW/syntax/type/02_basic.md | 2 ++ doc/zh_TW/syntax/type/03_trait.md | 2 ++ doc/zh_TW/syntax/type/04_class.md | 2 ++ doc/zh_TW/syntax/type/05_inheritance.md | 2 ++ doc/zh_TW/syntax/type/06_nst_vs_sst.md | 2 ++ doc/zh_TW/syntax/type/07_patch.md | 2 ++ doc/zh_TW/syntax/type/08_value.md | 2 ++ doc/zh_TW/syntax/type/09_attributive.md | 2 ++ doc/zh_TW/syntax/type/10_interval.md | 2 ++ doc/zh_TW/syntax/type/11_enum.md | 2 ++ doc/zh_TW/syntax/type/12_refinement.md | 2 ++ doc/zh_TW/syntax/type/13_algebraic.md | 3 ++- doc/zh_TW/syntax/type/14_dependent.md | 2 ++ doc/zh_TW/syntax/type/15_quantified.md | 2 ++ doc/zh_TW/syntax/type/16_subtyping.md | 2 ++ doc/zh_TW/syntax/type/17_type_casting.md | 2 ++ doc/zh_TW/syntax/type/18_mut.md | 2 ++ doc/zh_TW/syntax/type/19_bound.md | 2 ++ doc/zh_TW/syntax/type/advanced.md | 3 ++- doc/zh_TW/syntax/type/advanced/GADTs.md | 2 ++ doc/zh_TW/syntax/type/advanced/_rank2type.md | 2 ++ doc/zh_TW/syntax/type/advanced/default_param.md | 2 ++ doc/zh_TW/syntax/type/advanced/erasure.md | 2 ++ doc/zh_TW/syntax/type/advanced/existential.md | 2 ++ doc/zh_TW/syntax/type/advanced/keyword_param.md | 2 ++ doc/zh_TW/syntax/type/advanced/kind.md | 2 ++ doc/zh_TW/syntax/type/advanced/marker_trait.md | 2 ++ doc/zh_TW/syntax/type/advanced/mut_struct.md | 2 ++ doc/zh_TW/syntax/type/advanced/newtype.md | 2 ++ doc/zh_TW/syntax/type/advanced/overloading.md | 3 ++- doc/zh_TW/syntax/type/advanced/phantom.md | 2 ++ doc/zh_TW/syntax/type/advanced/projection.md | 2 ++ doc/zh_TW/syntax/type/advanced/quantified_dependent.md | 2 ++ doc/zh_TW/syntax/type/advanced/shared.md | 2 ++ doc/zh_TW/syntax/type/advanced/special.md | 2 ++ doc/zh_TW/syntax/type/advanced/typeof.md | 2 ++ doc/zh_TW/syntax/type/advanced/variance.md | 2 ++ doc/zh_TW/syntax/type/advanced/widening.md | 2 ++ doc/zh_TW/tips.md | 2 ++ doc/zh_TW/tools/build.md | 2 ++ doc/zh_TW/tools/env.md | 2 ++ doc/zh_TW/tools/fmt.md | 2 ++ doc/zh_TW/tools/index.md | 2 ++ doc/zh_TW/tools/install.md | 2 ++ doc/zh_TW/tools/pack.md | 2 ++ doc/zh_TW/tools/repl.md | 2 ++ doc/zh_TW/tools/test.md | 2 ++ 186 files changed, 374 insertions(+), 12 deletions(-) diff --git a/doc/zh_TW/API/consts.md b/doc/zh_TW/API/consts.md index 735fca38..05440468 100644 --- a/doc/zh_TW/API/consts.md +++ b/doc/zh_TW/API/consts.md @@ -1,5 +1,7 @@ # 內置常量 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/consts.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/consts.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## True ## False diff --git a/doc/zh_TW/API/funcs.md b/doc/zh_TW/API/funcs.md index 691715f6..a66a7555 100644 --- a/doc/zh_TW/API/funcs.md +++ b/doc/zh_TW/API/funcs.md @@ -1,5 +1,7 @@ # 功能 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/funcs.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/funcs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 基本功能 ### if|T; U|(cond: Bool, then: T, else: U) -> T or U diff --git a/doc/zh_TW/API/index.md b/doc/zh_TW/API/index.md index e69de29b..77223195 100644 --- a/doc/zh_TW/API/index.md +++ b/doc/zh_TW/API/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/index.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/API/modules/external/alstruct.md b/doc/zh_TW/API/modules/external/alstruct.md index 94e932f2..ff5b14f4 100644 --- a/doc/zh_TW/API/modules/external/alstruct.md +++ b/doc/zh_TW/API/modules/external/alstruct.md @@ -1,5 +1,7 @@ # 結構 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/external/alstruct.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/external/alstruct.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 模塊為它們提供代表代數結構和補丁的特征 * 成員 diff --git a/doc/zh_TW/API/modules/repl.md b/doc/zh_TW/API/modules/repl.md index 8a1018b3..8f13c939 100644 --- a/doc/zh_TW/API/modules/repl.md +++ b/doc/zh_TW/API/modules/repl.md @@ -1,5 +1,7 @@ # 模塊`repl` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/repl.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/repl.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 提供REPL(Read-Eval-Print-Loop)相關的API。 ## 功能 diff --git a/doc/zh_TW/API/modules/status.md b/doc/zh_TW/API/modules/status.md index ca082199..77ebb0e8 100644 --- a/doc/zh_TW/API/modules/status.md +++ b/doc/zh_TW/API/modules/status.md @@ -1,5 +1,7 @@ # 模塊`status` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/status.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/status.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 定義了一個類型來表示狀態。請根據情況刪除選項來使用它 * ExecResult = {"success", "warning", "failure", "fatal", "unknown"} diff --git a/doc/zh_TW/API/modules/unit.md b/doc/zh_TW/API/modules/unit.md index a4bccd20..6c3e4b95 100644 --- a/doc/zh_TW/API/modules/unit.md +++ b/doc/zh_TW/API/modules/unit.md @@ -1,5 +1,7 @@ # 模塊`unit` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/unit.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unit.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `unit` 模塊是將數值計算中經常使用的單位定義為類型的模塊。 Erg 數值類型包括 `Nat`、`Int`、`Ratio` 等。但是,這些類型沒有關于“數字的含義”的信息,因此可以執行諸如添加米和碼之類的無意義計算。 通過使用 `unit` 模塊,您可以避免錯誤,例如將不同單位的數字傳遞給函數。 diff --git a/doc/zh_TW/API/modules/unsound.md b/doc/zh_TW/API/modules/unsound.md index a5febad2..1a896545 100644 --- a/doc/zh_TW/API/modules/unsound.md +++ b/doc/zh_TW/API/modules/unsound.md @@ -1,5 +1,7 @@ # 模塊 `unsound` +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/modules/unsound.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/modules/unsound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 讓 API 執行在 Erg 的類型系統中無法保證的不健全和不安全的操作。 ## `unsafe!` diff --git a/doc/zh_TW/API/operators.md b/doc/zh_TW/API/operators.md index ce91831c..7ddcbeca 100644 --- a/doc/zh_TW/API/operators.md +++ b/doc/zh_TW/API/operators.md @@ -1,5 +1,7 @@ # 操作員 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/operators.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/operators.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## 中綴運算符 ### `_+_`|R; O; A <: Add(R, O)|(x: A, y: R) -> O diff --git a/doc/zh_TW/API/procs.md b/doc/zh_TW/API/procs.md index 38e3e3a0..c1ffdb32 100644 --- a/doc/zh_TW/API/procs.md +++ b/doc/zh_TW/API/procs.md @@ -1,5 +1,7 @@ # 過程 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/procs.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/procs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## print! ```python diff --git a/doc/zh_TW/API/special.md b/doc/zh_TW/API/special.md index ff4c4157..d67578bc 100644 --- a/doc/zh_TW/API/special.md +++ b/doc/zh_TW/API/special.md @@ -1,5 +1,7 @@ # 特殊形式 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/special.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 特殊形式是不能在 Erg 類型系統中表達的運算符、子程序(等等)。它被`包圍,但實際上無法捕獲。 此外,為方便起見,還出現了“Pattern”、“Body”和“Conv”等類型,但不存在此類類型。它的含義也取決于上下文。 diff --git a/doc/zh_TW/API/types.md b/doc/zh_TW/API/types.md index c8750872..c6ef3225 100644 --- a/doc/zh_TW/API/types.md +++ b/doc/zh_TW/API/types.md @@ -1,5 +1,7 @@ # 內置 Erg 類型列表 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 類型本身的屬性不存儲在 `.__dict__` 中,不能從實例中引用 ## 基本類型 diff --git a/doc/zh_TW/API/types/classes/Array!(T).md b/doc/zh_TW/API/types/classes/Array!(T).md index 3d683634..264c3d17 100644 --- a/doc/zh_TW/API/types/classes/Array!(T).md +++ b/doc/zh_TW/API/types/classes/Array!(T).md @@ -1,3 +1,5 @@ # Array! T +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Array!(T).md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array!(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示可變長度數組的類型。在編譯時長度未知時使用。 有一個語法糖叫做` [t]!`。在`Array! T = ArrayWithMutLength! T, !_`中被定義 \ No newline at end of file diff --git a/doc/zh_TW/API/types/classes/Array(T).md b/doc/zh_TW/API/types/classes/Array(T).md index 54011ea8..f2bfc5f0 100644 --- a/doc/zh_TW/API/types/classes/Array(T).md +++ b/doc/zh_TW/API/types/classes/Array(T).md @@ -1,3 +1,5 @@ # Array T: Type +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Array(T).md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Array(T).md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 由`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 index 6e7eaa7c..671a95fd 100644 --- a/doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md +++ b/doc/zh_TW/API/types/classes/ArrayWithLen(T,N).md @@ -1,5 +1,7 @@ # ArrayWithLen T: Type, N: Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/ArrayWithLen(T,N).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithLen(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `[T; N]`是語法糖。還有一個[`Array` 類型](./Array.md)省略了長度。 ## 方法 diff --git a/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md b/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md index b4704e32..9301585d 100644 --- a/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md +++ b/doc/zh_TW/API/types/classes/ArrayWithMutLength!(T,N).md @@ -1,5 +1,7 @@ # ArrayWithMutLength! T: Type, N: Nat! +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/ArrayWithMutLength!(T,N).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/ArrayWithMutLength!(T,N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 一個可變長度數組,其長度在編譯時已知。還有語法糖`ArrayWithMutLength(T, !N) == [T; !N]` ## 方法 diff --git a/doc/zh_TW/API/types/classes/Class.md b/doc/zh_TW/API/types/classes/Class.md index e69de29b..8cad7741 100644 --- a/doc/zh_TW/API/types/classes/Class.md +++ b/doc/zh_TW/API/types/classes/Class.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Class.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Class.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/API/types/classes/Complex.md b/doc/zh_TW/API/types/classes/Complex.md index c3dd5521..bc783294 100644 --- a/doc/zh_TW/API/types/classes/Complex.md +++ b/doc/zh_TW/API/types/classes/Complex.md @@ -1,5 +1,7 @@ # Complex +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Complex.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Complex.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示復數的類型。在 Erg 中表示數字的類型,例如 Float、Int和Nat,通常派生于Complex ## 父類 diff --git a/doc/zh_TW/API/types/classes/Dict!.md b/doc/zh_TW/API/types/classes/Dict!.md index 1b7ae72c..95950ea7 100644 --- a/doc/zh_TW/API/types/classes/Dict!.md +++ b/doc/zh_TW/API/types/classes/Dict!.md @@ -1,5 +1,7 @@ # Dict! K, V +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Dict!.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Dict!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示字典(哈希Map)的類型。 有一個語法糖叫做`{K: V}` ## 方法 diff --git a/doc/zh_TW/API/types/classes/Either.md b/doc/zh_TW/API/types/classes/Either.md index fd7e11ff..38517463 100644 --- a/doc/zh_TW/API/types/classes/Either.md +++ b/doc/zh_TW/API/types/classes/Either.md @@ -1,5 +1,7 @@ # Either L, R = L or R +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Either.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Either.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示L或R的類型。 您可以將其視為Or類型的二元形式 ## 方法 diff --git a/doc/zh_TW/API/types/classes/Float.md b/doc/zh_TW/API/types/classes/Float.md index 8e64241a..77a3ee9d 100644 --- a/doc/zh_TW/API/types/classes/Float.md +++ b/doc/zh_TW/API/types/classes/Float.md @@ -1,5 +1,7 @@ # Float size +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Float.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Float.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示實數(包含小數的數)的類型。符合IEEE 754的浮點數,在其他語言中一般是float的類型。 Float的大小為8(1byte)~128(16byte)。如果只是Float,則表示`Float64`。 Erg 中的 0.1 實際上屬于 Ratio 類型,而不是 Float 類型。沒有浮點類型字面量,它是由 `(Ratio object)f64` 生成的(例如 (1/2)f64, 15f64)。 f64 對應實數 1 diff --git a/doc/zh_TW/API/types/classes/Function(N).md b/doc/zh_TW/API/types/classes/Function(N).md index 4317a8ea..08d6b7b0 100644 --- a/doc/zh_TW/API/types/classes/Function(N).md +++ b/doc/zh_TW/API/types/classes/Function(N).md @@ -1,5 +1,7 @@ # Function N: Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Function(N).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Function(N).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## Function 1 的方法 * then(self, g: Self) -> Self diff --git a/doc/zh_TW/API/types/classes/Inf.md b/doc/zh_TW/API/types/classes/Inf.md index bbdabfe0..685cf242 100644 --- a/doc/zh_TW/API/types/classes/Inf.md +++ b/doc/zh_TW/API/types/classes/Inf.md @@ -1,5 +1,7 @@ # Inf +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Inf.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Inf.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Inf是一個類,其唯一實例是inf。 inf的主要用途是用于區間類型。 例如,大于等于 2 的整數類型是 `2.. Type ``` diff --git a/doc/zh_TW/API/types/classes/Matrix.md b/doc/zh_TW/API/types/classes/Matrix.md index b653846d..06acac62 100644 --- a/doc/zh_TW/API/types/classes/Matrix.md +++ b/doc/zh_TW/API/types/classes/Matrix.md @@ -1,5 +1,7 @@ # Matrix T: Num, Shape: [M, N] +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Matrix.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Matrix.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示矩陣的類型。 它繼承自 Tensor[M, N] ## 定義 diff --git a/doc/zh_TW/API/types/classes/Module.md b/doc/zh_TW/API/types/classes/Module.md index 547f7253..135a64da 100644 --- a/doc/zh_TW/API/types/classes/Module.md +++ b/doc/zh_TW/API/types/classes/Module.md @@ -1,3 +1,5 @@ # Module +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Module.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Module.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## 方法 diff --git a/doc/zh_TW/API/types/classes/Nat.md b/doc/zh_TW/API/types/classes/Nat.md index e02e9db6..1fe9da24 100644 --- a/doc/zh_TW/API/types/classes/Nat.md +++ b/doc/zh_TW/API/types/classes/Nat.md @@ -1,5 +1,7 @@ # Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Nat.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Nat.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 表示自然數的類型。 用于數組索引和范圍類型 ## 定義 diff --git a/doc/zh_TW/API/types/classes/Neg.md b/doc/zh_TW/API/types/classes/Neg.md index ef25b01d..5317a2bd 100644 --- a/doc/zh_TW/API/types/classes/Neg.md +++ b/doc/zh_TW/API/types/classes/Neg.md @@ -1,5 +1,7 @@ # Neg +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Neg.md%26commit_hash%3D290c43b09f7c3036112a164bed5fd07a1f6a5cda)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Neg.md&commit_hash=290c43b09f7c3036112a164bed5fd07a1f6a5cda) + 表示負整數的類型。 Pos和Neg和{0} == Int 它還具有一些值得注意的屬性,例如不被零除和 Neg * Neg == Pos diff --git a/doc/zh_TW/API/types/classes/Never.md b/doc/zh_TW/API/types/classes/Never.md index c2288573..00dcf7f1 100644 --- a/doc/zh_TW/API/types/classes/Never.md +++ b/doc/zh_TW/API/types/classes/Never.md @@ -1,5 +1,7 @@ # Never +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Never.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Never.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 它是所有類型的子類型。 它是一個`Class`,因為它擁有所有的方法,當然還有 `.new`。但是,它沒有實例,并且Erg會在即將創建的那一刻停止。 還有一種叫做`Panic`的類型沒有實例,但是`Never`用于正常終止或故意無限循環,`Panic`用于異常終止。 diff --git a/doc/zh_TW/API/types/classes/NonZero.md b/doc/zh_TW/API/types/classes/NonZero.md index 2dc71d41..c4b9e526 100644 --- a/doc/zh_TW/API/types/classes/NonZero.md +++ b/doc/zh_TW/API/types/classes/NonZero.md @@ -1,5 +1,7 @@ # NonZero N +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/NonZero.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/NonZero.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示非零數的類。 保證除零的安全性 ```mermaid diff --git a/doc/zh_TW/API/types/classes/Object.md b/doc/zh_TW/API/types/classes/Object.md index 62740f79..ea27c461 100644 --- a/doc/zh_TW/API/types/classes/Object.md +++ b/doc/zh_TW/API/types/classes/Object.md @@ -1,5 +1,7 @@ # Object +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Object.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Object.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 它是所有類型的超類型 ## 方法 diff --git a/doc/zh_TW/API/types/classes/Operator.md b/doc/zh_TW/API/types/classes/Operator.md index 0d40c2d7..363d3bd1 100644 --- a/doc/zh_TW/API/types/classes/Operator.md +++ b/doc/zh_TW/API/types/classes/Operator.md @@ -1,5 +1,7 @@ # Operator [...T], O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Operator.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Operator.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 是運算符的類型 ## 定義 diff --git a/doc/zh_TW/API/types/classes/Option.md b/doc/zh_TW/API/types/classes/Option.md index 979f8d25..dd14db2a 100644 --- a/doc/zh_TW/API/types/classes/Option.md +++ b/doc/zh_TW/API/types/classes/Option.md @@ -1,5 +1,7 @@ # Option T = T or NoneType +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Option.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Option.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 表示“可能失敗”的類型。 ## 方法 diff --git a/doc/zh_TW/API/types/classes/Pos.md b/doc/zh_TW/API/types/classes/Pos.md index 42edd789..02881a92 100644 --- a/doc/zh_TW/API/types/classes/Pos.md +++ b/doc/zh_TW/API/types/classes/Pos.md @@ -1,5 +1,7 @@ # Pos +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Pos.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Pos.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Pos是一種表示正數(大于或等于1的整數)的類型。 由于不包括0,因此具有消除被零除的可能性等優點。 diff --git a/doc/zh_TW/API/types/classes/Ratio.md b/doc/zh_TW/API/types/classes/Ratio.md index 1e98ca7c..a3b9fb05 100644 --- a/doc/zh_TW/API/types/classes/Ratio.md +++ b/doc/zh_TW/API/types/classes/Ratio.md @@ -1,5 +1,7 @@ # Ratio +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Ratio.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Ratio.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示有理數的類型。 它主要用于當您要使用分數時。 實際上,Erg中的/運算符返回 Ratio。1/3等不被評估為 0.33333... 并且被處理為1/3。 此外,0.1 相當于 1/10。 所以`0.1 + 0.2 == 0.3`。 這聽起來很明顯,但在 Python中它是False。 但是,Ratio類型的效率往往比Float類型略低。 在執行速度很重要且不需要精確數值的地方應該使用浮點類型。 然而,正如Rob Pike所說,過早優化是萬惡之源。 在丟棄Ratio類型并使用Float類型之前,請進行真實的性能測試。 業余愛好者無條件偏愛較輕的模具。 diff --git a/doc/zh_TW/API/types/classes/Record.md b/doc/zh_TW/API/types/classes/Record.md index 1e9056a7..74bd0baf 100644 --- a/doc/zh_TW/API/types/classes/Record.md +++ b/doc/zh_TW/API/types/classes/Record.md @@ -1,5 +1,7 @@ # Record +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Record.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Record.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 記錄所屬的類。例如,`{i = 1}` 是`Structural {i = Int}` 類型的元素,并且是`{i = Int}` 類的實例 請注意,其他類的實例是記錄類型的元素,而不是記錄類的實例 diff --git a/doc/zh_TW/API/types/classes/Result.md b/doc/zh_TW/API/types/classes/Result.md index 43656839..0205b31f 100644 --- a/doc/zh_TW/API/types/classes/Result.md +++ b/doc/zh_TW/API/types/classes/Result.md @@ -1,5 +1,7 @@ # Result T, E +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Result.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Result.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python Result T, E <: Error = Either T, E ``` diff --git a/doc/zh_TW/API/types/classes/Str!.md b/doc/zh_TW/API/types/classes/Str!.md index 317d291d..62c50c4d 100644 --- a/doc/zh_TW/API/types/classes/Str!.md +++ b/doc/zh_TW/API/types/classes/Str!.md @@ -1,3 +1,5 @@ # StrWithLen! N: Nat! = Inherit StrWithLen N +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Str!.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str!.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示可變長度字符串的類型 diff --git a/doc/zh_TW/API/types/classes/Str.md b/doc/zh_TW/API/types/classes/Str.md index b384d572..24c3cac3 100644 --- a/doc/zh_TW/API/types/classes/Str.md +++ b/doc/zh_TW/API/types/classes/Str.md @@ -1,5 +1,7 @@ # Str +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Str.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Str.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + (不變長度)表示字符串的類型。 簡單的 `Str` 類型是刪除了字符數的 `StrWithLen N` 類型(`Str = StrWithLen _`) ## 方法 diff --git a/doc/zh_TW/API/types/classes/StrWithLen.md b/doc/zh_TW/API/types/classes/StrWithLen.md index e69de29b..67caca65 100644 --- a/doc/zh_TW/API/types/classes/StrWithLen.md +++ b/doc/zh_TW/API/types/classes/StrWithLen.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/StrWithLen.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/StrWithLen.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/API/types/classes/Subroutine.md b/doc/zh_TW/API/types/classes/Subroutine.md index 60cbb806..5de32879 100644 --- a/doc/zh_TW/API/types/classes/Subroutine.md +++ b/doc/zh_TW/API/types/classes/Subroutine.md @@ -1,5 +1,7 @@ # Subroutine +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Subroutine.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Subroutine.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Func和Proc的基本類型。 ## 方法 diff --git a/doc/zh_TW/API/types/classes/Tensor.md b/doc/zh_TW/API/types/classes/Tensor.md index b9cfd3f8..db3304b9 100644 --- a/doc/zh_TW/API/types/classes/Tensor.md +++ b/doc/zh_TW/API/types/classes/Tensor.md @@ -1,5 +1,7 @@ # Tensor Shape: [Nat; N] +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Tensor.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tensor.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 用于有效操作多維數組的類。 它還定義了諸如多維數組上的乘法之類的操作 Matrix、Vector 等都繼承自該類型 diff --git a/doc/zh_TW/API/types/classes/TransCell(T).md b/doc/zh_TW/API/types/classes/TransCell(T).md index 38349392..cc95238c 100644 --- a/doc/zh_TW/API/types/classes/TransCell(T).md +++ b/doc/zh_TW/API/types/classes/TransCell(T).md @@ -1,5 +1,7 @@ # TransCell! T: Type! +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/TransCell(T).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/TransCell(T).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 它是一個單元格,其內容可以針對每個模具進行更改。 由于它是T類型的子類型,因此它也表現為T類型 當它在初始化時輸入T時很有用,并且在某個點之后總是輸入U diff --git a/doc/zh_TW/API/types/classes/Tuple.md b/doc/zh_TW/API/types/classes/Tuple.md index 9277cf54..fb0d5163 100644 --- a/doc/zh_TW/API/types/classes/Tuple.md +++ b/doc/zh_TW/API/types/classes/Tuple.md @@ -1,5 +1,7 @@ # Tuple T: ...Type +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Tuple.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Tuple.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 包含多種類型對象的集合 ## 方法 diff --git a/doc/zh_TW/API/types/classes/Type.md b/doc/zh_TW/API/types/classes/Type.md index e69de29b..dae4a5c2 100644 --- a/doc/zh_TW/API/types/classes/Type.md +++ b/doc/zh_TW/API/types/classes/Type.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Type.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/API/types/classes/Vector.md b/doc/zh_TW/API/types/classes/Vector.md index d5351a61..50e9b3d6 100644 --- a/doc/zh_TW/API/types/classes/Vector.md +++ b/doc/zh_TW/API/types/classes/Vector.md @@ -1,3 +1,5 @@ # Vector T: Num, N: Nat +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/classes/Vector.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/classes/Vector.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 表示向量的類型。與同名的Rust和C++類型不同,這種類型只處理數字。 \ No newline at end of file diff --git a/doc/zh_TW/API/types/patches/BinOp.md b/doc/zh_TW/API/types/patches/BinOp.md index 083de661..5fa493e7 100644 --- a/doc/zh_TW/API/types/patches/BinOp.md +++ b/doc/zh_TW/API/types/patches/BinOp.md @@ -1,5 +1,7 @@ # BinOp L, R, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/patches/BinOp.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/BinOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 二元運算符的類型 ## 修補程序 diff --git a/doc/zh_TW/API/types/patches/UnaryOp.md b/doc/zh_TW/API/types/patches/UnaryOp.md index b4ec87f0..5ac2ae86 100644 --- a/doc/zh_TW/API/types/patches/UnaryOp.md +++ b/doc/zh_TW/API/types/patches/UnaryOp.md @@ -1,5 +1,7 @@ # UnaryOp T, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/patches/UnaryOp.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/patches/UnaryOp.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 一元運算符的類型 ## 定義 diff --git a/doc/zh_TW/API/types/traits/Add(R,O).md b/doc/zh_TW/API/types/traits/Add(R,O).md index 54182f26..726071f0 100644 --- a/doc/zh_TW/API/types/traits/Add(R,O).md +++ b/doc/zh_TW/API/types/traits/Add(R,O).md @@ -1,5 +1,7 @@ # Add R +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Add(R,O).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Add(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python Add R = Trait { .AddO = Type diff --git a/doc/zh_TW/API/types/traits/Div(R,O).md b/doc/zh_TW/API/types/traits/Div(R,O).md index 085960f6..664dc954 100644 --- a/doc/zh_TW/API/types/traits/Div(R,O).md +++ b/doc/zh_TW/API/types/traits/Div(R,O).md @@ -1,5 +1,7 @@ # Div R, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Div(R,O).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Div(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 如果除以零沒有錯誤,請使用“SafeDiv” ```python diff --git a/doc/zh_TW/API/types/traits/Eq.md b/doc/zh_TW/API/types/traits/Eq.md index e69de29b..6aed2ae0 100644 --- a/doc/zh_TW/API/types/traits/Eq.md +++ b/doc/zh_TW/API/types/traits/Eq.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Eq.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Eq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/API/types/traits/Into.md b/doc/zh_TW/API/types/traits/Into.md index e9224512..83093df7 100644 --- a/doc/zh_TW/API/types/traits/Into.md +++ b/doc/zh_TW/API/types/traits/Into.md @@ -1,5 +1,7 @@ # Into T +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Into.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Into.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 一種類型,表明它可以被類型轉換為類型T。 即使Self和T之間沒有繼承關系,也是在關系可以相互轉換的時候定義的。 與繼承不同,沒有隱式轉換。您必須始終調用 `.into` 方法。 diff --git a/doc/zh_TW/API/types/traits/Iterable.md b/doc/zh_TW/API/types/traits/Iterable.md index e69de29b..ba458258 100644 --- a/doc/zh_TW/API/types/traits/Iterable.md +++ b/doc/zh_TW/API/types/traits/Iterable.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Iterable.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Iterable.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/API/types/traits/Num.md b/doc/zh_TW/API/types/traits/Num.md index 92315877..ca55178b 100644 --- a/doc/zh_TW/API/types/traits/Num.md +++ b/doc/zh_TW/API/types/traits/Num.md @@ -1,5 +1,7 @@ # Num +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Num.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Num.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 定義初始化 ```python diff --git a/doc/zh_TW/API/types/traits/Ord.md b/doc/zh_TW/API/types/traits/Ord.md index e69de29b..3ef5f04a 100644 --- a/doc/zh_TW/API/types/traits/Ord.md +++ b/doc/zh_TW/API/types/traits/Ord.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Ord.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Ord.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/API/types/traits/SafeDiv(R,O).md b/doc/zh_TW/API/types/traits/SafeDiv(R,O).md index 998faf89..03595643 100644 --- a/doc/zh_TW/API/types/traits/SafeDiv(R,O).md +++ b/doc/zh_TW/API/types/traits/SafeDiv(R,O).md @@ -1,5 +1,7 @@ # SafeDiv R, O +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/SafeDiv(R,O).md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/SafeDiv(R,O).md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python SafeDiv R, O = Subsume Div, { @Override diff --git a/doc/zh_TW/API/types/traits/Sample.md b/doc/zh_TW/API/types/traits/Sample.md index 7e57d1eb..5a601d84 100644 --- a/doc/zh_TW/API/types/traits/Sample.md +++ b/doc/zh_TW/API/types/traits/Sample.md @@ -1,5 +1,7 @@ # Sample +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Sample.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Sample.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 具有“隨機”選擇實例的`sample`和`sample!`方法的特征。`sample`方法總是返回相同的實例,而`sample!`方法返回一個隨機實例,該實例隨調用而變化 請注意,這是一個假設您想要一個適當的實例進行測試等的特征,并且它不一定是隨機的。 如果您想要隨機抽樣,請使用“隨機”模塊。 diff --git a/doc/zh_TW/API/types/traits/Seq.md b/doc/zh_TW/API/types/traits/Seq.md index e69de29b..007f7134 100644 --- a/doc/zh_TW/API/types/traits/Seq.md +++ b/doc/zh_TW/API/types/traits/Seq.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Seq.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Seq.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/API/types/traits/Show.md b/doc/zh_TW/API/types/traits/Show.md index e69de29b..30763e02 100644 --- a/doc/zh_TW/API/types/traits/Show.md +++ b/doc/zh_TW/API/types/traits/Show.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Show.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Show.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/API/types/traits/Unpack.md b/doc/zh_TW/API/types/traits/Unpack.md index e11011b1..37364850 100644 --- a/doc/zh_TW/API/types/traits/Unpack.md +++ b/doc/zh_TW/API/types/traits/Unpack.md @@ -1,5 +1,7 @@ # Unpack +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/API/types/traits/Unpack.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/API/types/traits/Unpack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 標記性狀。實現時,元素可以像記錄一樣通過模式匹配來分解 ```python diff --git a/doc/zh_TW/compiler/TODO_hint.md b/doc/zh_TW/compiler/TODO_hint.md index 2cf268ad..69f19f36 100644 --- a/doc/zh_TW/compiler/TODO_hint.md +++ b/doc/zh_TW/compiler/TODO_hint.md @@ -1,4 +1,6 @@ # 提示(未實現) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/TODO_hint.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_hint.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * `x 未定義`(x 已被`Del` 刪除)=> `提示:在第 X 行刪除` *補丁方法重復:“提示:指定補丁(如`T.foo(1)`)或使用`Del`刪除任何`.foo`” \ No newline at end of file diff --git a/doc/zh_TW/compiler/TODO_recov_suggest.md b/doc/zh_TW/compiler/TODO_recov_suggest.md index 07c6fc60..f21dd8bf 100644 --- a/doc/zh_TW/compiler/TODO_recov_suggest.md +++ b/doc/zh_TW/compiler/TODO_recov_suggest.md @@ -1,5 +1,7 @@ # 錯誤恢復建議(尚未實現) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/TODO_recov_suggest.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_recov_suggest.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * `1 or 2`, `1 and 2` => `{1, 2}`? * `U = Inherit T` => 非類類型不能被繼承,或者`U = Class T`? * `Int and Str` => 不允許多重繼承,或者`Int or Str`? diff --git a/doc/zh_TW/compiler/TODO_warn.md b/doc/zh_TW/compiler/TODO_warn.md index a84e53c0..1fff72b1 100644 --- a/doc/zh_TW/compiler/TODO_warn.md +++ b/doc/zh_TW/compiler/TODO_warn.md @@ -1,5 +1,7 @@ # 警告(尚未實現) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/TODO_warn.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/TODO_warn.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * `t = {(record type)}` => `T = {(record type)}`?(只有定義為常量的類型才能用于類型說明) * `{I: Int | ...}!` => `{I: Int! | ...}` * for/while 塊中的`return x`(`x != ()`) => `f::return`(外部塊)? \ No newline at end of file diff --git a/doc/zh_TW/compiler/abandoned.md b/doc/zh_TW/compiler/abandoned.md index d566fdf1..1ce62cce 100644 --- a/doc/zh_TW/compiler/abandoned.md +++ b/doc/zh_TW/compiler/abandoned.md @@ -1,5 +1,7 @@ # 廢棄/拒絕的語言規范 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/abandoned.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/abandoned.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## 重載(臨時多態性) 被放棄了,因為它可以用參數+子類型多態來代替,并且與Python的語義不兼容。 有關詳細信息,請參閱 [overload](../syntax/type/overloading.md) 文章。 diff --git a/doc/zh_TW/compiler/architecture.md b/doc/zh_TW/compiler/architecture.md index 9fddde10..30a908aa 100644 --- a/doc/zh_TW/compiler/architecture.md +++ b/doc/zh_TW/compiler/architecture.md @@ -1,5 +1,7 @@ # `ergc` 的架構 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/architecture.md%26commit_hash%3Da711efa99b325ba1012f6897e7b0e2bdb947d8a1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/architecture.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1) + ## 1. 掃描 Erg 腳本 (.er) 并生成 `TokenStream` (parser/lex.rs) * parser/lexer/Lexer 生成`TokenStream`(這是一個Token的迭代器,TokenStream可以通過lexer.collect()生成) diff --git a/doc/zh_TW/compiler/errors.md b/doc/zh_TW/compiler/errors.md index b0f043d9..1436942c 100644 --- a/doc/zh_TW/compiler/errors.md +++ b/doc/zh_TW/compiler/errors.md @@ -1,5 +1,7 @@ # Erg Compiler Errors +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/errors.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/errors.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## AssignError 嘗試重寫不可變變量時發生 diff --git a/doc/zh_TW/compiler/hir.md b/doc/zh_TW/compiler/hir.md index 48040873..addefb11 100644 --- a/doc/zh_TW/compiler/hir.md +++ b/doc/zh_TW/compiler/hir.md @@ -1,5 +1,7 @@ # 高級中間表示(HIR, High-level Intermediate Representation) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/hir.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/hir.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + HIR 是 Erg 編譯器從 AST 生成的結構 此結構包含源代碼中每個表達式的完整類型信息,并且在語法上已脫糖 AST與源代碼一一對應(純文本),但是HIR去掉了不必要的代碼信息,添加了省略的類型信息,所以HIR可以轉換為源代碼很難恢復 diff --git a/doc/zh_TW/compiler/index.md b/doc/zh_TW/compiler/index.md index e69de29b..33522b77 100644 --- a/doc/zh_TW/compiler/index.md +++ b/doc/zh_TW/compiler/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/index.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/compiler/inference.md b/doc/zh_TW/compiler/inference.md index 979baebf..719e1707 100644 --- a/doc/zh_TW/compiler/inference.md +++ b/doc/zh_TW/compiler/inference.md @@ -1,5 +1,7 @@ # 類型推斷算法 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/inference.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/inference.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + > __Warning__:此部分正在編輯中,可能包含一些錯誤 顯示了下面使用的符號 diff --git a/doc/zh_TW/compiler/overview.md b/doc/zh_TW/compiler/overview.md index 8d7d86c8..73061113 100644 --- a/doc/zh_TW/compiler/overview.md +++ b/doc/zh_TW/compiler/overview.md @@ -1,5 +1,7 @@ # `erg` 概覽 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/overview.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/overview.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 我們將介紹每一層的功能以及特別重要的功能和方法。 ## 1. 詞法分析 diff --git a/doc/zh_TW/compiler/parsing.md b/doc/zh_TW/compiler/parsing.md index 501e2bf8..3d6d4600 100644 --- a/doc/zh_TW/compiler/parsing.md +++ b/doc/zh_TW/compiler/parsing.md @@ -1,5 +1,7 @@ # 解析 Erg 語言 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/parsing.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/parsing.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 空格的處理 Erg語法的一個特點是它對空間敏感。 diff --git a/doc/zh_TW/compiler/refinement_subtyping.md b/doc/zh_TW/compiler/refinement_subtyping.md index aa0cf9ba..5fb30dae 100644 --- a/doc/zh_TW/compiler/refinement_subtyping.md +++ b/doc/zh_TW/compiler/refinement_subtyping.md @@ -1,5 +1,7 @@ # 篩子類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/refinement_subtyping.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/refinement_subtyping.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python {I: Int | I >= 0} {S: StrWithLen N | N >= 1} diff --git a/doc/zh_TW/compiler/trait_method_resolving.md b/doc/zh_TW/compiler/trait_method_resolving.md index 1f3a6f88..68fa15ec 100644 --- a/doc/zh_TW/compiler/trait_method_resolving.md +++ b/doc/zh_TW/compiler/trait_method_resolving.md @@ -1,5 +1,7 @@ # 解決補丁方法 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/trait_method_resolving.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/trait_method_resolving.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `Nat` 是零個或多個`Int`,`Int` 的子類型。 `Nat` 在 Python 類層次結構中不存在。 我想知道 Erg 是如何解決這個補丁方法的? diff --git a/doc/zh_TW/compiler/transpile.md b/doc/zh_TW/compiler/transpile.md index fa0afc6b..5cffba68 100644 --- a/doc/zh_TW/compiler/transpile.md +++ b/doc/zh_TW/compiler/transpile.md @@ -1,5 +1,7 @@ # Erg 代碼如何轉譯成 Python 代碼? +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/transpile.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/transpile.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 準確地說,Erg 代碼被轉譯為 Python 字節碼。 但是,由于 Python 字節碼幾乎可以重構為 Python 代碼,因此這里以等效的 Python 代碼為例。 順便說一句,這里展示的示例是低優化級別。 diff --git a/doc/zh_TW/compiler/type_var_normalization.md b/doc/zh_TW/compiler/type_var_normalization.md index cbf621e6..fa6e704e 100644 --- a/doc/zh_TW/compiler/type_var_normalization.md +++ b/doc/zh_TW/compiler/type_var_normalization.md @@ -1,5 +1,7 @@ # 歸一化 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/type_var_normalization.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/type_var_normalization.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + * Erg 的類型參數規范化基于 SymPy 的簡化函數。 例如,當您定義 `concat: |T, M, N|([T; M], [T; N] -> [T; M+N])` 時,您可以匹配類型變量和參數而無需實例化它們.必須作出判斷。 diff --git a/doc/zh_TW/dev_guide/branches.md b/doc/zh_TW/dev_guide/branches.md index 599d39a7..0d39107e 100644 --- a/doc/zh_TW/dev_guide/branches.md +++ b/doc/zh_TW/dev_guide/branches.md @@ -1,5 +1,7 @@ # 分支機構命名和運營策略 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/branches.md%26commit_hash%3Da711efa99b325ba1012f6897e7b0e2bdb947d8a1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/branches.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1) + ## main * 主要開發分支 diff --git a/doc/zh_TW/dev_guide/build_features.md b/doc/zh_TW/dev_guide/build_features.md index 1aea65b9..49731e40 100644 --- a/doc/zh_TW/dev_guide/build_features.md +++ b/doc/zh_TW/dev_guide/build_features.md @@ -1,5 +1,7 @@ # `erg` 構建功能 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/build_features.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/build_features.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 調試 進入調試模式。結果,Erg 內部的行為順序顯示在日志中。 diff --git a/doc/zh_TW/dev_guide/directories.md b/doc/zh_TW/dev_guide/directories.md index 542ae411..fa2cd397 100644 --- a/doc/zh_TW/dev_guide/directories.md +++ b/doc/zh_TW/dev_guide/directories.md @@ -1,5 +1,7 @@ # Erg存儲表結構 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/directories.md%26commit_hash%3Da711efa99b325ba1012f6897e7b0e2bdb947d8a1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/directories.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1) + ```console └─┬ assets:圖片等 ├─ CODE_OF_CONDUCT:行為準則 diff --git a/doc/zh_TW/dev_guide/doc_guideline.md b/doc/zh_TW/dev_guide/doc_guideline.md index 9c2e5241..30f29259 100644 --- a/doc/zh_TW/dev_guide/doc_guideline.md +++ b/doc/zh_TW/dev_guide/doc_guideline.md @@ -1,5 +1,7 @@ # 格式 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/doc_guideline.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/doc_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 任何不符合以下規則的文件都將得到更正。 * 以某種語氣寫代碼注釋或內部文檔。 diff --git a/doc/zh_TW/dev_guide/env.md b/doc/zh_TW/dev_guide/env.md index 99679c35..43511997 100644 --- a/doc/zh_TW/dev_guide/env.md +++ b/doc/zh_TW/dev_guide/env.md @@ -1,5 +1,7 @@ # 開發環境 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/env.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## 你需要安裝什么 * Rust(與 rustup 一起安裝) diff --git a/doc/zh_TW/dev_guide/faq_syntax.md b/doc/zh_TW/dev_guide/faq_syntax.md index af1cb5f9..68d760b8 100644 --- a/doc/zh_TW/dev_guide/faq_syntax.md +++ b/doc/zh_TW/dev_guide/faq_syntax.md @@ -1,5 +1,7 @@ # Erg design's "Why" and Answers +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/faq_syntax.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/faq_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 當我們有所有權系統時,為什么要與 GC 共存? 因為 Erg 推出所有權系統的動機并不是為了 Rust 那樣的“不依賴 GC 的內存管理”。最初,由于 Erg 是一種語言,目前使用 Python VM,因此最終仍使用 GC。Erg 引入產權系統的目標是“可變狀態的局部化”。在 Erg 中,可變對象具有所有權概念。這是根據共享可變狀態容易成為 bug 的溫床,甚至是類型安全性的侵犯(詳見)來判斷的。 @@ -48,7 +50,6 @@ assert S.i == Int 在 Erg 中,運算符使你可以在不太注意錯誤的情況下編寫。 - ```python read_file!() = f = open!("foo.txt")? # 如果失敗則立即返回錯誤,所以 f 是文件類型 @@ -77,7 +78,6 @@ Python 的庫中有一些類設計為繼承,如果完全取消繼承,這些 默認情況下,指向結構托盤會使類型指定變得復雜,并且可能會混合程序員的非預期行為。 - ```python # 如果 T 是結構特征的子類型... # f: |T <: Structural Trait {.`_+_` = Self.(Self) -> Self; .`_-_` = Self.(Self) -> Self}| (T, T) -> T diff --git a/doc/zh_TW/dev_guide/i18n_messages.md b/doc/zh_TW/dev_guide/i18n_messages.md index e663e5bd..f02827b9 100644 --- a/doc/zh_TW/dev_guide/i18n_messages.md +++ b/doc/zh_TW/dev_guide/i18n_messages.md @@ -1,5 +1,7 @@ # 多語言錯誤信息 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/i18n_messages.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/i18n_messages.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Erg 正在推動消息(開始、選項、文檔、提示、警告、錯誤消息等)的多語言化。如果你不熟悉 Rust 或 Erg,也可以參與此項目。請務必配合。 以下是多語種方法的說明。 diff --git a/doc/zh_TW/dev_guide/index.md b/doc/zh_TW/dev_guide/index.md index e69de29b..0e41be9e 100644 --- a/doc/zh_TW/dev_guide/index.md +++ b/doc/zh_TW/dev_guide/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/index.md%26commit_hash%3D7d43acdf0e2b71528b038b9a8e70be6c93831f96)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/index.md&commit_hash=7d43acdf0e2b71528b038b9a8e70be6c93831f96) + diff --git a/doc/zh_TW/dev_guide/rust_code_guideline.md b/doc/zh_TW/dev_guide/rust_code_guideline.md index d76615d9..93811890 100644 --- a/doc/zh_TW/dev_guide/rust_code_guideline.md +++ b/doc/zh_TW/dev_guide/rust_code_guideline.md @@ -1,5 +1,7 @@ # Rust 代碼指南 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/rust_code_guideline.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/rust_code_guideline.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + ## 本地規則 * 使用 `log!` 進行調試輸出(使用 `println!` 等進行輸出處理,這也是發布所必需的)。 diff --git a/doc/zh_TW/dev_guide/terms.md b/doc/zh_TW/dev_guide/terms.md index 4d970d66..e9a57f8e 100644 --- a/doc/zh_TW/dev_guide/terms.md +++ b/doc/zh_TW/dev_guide/terms.md @@ -1,5 +1,7 @@ # 詞匯表 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/terms.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 象征 ### ! diff --git a/doc/zh_TW/dev_guide/unify_terms.md b/doc/zh_TW/dev_guide/unify_terms.md index 49a40529..d1d804dc 100644 --- a/doc/zh_TW/dev_guide/unify_terms.md +++ b/doc/zh_TW/dev_guide/unify_terms.md @@ -1,5 +1,7 @@ # 術語統一 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/dev_guide/unify_terms.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/unify_terms.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 可訪問性,可見性 使用可見性。 diff --git a/doc/zh_TW/faq_general.md b/doc/zh_TW/faq_general.md index 9c8181f1..b687922b 100644 --- a/doc/zh_TW/faq_general.md +++ b/doc/zh_TW/faq_general.md @@ -1,8 +1,10 @@ # Erg常見問題 -此常見問題解答適用于一般 Erg 初學者。 -對于個別(常見)技術問題,請參閱 [此處](./faq_technical.md) 了解個別(常見)技術問題,以及 -[這里](./dev_guide/faq_syntax.md) 了解更多信息。 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/faq_general.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_general.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + +This FAQ is intended for the general Erg beginner. +For individual (common) technical issues, please refer to [here](./faq_technical.md) for individual (common) technical issues, and +[Here](./dev_guide/faq_syntax.md) for more information. ## Erg 是 Python 兼容語言是什么意思? diff --git a/doc/zh_TW/faq_technical.md b/doc/zh_TW/faq_technical.md index 8fcf254d..61fcc532 100644 --- a/doc/zh_TW/faq_technical.md +++ b/doc/zh_TW/faq_technical.md @@ -1,5 +1,6 @@ # 技術常見問題 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/faq_technical.md%26commit_hash%3Dc120700585fdb1d655255c8e2817bb13cc8d369e)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/faq_technical.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e) 本節回答有關使用 Erg 語言的技術問題。換句話說,它包含以 What 或 Which 開頭的問題,以及可以用 Yes/No 回答的問題。 diff --git a/doc/zh_TW/improved_points.md b/doc/zh_TW/improved_points.md index 8d99907b..3c8383d5 100644 --- a/doc/zh_TW/improved_points.md +++ b/doc/zh_TW/improved_points.md @@ -1,5 +1,7 @@ # Python 的改進 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/improved_points.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/improved_points.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## 執行靜態分析(靜態類型檢查、變量和屬性檢查) 靜態類型檢查的好處現在怎么強調都不為過,但是檢查變量和屬性的存在也是相當重要的一部分。 diff --git a/doc/zh_TW/index.md b/doc/zh_TW/index.md index 821be649..f97500ce 100644 --- a/doc/zh_TW/index.md +++ b/doc/zh_TW/index.md @@ -1,5 +1,7 @@ # 索引 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/index.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/index.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + ## [API/](./API/index.md) 本節介紹 Erg 的內置或標準庫提供的子程序、類型、常量等的規范。 diff --git a/doc/zh_TW/migration_from_py.md b/doc/zh_TW/migration_from_py.md index 80a5c66b..74abaa03 100644 --- a/doc/zh_TW/migration_from_py.md +++ b/doc/zh_TW/migration_from_py.md @@ -1,5 +1,7 @@ # 從 Python 遷移到 Erg 的提示 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/migration_from_py.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/migration_from_py.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## 我想將字符串轉換為 int 等。 使用 `Str` 類的 `parse` 方法。 它返回一個 `Result` 類型。 diff --git a/doc/zh_TW/python/bytecode_instructions.md b/doc/zh_TW/python/bytecode_instructions.md index 47e3ae8f..35715f37 100644 --- a/doc/zh_TW/python/bytecode_instructions.md +++ b/doc/zh_TW/python/bytecode_instructions.md @@ -1,5 +1,7 @@ # Python 字節碼指令 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/bytecode_instructions.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_instructions.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + Python 字節碼變量操作命令通過 名稱索引(名稱索引)訪問。 這是為了在 Python 中實現動態變量訪問(可以使用 eval 等作為字符串訪問)。 一條指令為 2 個字節,指令和參數以 little endian 形式存儲。 不帶參數的指令也使用 2 個字節(參數部分為 0)。 diff --git a/doc/zh_TW/python/bytecode_specification.md b/doc/zh_TW/python/bytecode_specification.md index d0a56f9c..8606d9c6 100644 --- a/doc/zh_TW/python/bytecode_specification.md +++ b/doc/zh_TW/python/bytecode_specification.md @@ -1,5 +1,7 @@ # Python bytecode specification +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/bytecode_specification.md%26commit_hash%3D9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/bytecode_specification.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4) + ## Format * 0~3 byte(u32): magic number (see common/bytecode.rs for details) @@ -70,7 +72,6 @@ * 1~4 byte: length of string * 5~ byte: payload - # Python 字節碼規范 ## 格式 diff --git a/doc/zh_TW/python/class_system.md b/doc/zh_TW/python/class_system.md index 8453038a..63606bbd 100644 --- a/doc/zh_TW/python/class_system.md +++ b/doc/zh_TW/python/class_system.md @@ -1,5 +1,7 @@ # Python 類系統(與 Erg 比較) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/class_system.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/class_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 方法 方法可以被前向引用,但這不是一種特殊的技術。 diff --git a/doc/zh_TW/python/index.md b/doc/zh_TW/python/index.md index e69de29b..2168ad9d 100644 --- a/doc/zh_TW/python/index.md +++ b/doc/zh_TW/python/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/python/index.md%26commit_hash%3D9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/python/index.md&commit_hash=9f6a4a43fcf7e4f58cabe6e5a7546820fd9f5ff4) + diff --git a/doc/zh_TW/syntax/00_basic.md b/doc/zh_TW/syntax/00_basic.md index 21a26fd2..03aa32e7 100644 --- a/doc/zh_TW/syntax/00_basic.md +++ b/doc/zh_TW/syntax/00_basic.md @@ -1,5 +1,7 @@ # 基本 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/00_basic.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/00_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + > __Warning__:本文檔不完整。 它未經校對(樣式、正確鏈接、誤譯等)。 此外,Erg 的語法可能在版本 0.* 期間發生破壞性更改,并且文檔可能沒有相應更新。 請事先了解這一點。 > 如果您在本文檔中發現任何錯誤,請報告至 [此處的表單](https://forms.gle/HtLYRfYzWCAaeTGb6) 或 [GitHub repo](https://github.com/mtshiba/TheErgBook/issues/new )。 我們將不勝感激您的建議。 diff --git a/doc/zh_TW/syntax/01_literal.md b/doc/zh_TW/syntax/01_literal.md index 44b9610e..25bc6f1b 100644 --- a/doc/zh_TW/syntax/01_literal.md +++ b/doc/zh_TW/syntax/01_literal.md @@ -1,5 +1,7 @@ # 字面量 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/01_literal.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/01_literal.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 基本字面量 ### 整數字面量 @@ -135,7 +137,6 @@ assert 0.0f32 == 0.0f64 一個“復雜”對象只是一個虛數單位對象`im`的算術組合 - ## *-less 乘法 在 Erg 中,您可以省略 `*` 來表示乘法,只要解釋上沒有混淆即可。 但是,運算符的組合強度設置為強于 `*`。 diff --git a/doc/zh_TW/syntax/02_name.md b/doc/zh_TW/syntax/02_name.md index 336458f2..5feed6d3 100644 --- a/doc/zh_TW/syntax/02_name.md +++ b/doc/zh_TW/syntax/02_name.md @@ -1,5 +1,7 @@ # 多變的 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/02_name.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 變量是一種代數; Erg 中的代數 - 如果沒有混淆,有時簡稱為變量 - 指的是命名對象并使它們可從代碼的其他地方引用的功能。 變量定義如下。 diff --git a/doc/zh_TW/syntax/03_declaration.md b/doc/zh_TW/syntax/03_declaration.md index 7de06ec0..b984c65a 100644 --- a/doc/zh_TW/syntax/03_declaration.md +++ b/doc/zh_TW/syntax/03_declaration.md @@ -1,5 +1,7 @@ # 宣言(Declaration) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/03_declaration.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/03_declaration.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 聲明是用于指定要使用的變量類型的語法。 可以在代碼中的任何地方進行聲明,但單獨的聲明并不引用變量。 它們必須被初始化。 分配后,可以檢查聲明以確保類型與分配它的對象兼容。 diff --git a/doc/zh_TW/syntax/04_function.md b/doc/zh_TW/syntax/04_function.md index 02e4706e..25389c36 100644 --- a/doc/zh_TW/syntax/04_function.md +++ b/doc/zh_TW/syntax/04_function.md @@ -1,5 +1,7 @@ # 功能 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/04_function.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/04_function.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 函數是一個塊,它接受一個“參數”,對其進行處理,并將其作為“返回值”返回。 定義如下。 ```python diff --git a/doc/zh_TW/syntax/05_builtin_funcs.md b/doc/zh_TW/syntax/05_builtin_funcs.md index 294ab71e..db2204b0 100644 --- a/doc/zh_TW/syntax/05_builtin_funcs.md +++ b/doc/zh_TW/syntax/05_builtin_funcs.md @@ -1,5 +1,7 @@ # 內置函數 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/05_builtin_funcs.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/05_builtin_funcs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 如果 `if` 是一個根據條件改變處理的函數。 diff --git a/doc/zh_TW/syntax/06_operator.md b/doc/zh_TW/syntax/06_operator.md index ee6f32cf..84e7d71f 100644 --- a/doc/zh_TW/syntax/06_operator.md +++ b/doc/zh_TW/syntax/06_operator.md @@ -1,5 +1,7 @@ # 運算符 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/06_operator.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/06_operator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 運算符是表示操作的符號。 操作數是運算符(左)右側的東西。 運算符是一種函數,因此它們本身就是可以綁定到變量的一流對象。 綁定時,需要用```括起來。 diff --git a/doc/zh_TW/syntax/07_side_effect.md b/doc/zh_TW/syntax/07_side_effect.md index d1dada58..35722f81 100644 --- a/doc/zh_TW/syntax/07_side_effect.md +++ b/doc/zh_TW/syntax/07_side_effect.md @@ -1,5 +1,7 @@ # 副作用和程序 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/07_side_effect.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/07_side_effect.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 我們一直忽略了解釋“!”的含義,但現在它的含義終于要揭曉了。 這個 `!` 表示這個對象是一個帶有“副作用”的“過程”。 過程是具有副作用的函數。 ```python diff --git a/doc/zh_TW/syntax/08_procedure.md b/doc/zh_TW/syntax/08_procedure.md index a381e88f..d0f5408b 100644 --- a/doc/zh_TW/syntax/08_procedure.md +++ b/doc/zh_TW/syntax/08_procedure.md @@ -1,5 +1,7 @@ # 程序 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/08_procedure.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/08_procedure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 處理可變對象時需要過程,但將可變對象作為參數并不一定使其成為過程。 這是一個函數接受一個可變對象(不是過程)。 diff --git a/doc/zh_TW/syntax/09_builtin_procs.md b/doc/zh_TW/syntax/09_builtin_procs.md index 25559d98..67130a36 100644 --- a/doc/zh_TW/syntax/09_builtin_procs.md +++ b/doc/zh_TW/syntax/09_builtin_procs.md @@ -1,5 +1,7 @@ # 內置程序 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/09_builtin_procs.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/09_builtin_procs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## id! 返回對象的唯一標識號。 diff --git a/doc/zh_TW/syntax/10_array.md b/doc/zh_TW/syntax/10_array.md index 892ad80a..cad38bb1 100644 --- a/doc/zh_TW/syntax/10_array.md +++ b/doc/zh_TW/syntax/10_array.md @@ -1,5 +1,7 @@ # Array +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/10_array.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/10_array.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 數組是最基本的__collection(聚合)__。 集合是一個可以在其中包含多個對象的對象。 diff --git a/doc/zh_TW/syntax/11_tuple.md b/doc/zh_TW/syntax/11_tuple.md index 7c62c2f4..0b35dc97 100644 --- a/doc/zh_TW/syntax/11_tuple.md +++ b/doc/zh_TW/syntax/11_tuple.md @@ -1,5 +1,7 @@ # 元組 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/11_tuple.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/11_tuple.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 元組類似于數組,但可以保存不同類型的對象。 這樣的集合稱為不等集合。 相比之下,同構集合包括數組、集合等。 diff --git a/doc/zh_TW/syntax/12_dict.md b/doc/zh_TW/syntax/12_dict.md index 235071d9..a8ff4003 100644 --- a/doc/zh_TW/syntax/12_dict.md +++ b/doc/zh_TW/syntax/12_dict.md @@ -1,5 +1,7 @@ # 字典 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/12_dict.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/12_dict.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Dict 是鍵/值對的集合。 ```python diff --git a/doc/zh_TW/syntax/13_record.md b/doc/zh_TW/syntax/13_record.md index 19e4252d..0c713680 100644 --- a/doc/zh_TW/syntax/13_record.md +++ b/doc/zh_TW/syntax/13_record.md @@ -1,5 +1,7 @@ # 記錄(Record) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/13_record.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/13_record.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 記錄是一個集合,它結合了通過鍵訪問的 Dict 和在編譯時檢查其訪問的元組的屬性。 如果您了解 JavaScript,請將其視為一種(更增強的)對象字面量表示法。 diff --git a/doc/zh_TW/syntax/14_set.md b/doc/zh_TW/syntax/14_set.md index 304b5cc0..0591a777 100644 --- a/doc/zh_TW/syntax/14_set.md +++ b/doc/zh_TW/syntax/14_set.md @@ -1,5 +1,7 @@ # Set +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/14_set.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/14_set.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 一個Set代表一個集合,它在結構上是一個重復的無序數組。 ```python diff --git a/doc/zh_TW/syntax/15_type.md b/doc/zh_TW/syntax/15_type.md index 9d39a89d..c547d3bd 100644 --- a/doc/zh_TW/syntax/15_type.md +++ b/doc/zh_TW/syntax/15_type.md @@ -1,5 +1,7 @@ # 類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/15_type.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/15_type.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 類型是 Erg 中一個非常重要的特性,所以我們有一個 [dedicated section](./type/01_type_system.md)。 請看那里。

diff --git a/doc/zh_TW/syntax/16_iterator.md b/doc/zh_TW/syntax/16_iterator.md index be023422..bbd0a511 100644 --- a/doc/zh_TW/syntax/16_iterator.md +++ b/doc/zh_TW/syntax/16_iterator.md @@ -1,5 +1,7 @@ # 迭代器 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/16_iterator.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/16_iterator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 迭代器是用于檢索容器元素的對象。 ```python diff --git a/doc/zh_TW/syntax/17_mutability.md b/doc/zh_TW/syntax/17_mutability.md index 41988a44..339cb1cf 100644 --- a/doc/zh_TW/syntax/17_mutability.md +++ b/doc/zh_TW/syntax/17_mutability.md @@ -1,5 +1,7 @@ # 可變性 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/17_mutability.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/17_mutability.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 正如我們已經看到的,所有 Erg 變量都是不可變的。 但是,Erg 對象具有可變性的概念。 以下面的代碼為例。 diff --git a/doc/zh_TW/syntax/18_ownership.md b/doc/zh_TW/syntax/18_ownership.md index 8bbdf86a..39656902 100644 --- a/doc/zh_TW/syntax/18_ownership.md +++ b/doc/zh_TW/syntax/18_ownership.md @@ -1,5 +1,7 @@ #所有權制度 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/18_ownership.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/18_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 由于 Erg 是一種使用 Python 作為宿主語言的語言,因此內存管理的方法取決于 Python 的實現。 但語義上 Erg 的內存管理與 Python 的不同。 一個顯著的區別在于所有權制度和禁止循環引用。 diff --git a/doc/zh_TW/syntax/19_visibility.md b/doc/zh_TW/syntax/19_visibility.md index 2bec3898..e6d5090b 100644 --- a/doc/zh_TW/syntax/19_visibility.md +++ b/doc/zh_TW/syntax/19_visibility.md @@ -1,5 +1,7 @@ # 可見性 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/19_visibility.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/19_visibility.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg 變量具有 __visibility__ 的概念。 到目前為止,我們看到的所有變量都稱為 __private variables__。 這是一個外部不可見的變量。 例如,`foo` 模塊中定義的私有變量不能被另一個模塊引用。 diff --git a/doc/zh_TW/syntax/20_naming_rule.md b/doc/zh_TW/syntax/20_naming_rule.md index 7c946340..640c1262 100644 --- a/doc/zh_TW/syntax/20_naming_rule.md +++ b/doc/zh_TW/syntax/20_naming_rule.md @@ -1,5 +1,7 @@ # 命名約定 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/20_naming_rule.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/20_naming_rule.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 如果要將變量用作常量表達式,請確保它以大寫字母開頭。 兩個或多個字母可能是小寫的。 ```python diff --git a/doc/zh_TW/syntax/21_lambda.md b/doc/zh_TW/syntax/21_lambda.md index bb8e00dc..6b240482 100644 --- a/doc/zh_TW/syntax/21_lambda.md +++ b/doc/zh_TW/syntax/21_lambda.md @@ -1,5 +1,7 @@ # 匿名函數 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/21_lambda.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/21_lambda.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 匿名函數是一種無需命名即可動態創建函數對象的語法。 ```python @@ -59,7 +61,6 @@ now = if! True: 您還可以鍵入和模式匹配。 正因為如此,`match` 函數大多是借助匿名函數的力量來實現的。 作為 `match` 函數的參數給出的匿名函數從頂部開始按順序嘗試。 因此,您應該在頂部描述特殊情況,在底部描述更一般的情況。 如果你弄錯了順序,編譯器會發出警告(如果可能的話) - ```python n = (Complex or Ratio or Int).sample!() i = matchn: diff --git a/doc/zh_TW/syntax/22_subroutine.md b/doc/zh_TW/syntax/22_subroutine.md index da449e98..29f7b790 100644 --- a/doc/zh_TW/syntax/22_subroutine.md +++ b/doc/zh_TW/syntax/22_subroutine.md @@ -1,5 +1,7 @@ # 子程序簽名 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/22_subroutine.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/22_subroutine.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 函數 ```python diff --git a/doc/zh_TW/syntax/23_closure.md b/doc/zh_TW/syntax/23_closure.md index 67e9b0c1..f8586ffa 100644 --- a/doc/zh_TW/syntax/23_closure.md +++ b/doc/zh_TW/syntax/23_closure.md @@ -1,5 +1,7 @@ # 關閉 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/23_closure.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/23_closure.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg 子例程有一個稱為“閉包”的功能,可以捕獲外部變量。 ```python diff --git a/doc/zh_TW/syntax/24_module.md b/doc/zh_TW/syntax/24_module.md index eff76cdd..8d18f7bc 100644 --- a/doc/zh_TW/syntax/24_module.md +++ b/doc/zh_TW/syntax/24_module.md @@ -1,5 +1,7 @@ # module +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/24_module.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/24_module.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg allows you to think of the file itself as a single record. This is called a module. ```python: foo.er diff --git a/doc/zh_TW/syntax/25_object_system.md b/doc/zh_TW/syntax/25_object_system.md index ce089cc3..317f702b 100644 --- a/doc/zh_TW/syntax/25_object_system.md +++ b/doc/zh_TW/syntax/25_object_system.md @@ -1,5 +1,7 @@ # 目的 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/25_object_system.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/25_object_system.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 可以分配給變量的所有數據。 `Object` 類的屬性如下。 * `.__repr__`:返回對象的(非豐富)字符串表示 diff --git a/doc/zh_TW/syntax/26_pattern_matching.md b/doc/zh_TW/syntax/26_pattern_matching.md index 9c4cdbd5..411650fd 100644 --- a/doc/zh_TW/syntax/26_pattern_matching.md +++ b/doc/zh_TW/syntax/26_pattern_matching.md @@ -1,5 +1,7 @@ # 模式匹配,可反駁 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/26_pattern_matching.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/26_pattern_matching.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ## Erg 中可用的模式 ### 變量模式 diff --git a/doc/zh_TW/syntax/27_comprehension.md b/doc/zh_TW/syntax/27_comprehension.md index 1aae05b8..9ba5b6fc 100644 --- a/doc/zh_TW/syntax/27_comprehension.md +++ b/doc/zh_TW/syntax/27_comprehension.md @@ -1,5 +1,7 @@ # Comprehension +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/27_comprehension.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/27_comprehension.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Array 和 `[expr | (name <- iterable)+ (predicate)*]`, set 和 `{expr | (name <- iterable)+ (predicate)*}`, 你可以創建一個字典 `{key: value | (name <- iterable)+ (predicate)*}`. diff --git a/doc/zh_TW/syntax/28_spread_syntax.md b/doc/zh_TW/syntax/28_spread_syntax.md index ab3c96fd..60630b96 100644 --- a/doc/zh_TW/syntax/28_spread_syntax.md +++ b/doc/zh_TW/syntax/28_spread_syntax.md @@ -1,5 +1,7 @@ # 傳播賦值 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/28_spread_syntax.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/28_spread_syntax.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 在分解賦值中,將 `...` 放在變量前面會將所有剩余元素展開到該變量中。 這稱為擴展賦值。 ```python diff --git a/doc/zh_TW/syntax/29_decorator.md b/doc/zh_TW/syntax/29_decorator.md index c419cd4a..1b19af3a 100644 --- a/doc/zh_TW/syntax/29_decorator.md +++ b/doc/zh_TW/syntax/29_decorator.md @@ -1,5 +1,7 @@ # 裝飾器(修飾符) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/29_decorator.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/29_decorator.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 裝飾器用于向類型或函數添加或演示特定狀態或行為。 裝飾器的語法如下。 diff --git a/doc/zh_TW/syntax/30_error_handling.md b/doc/zh_TW/syntax/30_error_handling.md index 3c549435..c58e6dd7 100644 --- a/doc/zh_TW/syntax/30_error_handling.md +++ b/doc/zh_TW/syntax/30_error_handling.md @@ -1,5 +1,7 @@ # 錯誤處理系統 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/30_error_handling.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/30_error_handling.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 主要使用Result類型。 在 Erg 中,如果您丟棄 Error 類型的對象(頂層不支持),則會發生錯誤。 diff --git a/doc/zh_TW/syntax/31_pipeline.md b/doc/zh_TW/syntax/31_pipeline.md index b8de0cf1..4d1f736e 100644 --- a/doc/zh_TW/syntax/31_pipeline.md +++ b/doc/zh_TW/syntax/31_pipeline.md @@ -1,5 +1,7 @@ # 管道運算符 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/31_pipeline.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/31_pipeline.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 管道運算符的使用方式如下: ```python diff --git a/doc/zh_TW/syntax/32_integration_with_Python.md b/doc/zh_TW/syntax/32_integration_with_Python.md index 6f2c4d56..3649c674 100644 --- a/doc/zh_TW/syntax/32_integration_with_Python.md +++ b/doc/zh_TW/syntax/32_integration_with_Python.md @@ -1,5 +1,7 @@ # 與 Python 集成 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/32_integration_with_Python.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/32_integration_with_Python.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 導出到 Python 編譯 Erg 腳本時,會生成一個 .pyc 文件,可以簡單地將其作為 Python 模塊導入。 @@ -65,7 +67,6 @@ assert foo.bar(1) in Int 這通過在運行時執行類型檢查來確保類型安全。 ``declare`` 函數大致如下工作 - ```python declare|S: Subroutine| sub!: S, T = # 實際上,=> 可以強制轉換為沒有塊副作用的函數 diff --git a/doc/zh_TW/syntax/33_package_system.md b/doc/zh_TW/syntax/33_package_system.md index db6a9367..7946a2c8 100644 --- a/doc/zh_TW/syntax/33_package_system.md +++ b/doc/zh_TW/syntax/33_package_system.md @@ -1,5 +1,7 @@ # 打包系統 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/33_package_system.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/33_package_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Erg包大致可以分為app包,即應用程序,以及lib包,即庫。 應用包的入口點是`src/app.er`。 `app.er` 中定義的`main` 函數被執行。 lib 包的入口點是`src/lib.er`。導入包相當于導入 `lib.er`。 diff --git a/doc/zh_TW/syntax/34_generator.md b/doc/zh_TW/syntax/34_generator.md index 34c3fceb..e6c55854 100644 --- a/doc/zh_TW/syntax/34_generator.md +++ b/doc/zh_TW/syntax/34_generator.md @@ -1,5 +1,7 @@ # 生成器 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/34_generator.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/34_generator.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 生成器是在塊中使用 `yield!` 過程的特殊過程。 ```python diff --git a/doc/zh_TW/syntax/SUMMARY.md b/doc/zh_TW/syntax/SUMMARY.md index 55ad61ad..1fa1e2c4 100644 --- a/doc/zh_TW/syntax/SUMMARY.md +++ b/doc/zh_TW/syntax/SUMMARY.md @@ -1,5 +1,7 @@ # 概括 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/SUMMARY.md%26commit_hash%3D2ce482b1c8407332b3b74f4c3e5596f373f9a657)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/SUMMARY.md&commit_hash=2ce482b1c8407332b3b74f4c3e5596f373f9a657) + - [基礎](./00_basic.md) - [文字](./01_literal.md) - [名稱](02_name.md) diff --git a/doc/zh_TW/syntax/container_ownership.md b/doc/zh_TW/syntax/container_ownership.md index 283eb5d3..31392695 100644 --- a/doc/zh_TW/syntax/container_ownership.md +++ b/doc/zh_TW/syntax/container_ownership.md @@ -1,5 +1,7 @@ # 下標(索引訪問) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/container_ownership.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/container_ownership.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `[]` 不同于普通的方法。 ```python diff --git a/doc/zh_TW/syntax/indexes.md b/doc/zh_TW/syntax/indexes.md index 1ff34807..25fc980e 100644 --- a/doc/zh_TW/syntax/indexes.md +++ b/doc/zh_TW/syntax/indexes.md @@ -1,5 +1,7 @@ # 指數 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/indexes.md%26commit_hash%3D438bcb89ea692f219b30f3a3ba107888b23eae98)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/indexes.md&commit_hash=438bcb89ea692f219b30f3a3ba107888b23eae98) + 有關不在此索引中的 API,請參閱 [此處](../API/index.md)。 有關術語,請參見 [此處](../dev_guide/terms.md)。 diff --git a/doc/zh_TW/syntax/quick_tour.md b/doc/zh_TW/syntax/quick_tour.md index e91bef22..c293b37b 100644 --- a/doc/zh_TW/syntax/quick_tour.md +++ b/doc/zh_TW/syntax/quick_tour.md @@ -1,5 +1,7 @@ # 快速瀏覽 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/quick_tour.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/quick_tour.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `syntax` 下面的文檔是為了讓編程初學者也能理解而編寫的。 對于已經掌握 Python、Rust、Haskell 等語言的人來說,可能有點啰嗦。 diff --git a/doc/zh_TW/syntax/type/01_type_system.md b/doc/zh_TW/syntax/type/01_type_system.md index 9dabb102..9dcd57e3 100644 --- a/doc/zh_TW/syntax/type/01_type_system.md +++ b/doc/zh_TW/syntax/type/01_type_system.md @@ -1,5 +1,7 @@ # Erg 的類型系統 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/01_type_system.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/01_type_system.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 下面簡單介紹一下 Erg 的類型系統。 詳細信息在其他部分進行說明。 ## 如何定義 diff --git a/doc/zh_TW/syntax/type/02_basic.md b/doc/zh_TW/syntax/type/02_basic.md index addbf3a7..583a8615 100644 --- a/doc/zh_TW/syntax/type/02_basic.md +++ b/doc/zh_TW/syntax/type/02_basic.md @@ -1,5 +1,7 @@ # 類型的基本語法 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/02_basic.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/02_basic.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 類型規范 在 Erg 中,可以在 `:` 之后指定變量的類型,如下所示。這可以與作業同時完成。 diff --git a/doc/zh_TW/syntax/type/03_trait.md b/doc/zh_TW/syntax/type/03_trait.md index 4059f479..df7f4dee 100644 --- a/doc/zh_TW/syntax/type/03_trait.md +++ b/doc/zh_TW/syntax/type/03_trait.md @@ -1,5 +1,7 @@ # 特質 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/03_trait.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/03_trait.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Trait 是一種名義類型,它將類型屬性要求添加到記錄類型。 它類似于 Python 中的抽象基類 (ABC),但區別在于能夠執行代數運算。 diff --git a/doc/zh_TW/syntax/type/04_class.md b/doc/zh_TW/syntax/type/04_class.md index 02c17321..80185bb1 100644 --- a/doc/zh_TW/syntax/type/04_class.md +++ b/doc/zh_TW/syntax/type/04_class.md @@ -1,5 +1,7 @@ # Class +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/04_class.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/04_class.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Erg 中的類大致是一種可以創建自己的元素(實例)的類型。 這是一個簡單類的示例。 diff --git a/doc/zh_TW/syntax/type/05_inheritance.md b/doc/zh_TW/syntax/type/05_inheritance.md index 19ee1501..ab3dc4a0 100644 --- a/doc/zh_TW/syntax/type/05_inheritance.md +++ b/doc/zh_TW/syntax/type/05_inheritance.md @@ -1,5 +1,7 @@ # 繼承 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/05_inheritance.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/05_inheritance.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 繼承允許您定義一個新類,為現有類添加功能或專業化。 繼承類似于包含在特征中。 繼承的類成為原始類的子類型。 diff --git a/doc/zh_TW/syntax/type/06_nst_vs_sst.md b/doc/zh_TW/syntax/type/06_nst_vs_sst.md index 1464f8a1..8e0ecac5 100644 --- a/doc/zh_TW/syntax/type/06_nst_vs_sst.md +++ b/doc/zh_TW/syntax/type/06_nst_vs_sst.md @@ -1,5 +1,7 @@ # 名義子類型與結構子類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/06_nst_vs_sst.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/06_nst_vs_sst.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ```python Months = 0..12 diff --git a/doc/zh_TW/syntax/type/07_patch.md b/doc/zh_TW/syntax/type/07_patch.md index da3f02ef..0cc37292 100644 --- a/doc/zh_TW/syntax/type/07_patch.md +++ b/doc/zh_TW/syntax/type/07_patch.md @@ -1,5 +1,7 @@ # 修補 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/07_patch.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/07_patch.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Erg 不允許修改現有類型和類。 這意味著,不可能在類中定義額外的方法,也不能執行特化(一種語言特性,單態化多態聲明的類型并定義專用方法,如在 C++ 中)。 但是,在許多情況下,您可能希望向現有類型或類添加功能,并且有一個稱為“修補”的功能允許您執行此操作。 diff --git a/doc/zh_TW/syntax/type/08_value.md b/doc/zh_TW/syntax/type/08_value.md index c4b8986b..0989d081 100644 --- a/doc/zh_TW/syntax/type/08_value.md +++ b/doc/zh_TW/syntax/type/08_value.md @@ -1,5 +1,7 @@ # 值類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/08_value.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/08_value.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 值類型是可以在編譯時評估的 Erg 內置類型,具體來說: ```python diff --git a/doc/zh_TW/syntax/type/09_attributive.md b/doc/zh_TW/syntax/type/09_attributive.md index ec51fae5..726e38ea 100644 --- a/doc/zh_TW/syntax/type/09_attributive.md +++ b/doc/zh_TW/syntax/type/09_attributive.md @@ -1,5 +1,7 @@ # 屬性類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/09_attributive.md%26commit_hash%3Deccd113c1512076c367fb87ea73406f91ff83ba7)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/09_attributive.md&commit_hash=eccd113c1512076c367fb87ea73406f91ff83ba7) + 屬性類型是包含 Record 和 Dataclass、Patch、Module 等的類型。 屬于屬性類型的類型不是值類型。 diff --git a/doc/zh_TW/syntax/type/10_interval.md b/doc/zh_TW/syntax/type/10_interval.md index b699706c..b64290d9 100644 --- a/doc/zh_TW/syntax/type/10_interval.md +++ b/doc/zh_TW/syntax/type/10_interval.md @@ -1,5 +1,7 @@ # 間隔類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/10_interval.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/10_interval.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + `Range` 對象最基本的用途是作為迭代器。 ```python diff --git a/doc/zh_TW/syntax/type/11_enum.md b/doc/zh_TW/syntax/type/11_enum.md index d5d6c2a2..0ece296c 100644 --- a/doc/zh_TW/syntax/type/11_enum.md +++ b/doc/zh_TW/syntax/type/11_enum.md @@ -1,5 +1,7 @@ # 枚舉類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/11_enum.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/11_enum.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Set 生成的枚舉類型。 枚舉類型可以與類型規范一起使用,但可以通過將它們分類為類或定義修復程序來定義進一步的方法。 diff --git a/doc/zh_TW/syntax/type/12_refinement.md b/doc/zh_TW/syntax/type/12_refinement.md index 410e926b..1bb55f49 100644 --- a/doc/zh_TW/syntax/type/12_refinement.md +++ b/doc/zh_TW/syntax/type/12_refinement.md @@ -1,5 +1,7 @@ # 細化類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/12_refinement.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/12_refinement.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 細化類型是受謂詞表達式約束的類型。 枚舉類型和區間類型是細化類型的語法糖。 細化類型的標準形式是`{Elem: Type | (預)*}`。 這意味著該類型是其元素為滿足 `Pred` 的 `Elem` 的類型。 diff --git a/doc/zh_TW/syntax/type/13_algebraic.md b/doc/zh_TW/syntax/type/13_algebraic.md index 67d6bf97..45739a7c 100644 --- a/doc/zh_TW/syntax/type/13_algebraic.md +++ b/doc/zh_TW/syntax/type/13_algebraic.md @@ -1,5 +1,7 @@ # 代數類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/13_algebraic.md%26commit_hash%3Dc120700585fdb1d655255c8e2817bb13cc8d369e)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/13_algebraic.md&commit_hash=c120700585fdb1d655255c8e2817bb13cc8d369e) + 代數類型是通過將類型視為代數來操作類型而生成的類型。 它們處理的操作包括Union、Intersection、Diff、Complement等。 普通類只能進行Union,其他操作會導致類型錯誤。 @@ -9,7 +11,6 @@ 聯合類型可以為類型提供多種可能性。 顧名思義,它們是由“或”運算符生成的。 一個典型的 Union 是 `Option` 類型。 `Option` 類型是 `T 或 NoneType` 補丁類型,主要表示可能失敗的值。 - ```python IntOrStr = Int or Str assert dict.get("some key") in (Int or NoneType) diff --git a/doc/zh_TW/syntax/type/14_dependent.md b/doc/zh_TW/syntax/type/14_dependent.md index 133b5bf4..b2f226a4 100644 --- a/doc/zh_TW/syntax/type/14_dependent.md +++ b/doc/zh_TW/syntax/type/14_dependent.md @@ -1,5 +1,7 @@ # 依賴類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/14_dependent.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/14_dependent.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 依賴類型是一個特性,可以說是 Erg 的最大特性。 依賴類型是將值作為參數的類型。 普通的多態類型只能將類型作為參數,但依賴類型放寬了這個限制。 diff --git a/doc/zh_TW/syntax/type/15_quantified.md b/doc/zh_TW/syntax/type/15_quantified.md index a80193f5..b0703989 100644 --- a/doc/zh_TW/syntax/type/15_quantified.md +++ b/doc/zh_TW/syntax/type/15_quantified.md @@ -1,5 +1,7 @@ # 類型變量,量化類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/15_quantified.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/15_quantified.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 類型變量是用于例如指定子程序參數類型的變量,它的類型是任意的(不是單態的)。 首先,作為引入類型變量的動機,考慮 `id` 函數,它按原樣返回輸入。 diff --git a/doc/zh_TW/syntax/type/16_subtyping.md b/doc/zh_TW/syntax/type/16_subtyping.md index ebb4a6ae..fe8e4127 100644 --- a/doc/zh_TW/syntax/type/16_subtyping.md +++ b/doc/zh_TW/syntax/type/16_subtyping.md @@ -1,5 +1,7 @@ # 子類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/16_subtyping.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/16_subtyping.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 在 Erg 中,可以使用比較運算符 `<`、`>` 確定類包含。 ```python diff --git a/doc/zh_TW/syntax/type/17_type_casting.md b/doc/zh_TW/syntax/type/17_type_casting.md index 010719ea..fcf0ff37 100644 --- a/doc/zh_TW/syntax/type/17_type_casting.md +++ b/doc/zh_TW/syntax/type/17_type_casting.md @@ -1,5 +1,7 @@ # 投擲 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/17_type_casting.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/17_type_casting.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 向上轉型 因為 Python 是一種使用鴨子類型的語言,所以沒有強制轉換的概念。沒有必要向上轉型,本質上也沒有向下轉型。 diff --git a/doc/zh_TW/syntax/type/18_mut.md b/doc/zh_TW/syntax/type/18_mut.md index 3bed2c2f..d0d24c7c 100644 --- a/doc/zh_TW/syntax/type/18_mut.md +++ b/doc/zh_TW/syntax/type/18_mut.md @@ -1,5 +1,7 @@ # 可變類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/18_mut.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/18_mut.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + > __Warning__:本節中的信息是舊的并且包含一些錯誤。 默認情況下,Erg 中的所有類型都是不可變的,即它們的內部狀態無法更新。 diff --git a/doc/zh_TW/syntax/type/19_bound.md b/doc/zh_TW/syntax/type/19_bound.md index 54a09032..adf24228 100644 --- a/doc/zh_TW/syntax/type/19_bound.md +++ b/doc/zh_TW/syntax/type/19_bound.md @@ -1,5 +1,7 @@ # 類型綁定 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/19_bound.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/19_bound.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 類型邊界為類型規范添加條件。 實現這一點的函數是守衛(守衛子句)。 此功能可用于函數簽名、匿名函數簽名以及篩選類型。 守衛寫在返回類型之后。 diff --git a/doc/zh_TW/syntax/type/advanced.md b/doc/zh_TW/syntax/type/advanced.md index d4abf310..18a43be3 100644 --- a/doc/zh_TW/syntax/type/advanced.md +++ b/doc/zh_TW/syntax/type/advanced.md @@ -1 +1,2 @@ -下面,我們將討論更高級的類型系統。 初學者不必閱讀所有部分。 \ No newline at end of file +下面,我們將討論更高級的類型系統。 初學者不必閱讀所有部分。[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/syntax/type/advanced/GADTs.md b/doc/zh_TW/syntax/type/advanced/GADTs.md index 4bb7763a..d8887fb4 100644 --- a/doc/zh_TW/syntax/type/advanced/GADTs.md +++ b/doc/zh_TW/syntax/type/advanced/GADTs.md @@ -1,5 +1,7 @@ # 廣義代數數據類型 (GADT) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/GADTs.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/GADTs.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg 可以通過對 Or 類型進行分類來創建廣義代數數據類型 (GADT)。 ```python diff --git a/doc/zh_TW/syntax/type/advanced/_rank2type.md b/doc/zh_TW/syntax/type/advanced/_rank2type.md index f6ab52ee..f506bb75 100644 --- a/doc/zh_TW/syntax/type/advanced/_rank2type.md +++ b/doc/zh_TW/syntax/type/advanced/_rank2type.md @@ -1,5 +1,7 @@ # rank-2 多態性 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/_rank2type.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/_rank2type.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + > __Warning__:本文檔已過時,一般包含錯誤。 Erg 允許您定義接受各種類型的函數,例如 `id|T|(x: T): T = x`,即多相關。 diff --git a/doc/zh_TW/syntax/type/advanced/default_param.md b/doc/zh_TW/syntax/type/advanced/default_param.md index 7348b947..8b2e2e63 100644 --- a/doc/zh_TW/syntax/type/advanced/default_param.md +++ b/doc/zh_TW/syntax/type/advanced/default_param.md @@ -1,5 +1,7 @@ # 帶默認參數的函數類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/default_param.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/default_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 首先,讓我們看一個使用默認參數的示例。 ```python diff --git a/doc/zh_TW/syntax/type/advanced/erasure.md b/doc/zh_TW/syntax/type/advanced/erasure.md index 7dbf7ed3..7a4a74c5 100644 --- a/doc/zh_TW/syntax/type/advanced/erasure.md +++ b/doc/zh_TW/syntax/type/advanced/erasure.md @@ -1,5 +1,7 @@ # 類型擦除 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/erasure.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/erasure.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 類型擦除是將類型參數設置為 `_` 并故意丟棄其信息的過程。類型擦除是許多多態語言的特性,但在 Erg 的語法上下文中,將其稱為類型參數擦除更為準確。 類型擦除的最常見示例是 `[T, _]`。數組在編譯時并不總是知道它們的長度。例如,引用命令行參數的 `sys.argv` 的類型為 `[Str, _]`。由于 Erg 的編譯器無法知道命令行參數的長度,因此必須放棄有關其長度的信息。 diff --git a/doc/zh_TW/syntax/type/advanced/existential.md b/doc/zh_TW/syntax/type/advanced/existential.md index e5900b93..b26f02ab 100644 --- a/doc/zh_TW/syntax/type/advanced/existential.md +++ b/doc/zh_TW/syntax/type/advanced/existential.md @@ -1,5 +1,7 @@ # 存在類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/existential.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/existential.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 如果存在對應于?的for-all類型,那么很自然地假設存在對應于?的存在類型。 存在類型并不難。 你已經知道存在類型,只是沒有意識到它本身。 diff --git a/doc/zh_TW/syntax/type/advanced/keyword_param.md b/doc/zh_TW/syntax/type/advanced/keyword_param.md index 313c3903..0fe2254a 100644 --- a/doc/zh_TW/syntax/type/advanced/keyword_param.md +++ b/doc/zh_TW/syntax/type/advanced/keyword_param.md @@ -1,5 +1,7 @@ # 帶有關鍵字參數的函數類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/keyword_param.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/keyword_param.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + ```python h(f) = f(y: 1, x: 2) h: |T: type|((y: Int, x: Int) -> T) -> T diff --git a/doc/zh_TW/syntax/type/advanced/kind.md b/doc/zh_TW/syntax/type/advanced/kind.md index 2cb42a9e..c8c151c2 100644 --- a/doc/zh_TW/syntax/type/advanced/kind.md +++ b/doc/zh_TW/syntax/type/advanced/kind.md @@ -1,5 +1,7 @@ # Kind +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/kind.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/kind.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 一切都在 Erg 中輸入。類型本身也不例外。 __kind__ 表示“類型的類型”。例如,`Int` 屬于 `Type`,就像 `1` 屬于 `Int`。 `Type` 是最簡單的一種,__atomic kind__。在類型論符號中,`Type` 對應于 `*`。 在Kind的概念中,實際上重要的是一種或多種Kind(多項式Kind)。單項類型,例如`Option`,屬于它。一元Kind表示為 `Type -> Type` [1](#1)。諸如 `Array` 或 `Option` 之類的 __container__ 特別是一種以類型作為參數的多項式類型。 diff --git a/doc/zh_TW/syntax/type/advanced/marker_trait.md b/doc/zh_TW/syntax/type/advanced/marker_trait.md index 733173bf..88f13c49 100644 --- a/doc/zh_TW/syntax/type/advanced/marker_trait.md +++ b/doc/zh_TW/syntax/type/advanced/marker_trait.md @@ -1,5 +1,7 @@ # 標記特征 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/marker_trait.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/marker_trait.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 標記特征是沒有必需屬性的特征。 也就是說,您可以在不實現任何方法的情況下實現 Impl。 沒有 required 屬性似乎沒有意義,但由于注冊了它屬于 trait 的信息,因此可以使用 patch 方法或由編譯器進行特殊處理。 diff --git a/doc/zh_TW/syntax/type/advanced/mut_struct.md b/doc/zh_TW/syntax/type/advanced/mut_struct.md index 83ff0c82..ea383304 100644 --- a/doc/zh_TW/syntax/type/advanced/mut_struct.md +++ b/doc/zh_TW/syntax/type/advanced/mut_struct.md @@ -1,5 +1,7 @@ # 可變結構類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/mut_struct.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/mut_struct.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + `T!` 類型被描述為可以被任何 `T` 類型對象替換的盒子類型。 ```python diff --git a/doc/zh_TW/syntax/type/advanced/newtype.md b/doc/zh_TW/syntax/type/advanced/newtype.md index fde9b08d..2b2435d5 100644 --- a/doc/zh_TW/syntax/type/advanced/newtype.md +++ b/doc/zh_TW/syntax/type/advanced/newtype.md @@ -1,5 +1,7 @@ # 新類型模式 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/newtype.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/newtype.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 這是 Rust 中常用的 newtype 模式的 Erg 版本。 Erg 允許定義類型別名如下,但它們只引用相同的類型。 diff --git a/doc/zh_TW/syntax/type/advanced/overloading.md b/doc/zh_TW/syntax/type/advanced/overloading.md index 0cbe405c..10a7c651 100644 --- a/doc/zh_TW/syntax/type/advanced/overloading.md +++ b/doc/zh_TW/syntax/type/advanced/overloading.md @@ -1,5 +1,7 @@ # 重載 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/overloading.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/overloading.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Erg 不支持 __ad hoc 多態性__。 也就是說,函數和種類(重載)的多重定義是不可能的。 但是,您可以通過使用特征和補丁的組合來重現重載行為。 您可以使用特征而不是特征類,但隨后將涵蓋所有實現 `.add1` 的類型。 @@ -47,7 +49,6 @@ Erg 的立場是,您不能定義行為完全不同的函數,例如根據參 首先,重載函數分布在它們的定義中。 這使得在發生錯誤時很難報告錯誤的原因。 此外,導入子程序可能會改變已定義子程序的行為。 - ```python {id; ...} = import "foo" ... diff --git a/doc/zh_TW/syntax/type/advanced/phantom.md b/doc/zh_TW/syntax/type/advanced/phantom.md index 52fbf2ef..f83b8d02 100644 --- a/doc/zh_TW/syntax/type/advanced/phantom.md +++ b/doc/zh_TW/syntax/type/advanced/phantom.md @@ -1,5 +1,7 @@ # 幻影(phantom)類 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/phantom.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/phantom.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 幻像類型是標記特征,其存在僅用于向編譯器提供注釋。 作為幻像類型的一種用法,讓我們看一下列表的結構。 diff --git a/doc/zh_TW/syntax/type/advanced/projection.md b/doc/zh_TW/syntax/type/advanced/projection.md index 6d295db2..d8661882 100644 --- a/doc/zh_TW/syntax/type/advanced/projection.md +++ b/doc/zh_TW/syntax/type/advanced/projection.md @@ -1,5 +1,7 @@ # 投影類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/projection.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/projection.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 投影類型表示如下代碼中的“Self.AddO”等類型。 ```python diff --git a/doc/zh_TW/syntax/type/advanced/quantified_dependent.md b/doc/zh_TW/syntax/type/advanced/quantified_dependent.md index e9f70a41..aecbe76e 100644 --- a/doc/zh_TW/syntax/type/advanced/quantified_dependent.md +++ b/doc/zh_TW/syntax/type/advanced/quantified_dependent.md @@ -1,5 +1,7 @@ # 量化依賴類型 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/quantified_dependent.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/quantified_dependent.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + Erg 有量化和依賴類型。 那么很自然地,就可以創建一個將兩者結合起來的類型。 那是量化的依賴類型。 ```python diff --git a/doc/zh_TW/syntax/type/advanced/shared.md b/doc/zh_TW/syntax/type/advanced/shared.md index 8de3d6cd..7be09ecc 100644 --- a/doc/zh_TW/syntax/type/advanced/shared.md +++ b/doc/zh_TW/syntax/type/advanced/shared.md @@ -1,5 +1,7 @@ # 共享參考 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/shared.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/shared.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + 共享引用是必須小心處理的語言特性之一。 例如,在 TypeScript 中,以下代碼將通過類型檢查。 diff --git a/doc/zh_TW/syntax/type/advanced/special.md b/doc/zh_TW/syntax/type/advanced/special.md index 43a60d8c..a79890f1 100644 --- a/doc/zh_TW/syntax/type/advanced/special.md +++ b/doc/zh_TW/syntax/type/advanced/special.md @@ -1,5 +1,7 @@ # 特殊類型(Self、Super) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/special.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/special.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `Self` 代表它自己的類型。 您可以將其用作別名,但請注意派生類型的含義會發生變化(指的是自己的類型)。 ```python diff --git a/doc/zh_TW/syntax/type/advanced/typeof.md b/doc/zh_TW/syntax/type/advanced/typeof.md index a43da672..ca15b886 100644 --- a/doc/zh_TW/syntax/type/advanced/typeof.md +++ b/doc/zh_TW/syntax/type/advanced/typeof.md @@ -1,5 +1,7 @@ # Typeof, classof +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/typeof.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/typeof.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + `Typeof` 是一個可以窺探 Erg 類型推斷系統的函數,它的行為很復雜 ```python diff --git a/doc/zh_TW/syntax/type/advanced/variance.md b/doc/zh_TW/syntax/type/advanced/variance.md index 6afead62..1124dc38 100644 --- a/doc/zh_TW/syntax/type/advanced/variance.md +++ b/doc/zh_TW/syntax/type/advanced/variance.md @@ -1,5 +1,7 @@ # 變化 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/variance.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/variance.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg 可以對多態類型進行子類型化,但有一些注意事項。 首先,考慮普通多態類型的包含關系。一般來說,有一個容器`K`和它分配的類型`A,B`,當`A < B`時,`K A < K B`。 diff --git a/doc/zh_TW/syntax/type/advanced/widening.md b/doc/zh_TW/syntax/type/advanced/widening.md index 22991331..4f8a11b6 100644 --- a/doc/zh_TW/syntax/type/advanced/widening.md +++ b/doc/zh_TW/syntax/type/advanced/widening.md @@ -1,5 +1,7 @@ # 類型加寬 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/advanced/widening.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/advanced/widening.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + 例如,定義多相關系數如下。 ```python diff --git a/doc/zh_TW/tips.md b/doc/zh_TW/tips.md index 2ce0240b..56d8f484 100644 --- a/doc/zh_TW/tips.md +++ b/doc/zh_TW/tips.md @@ -1,5 +1,7 @@ # 提示 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tips.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tips.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) + ## 想要更改顯示錯誤的語言 請為您的語言下載 Erg。 diff --git a/doc/zh_TW/tools/build.md b/doc/zh_TW/tools/build.md index 2f8fd227..bbc7fa5a 100644 --- a/doc/zh_TW/tools/build.md +++ b/doc/zh_TW/tools/build.md @@ -1,5 +1,7 @@ # 構建子命令 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/build.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/build.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + build 子命令構建包。 默認構建中執行的步驟如下: diff --git a/doc/zh_TW/tools/env.md b/doc/zh_TW/tools/env.md index 44e6f30c..933ff187 100644 --- a/doc/zh_TW/tools/env.md +++ b/doc/zh_TW/tools/env.md @@ -1,5 +1,7 @@ # 環境子命令 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/env.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/env.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + env 子命令指定 erg 執行環境。 使用 `erg env new [env name]` 創建一個新的執行環境。 將打開一個交互式工具,當您指定 erg 版本時,將安裝該版本的 erg(如果已存在,將使用它),您將能夠將其用作新環境。 您可以使用 `erg env switch [env name]` 切換環境。 diff --git a/doc/zh_TW/tools/fmt.md b/doc/zh_TW/tools/fmt.md index a7f9ce90..4f73844c 100644 --- a/doc/zh_TW/tools/fmt.md +++ b/doc/zh_TW/tools/fmt.md @@ -1,5 +1,7 @@ # fmt +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/fmt.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/fmt.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 可以使用 fmt 子命令來完成代碼格式化。 常用的標志有: diff --git a/doc/zh_TW/tools/index.md b/doc/zh_TW/tools/index.md index e69de29b..f08300dc 100644 --- a/doc/zh_TW/tools/index.md +++ b/doc/zh_TW/tools/index.md @@ -0,0 +1,2 @@ +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/index.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/index.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + diff --git a/doc/zh_TW/tools/install.md b/doc/zh_TW/tools/install.md index c8a85230..dec4ce30 100644 --- a/doc/zh_TW/tools/install.md +++ b/doc/zh_TW/tools/install.md @@ -1,5 +1,7 @@ # 安裝子命令 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/install.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/install.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 您可以使用 install 安裝在注冊表站點上注冊的軟件包。 基本用法與cargo等包管理器相同。 diff --git a/doc/zh_TW/tools/pack.md b/doc/zh_TW/tools/pack.md index 8b012a8e..f966688c 100644 --- a/doc/zh_TW/tools/pack.md +++ b/doc/zh_TW/tools/pack.md @@ -1,5 +1,7 @@ # 包管理器 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/pack.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/pack.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + Erg 標配有一個包管理器,您可以使用 `pack` 子命令調用它。 以下是典型的選項。 diff --git a/doc/zh_TW/tools/repl.md b/doc/zh_TW/tools/repl.md index 2f02a483..765b72a7 100644 --- a/doc/zh_TW/tools/repl.md +++ b/doc/zh_TW/tools/repl.md @@ -1,5 +1,7 @@ # REPL +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/repl.md%26commit_hash%3Dd15cbbf7b33df0f78a575cff9679d84c36ea3ab1)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/repl.md&commit_hash=d15cbbf7b33df0f78a575cff9679d84c36ea3ab1) + 運行不帶參數的 `erg` 命令會調用 REPL。 它也可以用 `repl` 子命令調用。 此外,您可以指定以下標志: diff --git a/doc/zh_TW/tools/test.md b/doc/zh_TW/tools/test.md index 237826e8..a5254f27 100644 --- a/doc/zh_TW/tools/test.md +++ b/doc/zh_TW/tools/test.md @@ -1,5 +1,7 @@ # 測試子命令 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tools/test.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tools/test.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) + erg 命令有一個名為 test 的子命令,它支持測試的實現和執行。 ## 測試裝飾器 (@Test) From 836a0e0449c785be4226ea96c25fee8d3a4b2a29 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Tue, 6 Sep 2022 20:16:47 +0800 Subject: [PATCH 33/42] trifle --- doc/JA/dev_guide/i18n_messages.md | 2 +- doc/JA/syntax/25_object_system.md | 4 ++-- doc/zh_CN/API/types.md | 2 +- doc/zh_CN/dev_guide/terms.md | 6 +++--- doc/zh_CN/syntax/04_function.md | 6 +++--- doc/zh_CN/syntax/05_builtin_funcs.md | 2 +- doc/zh_CN/syntax/25_object_system.md | 4 ++-- doc/zh_CN/syntax/29_decorator.md | 4 ++-- doc/zh_CN/syntax/SUMMARY.md | 2 +- doc/zh_CN/syntax/type/17_type_casting.md | 2 +- doc/zh_TW/API/types.md | 2 +- doc/zh_TW/dev_guide/terms.md | 6 +++--- doc/zh_TW/syntax/04_function.md | 6 +++--- doc/zh_TW/syntax/05_builtin_funcs.md | 2 +- doc/zh_TW/syntax/25_object_system.md | 4 ++-- doc/zh_TW/syntax/29_decorator.md | 4 ++-- doc/zh_TW/syntax/SUMMARY.md | 2 +- doc/zh_TW/syntax/type/17_type_casting.md | 2 +- 18 files changed, 31 insertions(+), 31 deletions(-) diff --git a/doc/JA/dev_guide/i18n_messages.md b/doc/JA/dev_guide/i18n_messages.md index 312d2553..5a971cb4 100644 --- a/doc/JA/dev_guide/i18n_messages.md +++ b/doc/JA/dev_guide/i18n_messages.md @@ -55,6 +55,6 @@ A: 現在、以下の言語がサポートされています。 * "english" (デフォルト) * "japanese" (日本語) * "simplified_chinese" (簡体字中国語) -* "traditional_chinese"(繁体字中国語) +* "traditional_chinese"(繁体字中国語) これら以外の言語を追加したい場合は、リクエストしてください。 diff --git a/doc/JA/syntax/25_object_system.md b/doc/JA/syntax/25_object_system.md index 144fb5cb..88076206 100644 --- a/doc/JA/syntax/25_object_system.md +++ b/doc/JA/syntax/25_object_system.md @@ -9,8 +9,8 @@ * `.__dir__`: オブジェクトの属性を一覧にして返します * `.__hash__`: オブジェクトのハッシュ値を返します * `.__getattribute__`: オブジェクトの属性を取得して返します -* `.clone`: オブジェクトのクローン(メモリ上に独立な実体を持つ)を生成して返します -* `.copy`: オブジェクトのコピー(メモリ上で同じものをさす)を返します +* `.clone`: オブジェクトのクローン(メモリ上に独立な実体を持つ)を生成して返します +* `.copy`: オブジェクトのコピー(メモリ上で同じものをさす)を返します ## Record(レコード) diff --git a/doc/zh_CN/API/types.md b/doc/zh_CN/API/types.md index 8358b78c..e4f25143 100644 --- a/doc/zh_CN/API/types.md +++ b/doc/zh_CN/API/types.md @@ -164,7 +164,7 @@ Trait 类相当于 Python 中的 ABC(抽象基类,接口) * `title` * `upper` -## 其他 +## 其他 ### 位 diff --git a/doc/zh_CN/dev_guide/terms.md b/doc/zh_CN/dev_guide/terms.md index eb31fb2b..66bf0055 100644 --- a/doc/zh_CN/dev_guide/terms.md +++ b/doc/zh_CN/dev_guide/terms.md @@ -591,7 +591,7 @@ Erg 标准 API 未在 .er 文件中实现。 ### [赋值](../syntax/02_variable.md/#assignment) -### 多 +### 多 * [多重继承](../syntax/type/07_inheritance.md/#禁止多重继承) * 多重赋值 @@ -639,7 +639,7 @@ Erg 标准 API 未在 .er 文件中实现。 可作为 API 使用的属性。特别是由特征自动实现的属性。 -### 申请 +### 申请 将参数传递给函数对象并获取评估结果。 @@ -666,7 +666,7 @@ f x = ... 通过指定形式参数的默认值,可以在调用时省略实际参数的指定的函数。 -### 扩张 +### 扩张 * 扩展运算符 * 扩展分配 diff --git a/doc/zh_CN/syntax/04_function.md b/doc/zh_CN/syntax/04_function.md index 085e9be2..efc8ef08 100644 --- a/doc/zh_CN/syntax/04_function.md +++ b/doc/zh_CN/syntax/04_function.md @@ -1,4 +1,4 @@ -# 功能 +# 功能 [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/04_function.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/04_function.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) @@ -125,8 +125,8 @@ f x := 1, y := x = ... # NG 输出其参数的日志(记录)的 `log` 函数可以采用任意数量的参数。 -```蟒蛇 -记录“你好”、“世界”、“!” # 你好世界 ! +```python +记录“你好”、“世界”、“!” # 你好世界 ! ``` 要定义这样的函数,请将 `...` 添加到参数中。 这样,函数将参数作为可变长度数组接收 diff --git a/doc/zh_CN/syntax/05_builtin_funcs.md b/doc/zh_CN/syntax/05_builtin_funcs.md index 6fd87b16..5eadce67 100644 --- a/doc/zh_CN/syntax/05_builtin_funcs.md +++ b/doc/zh_CN/syntax/05_builtin_funcs.md @@ -2,7 +2,7 @@ [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/05_builtin_funcs.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/05_builtin_funcs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) -## 如果 +## 如果 `if` 是一个根据条件改变处理的函数。 diff --git a/doc/zh_CN/syntax/25_object_system.md b/doc/zh_CN/syntax/25_object_system.md index edf799ba..5272ca56 100644 --- a/doc/zh_CN/syntax/25_object_system.md +++ b/doc/zh_CN/syntax/25_object_system.md @@ -1,4 +1,4 @@ -# 目的 +# 目的 [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/25_object_system.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/25_object_system.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) @@ -37,7 +37,7 @@ record.private_attr # AttributeError: private_attr 是私有的 assert record.method() == 3 ``` -## 元素 +## 元素 属于特定类型的对象(例如,“1”是“Int”类型的元素)。所有对象至少是`{=}`类型的元素。 类的元素有时称为实例。 diff --git a/doc/zh_CN/syntax/29_decorator.md b/doc/zh_CN/syntax/29_decorator.md index 7f0c5c0a..823a1d58 100644 --- a/doc/zh_CN/syntax/29_decorator.md +++ b/doc/zh_CN/syntax/29_decorator.md @@ -40,7 +40,7 @@ C = Class... 指示定义类型是可继承的类。 如果为参数 `scope` 指定 `"public"`,甚至可以继承外部模块的类。 默认情况下它是`"private"`,不能被外部继承。 -## 最后 +## 最后 使该方法不可覆盖。 将它添加到类中使其成为不可继承的类,但由于它是默认值,因此没有意义。 @@ -113,7 +113,7 @@ assert Y in U. attaches 指示变量规范已过时且不推荐使用。 -## 测试 +## 测试 表示这是一个测试子例程。 测试子程序使用 `erg test` 命令运行。 diff --git a/doc/zh_CN/syntax/SUMMARY.md b/doc/zh_CN/syntax/SUMMARY.md index 2eebbae2..3715a451 100644 --- a/doc/zh_CN/syntax/SUMMARY.md +++ b/doc/zh_CN/syntax/SUMMARY.md @@ -1,4 +1,4 @@ -# 概括 +# 概括 [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/SUMMARY.md%26commit_hash%3D2ce482b1c8407332b3b74f4c3e5596f373f9a657)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/SUMMARY.md&commit_hash=2ce482b1c8407332b3b74f4c3e5596f373f9a657) diff --git a/doc/zh_CN/syntax/type/17_type_casting.md b/doc/zh_CN/syntax/type/17_type_casting.md index 2500c346..cd04bcc6 100644 --- a/doc/zh_CN/syntax/type/17_type_casting.md +++ b/doc/zh_CN/syntax/type/17_type_casting.md @@ -1,4 +1,4 @@ -# 投掷 +# 投掷 [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/17_type_casting.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/17_type_casting.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) diff --git a/doc/zh_TW/API/types.md b/doc/zh_TW/API/types.md index c6ef3225..2dba366c 100644 --- a/doc/zh_TW/API/types.md +++ b/doc/zh_TW/API/types.md @@ -164,7 +164,7 @@ Trait 類相當于 Python 中的 ABC(抽象基類,接口) * `title` * `upper` -## 其他 +## 其他 ### 位 diff --git a/doc/zh_TW/dev_guide/terms.md b/doc/zh_TW/dev_guide/terms.md index e9a57f8e..a023bfb9 100644 --- a/doc/zh_TW/dev_guide/terms.md +++ b/doc/zh_TW/dev_guide/terms.md @@ -591,7 +591,7 @@ Erg 標準 API 未在 .er 文件中實現。 ### [賦值](../syntax/02_variable.md/#assignment) -### 多 +### 多 * [多重繼承](../syntax/type/07_inheritance.md/#禁止多重繼承) * 多重賦值 @@ -639,7 +639,7 @@ Erg 標準 API 未在 .er 文件中實現。 可作為 API 使用的屬性。特別是由特征自動實現的屬性。 -### 申請 +### 申請 將參數傳遞給函數對象并獲取評估結果。 @@ -666,7 +666,7 @@ f x = ... 通過指定形式參數的默認值,可以在調用時省略實際參數的指定的函數。 -### 擴張 +### 擴張 * 擴展運算符 * 擴展分配 diff --git a/doc/zh_TW/syntax/04_function.md b/doc/zh_TW/syntax/04_function.md index 25389c36..3fb06cd5 100644 --- a/doc/zh_TW/syntax/04_function.md +++ b/doc/zh_TW/syntax/04_function.md @@ -1,4 +1,4 @@ -# 功能 +# 功能 [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/04_function.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/04_function.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) @@ -125,8 +125,8 @@ f x := 1, y := x = ... # NG 輸出其參數的日志(記錄)的 `log` 函數可以采用任意數量的參數。 -```蟒蛇 -記錄“你好”、“世界”、“!” # 你好世界 ! +```python +記錄“你好”、“世界”、“!” # 你好世界 ! ``` 要定義這樣的函數,請將 `...` 添加到參數中。 這樣,函數將參數作為可變長度數組接收 diff --git a/doc/zh_TW/syntax/05_builtin_funcs.md b/doc/zh_TW/syntax/05_builtin_funcs.md index db2204b0..1df9023d 100644 --- a/doc/zh_TW/syntax/05_builtin_funcs.md +++ b/doc/zh_TW/syntax/05_builtin_funcs.md @@ -2,7 +2,7 @@ [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/05_builtin_funcs.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/05_builtin_funcs.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) -## 如果 +## 如果 `if` 是一個根據條件改變處理的函數。 diff --git a/doc/zh_TW/syntax/25_object_system.md b/doc/zh_TW/syntax/25_object_system.md index 317f702b..bca97d5b 100644 --- a/doc/zh_TW/syntax/25_object_system.md +++ b/doc/zh_TW/syntax/25_object_system.md @@ -1,4 +1,4 @@ -# 目的 +# 目的 [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/25_object_system.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/25_object_system.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) @@ -37,7 +37,7 @@ record.private_attr # AttributeError: private_attr 是私有的 assert record.method() == 3 ``` -## 元素 +## 元素 屬于特定類型的對象(例如,“1”是“Int”類型的元素)。所有對象至少是`{=}`類型的元素。 類的元素有時稱為實例。 diff --git a/doc/zh_TW/syntax/29_decorator.md b/doc/zh_TW/syntax/29_decorator.md index 1b19af3a..97e94d02 100644 --- a/doc/zh_TW/syntax/29_decorator.md +++ b/doc/zh_TW/syntax/29_decorator.md @@ -40,7 +40,7 @@ C = Class... 指示定義類型是可繼承的類。 如果為參數 `scope` 指定 `"public"`,甚至可以繼承外部模塊的類。 默認情況下它是`"private"`,不能被外部繼承。 -## 最后 +## 最后 使該方法不可覆蓋。 將它添加到類中使其成為不可繼承的類,但由于它是默認值,因此沒有意義。 @@ -113,7 +113,7 @@ assert Y in U. attaches 指示變量規范已過時且不推薦使用。 -## 測試 +## 測試 表示這是一個測試子例程。 測試子程序使用 `erg test` 命令運行。 diff --git a/doc/zh_TW/syntax/SUMMARY.md b/doc/zh_TW/syntax/SUMMARY.md index 1fa1e2c4..01f84f51 100644 --- a/doc/zh_TW/syntax/SUMMARY.md +++ b/doc/zh_TW/syntax/SUMMARY.md @@ -1,4 +1,4 @@ -# 概括 +# 概括 [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/SUMMARY.md%26commit_hash%3D2ce482b1c8407332b3b74f4c3e5596f373f9a657)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/SUMMARY.md&commit_hash=2ce482b1c8407332b3b74f4c3e5596f373f9a657) diff --git a/doc/zh_TW/syntax/type/17_type_casting.md b/doc/zh_TW/syntax/type/17_type_casting.md index fcf0ff37..14a80ce8 100644 --- a/doc/zh_TW/syntax/type/17_type_casting.md +++ b/doc/zh_TW/syntax/type/17_type_casting.md @@ -1,4 +1,4 @@ -# 投擲 +# 投擲 [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/type/17_type_casting.md%26commit_hash%3D51de3c9d5a9074241f55c043b9951b384836b258)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/type/17_type_casting.md&commit_hash=51de3c9d5a9074241f55c043b9951b384836b258) From f2118ff45d9e46ca8fa44242363223be43b046dd Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Tue, 6 Sep 2022 20:28:21 +0800 Subject: [PATCH 34/42] trifle --- CODE_OF_CONDUCT.md | 18 +- CODE_OF_CONDUCT/CODE_OF_CONDUCT_EN.md | 27 -- CODE_OF_CONDUCT/LICENSE | 395 ------------------ CONTRIBUTING.md | 12 + README.md | 2 +- README_JA.md | 3 +- README_zh-CN.md | 3 +- README_zh-TW.md | 3 +- .../CODE_OF_CONDUCT}/CODE_OF_CONDUCT_JA.md | 12 +- .../CODE_OF_CONDUCT}/CODE_OF_CONDUCT_zh-CN.md | 12 +- .../CODE_OF_CONDUCT}/CODE_OF_CONDUCT_zh-TW.md | 10 - doc/CONTRIBUTING/CONTRIBUTING_JA.md | 38 ++ doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md | 38 ++ doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md | 38 ++ 14 files changed, 146 insertions(+), 465 deletions(-) delete mode 100644 CODE_OF_CONDUCT/CODE_OF_CONDUCT_EN.md delete mode 100644 CODE_OF_CONDUCT/LICENSE rename {CODE_OF_CONDUCT => doc/CODE_OF_CONDUCT}/CODE_OF_CONDUCT_JA.md (62%) rename {CODE_OF_CONDUCT => doc/CODE_OF_CONDUCT}/CODE_OF_CONDUCT_zh-CN.md (67%) rename {CODE_OF_CONDUCT => doc/CODE_OF_CONDUCT}/CODE_OF_CONDUCT_zh-TW.md (68%) create mode 100644 doc/CONTRIBUTING/CONTRIBUTING_JA.md create mode 100644 doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md create mode 100644 doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index e6eafb3d..b7db6bea 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,9 +1,19 @@ # Code of Conduct -See [CODE_OF_CONDUCT](./CODE_OF_CONDUCT) Folder. +English | 日本語 | 简体中文 | 繁體中文 -[CODE_OF_CONDUCT](./CODE_OF_CONDUCT)フォルダを参照してください。 +## General -参见[CODE_OF_CONDUCT](./CODE_OF_CONDUCT)文件夹 +Respect others. -參見[CODE_OF_CONDUCT](./CODE_OF_CONDUCT)資料夾 +Do not say mean things or show contempt, even if there is a difference in skill. + +Do not be aggressive in disagreements. + +Do not deny any identity of the other person. + +Do not post anything that is severely offensive to others. + +Do not spam, fish or troll. + +If you see someone who you think is violating this Code of Conduct, please contact the [administrator](mailto:moderation.erglang@gmail.com) immediately. We will take appropriate action. diff --git a/CODE_OF_CONDUCT/CODE_OF_CONDUCT_EN.md b/CODE_OF_CONDUCT/CODE_OF_CONDUCT_EN.md deleted file mode 100644 index 74cb8883..00000000 --- a/CODE_OF_CONDUCT/CODE_OF_CONDUCT_EN.md +++ /dev/null @@ -1,27 +0,0 @@ -# Code of Conduct - -## General - -Respect others. - -Do not say mean things or show contempt, even if there is a difference in skill. - -Do not be aggressive in disagreements. - -Do not deny any identity of the other person. - -Do not post anything that is severely offensive to others. - -Do not spam, fish or troll. - -If you see someone who you think is violating this Code of Conduct, please contact the [administrator](mailto:moderation.erglang@gmail.com) immediately. We will take appropriate action. - -## Development - -Requests are always welcome, but please keep in mind that they will not always be accepted. Many issues have trade-offs. - -Don't intercept issues that others have been assigned (Check assignees on GitHub). If it is considered too difficult for one person to handle it, we will call for more support. - -Before proposing a new feature, consider whether that feature could be easily solved by combining existing features. - -Please write code in a style that is standardized by the Erg team and languages. diff --git a/CODE_OF_CONDUCT/LICENSE b/CODE_OF_CONDUCT/LICENSE deleted file mode 100644 index 52bd1459..00000000 --- a/CODE_OF_CONDUCT/LICENSE +++ /dev/null @@ -1,395 +0,0 @@ -Attribution 4.0 International - -======================================================================= - -Creative Commons Corporation ("Creative Commons") is not a law firm and -does not provide legal services or legal advice. Distribution of -Creative Commons public licenses does not create a lawyer-client or -other relationship. Creative Commons makes its licenses and related -information available on an "as-is" basis. Creative Commons gives no -warranties regarding its licenses, any material licensed under their -terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the -fullest extent possible. - -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and -conditions that creators and other rights holders may use to share -original works of authorship and other material subject to copyright -and certain other rights specified in the public license below. The -following considerations are for informational purposes only, are not -exhaustive, and do not form part of our licenses. - - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More_considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - -======================================================================= - -Creative Commons Attribution 4.0 International Public License - -By exercising the Licensed Rights (defined below), You accept and agree -to be bound by the terms and conditions of this Creative Commons -Attribution 4.0 International Public License ("Public License"). To the -extent this Public License may be interpreted as a contract, You are -granted the Licensed Rights in consideration of Your acceptance of -these terms and conditions, and the Licensor grants You such rights in -consideration of benefits the Licensor receives from making the -Licensed Material available under these terms and conditions. - - -Section 1 -- Definitions. - - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - - c. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - - d. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - - e. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - - f. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - g. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - - h. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - i. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - - j. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - - k. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - - -Section 2 -- Scope. - - a. License grant. - - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - - a. reproduce and Share the Licensed Material, in whole or - in part; and - - b. produce, reproduce, and Share Adapted Material. - - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - - 3. Term. The term of this Public License is specified in Section - 6(a). - - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - - 5. Downstream recipients. - - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - - b. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - - b. Other rights. - - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - - 2. Patent and trademark rights are not licensed under this - Public License. - - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties. - - -Section 3 -- License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the -following conditions. - - a. Attribution. - - 1. If You Share the Licensed Material (including in modified - form), You must: - - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of - warranties; - - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - - 4. If You Share Adapted Material You produce, the Adapter's - License You apply must not prevent recipients of the Adapted - Material from complying with this Public License. - - -Section 4 -- Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that -apply to Your use of the Licensed Material: - - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database; - - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material; and - - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not -replace Your obligations under this Public License where the Licensed -Rights include other Copyright and Similar Rights. - - -Section 5 -- Disclaimer of Warranties and Limitation of Liability. - - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - - -Section 6 -- Term and Termination. - - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - - 2. upon express reinstatement by the Licensor. - - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - - -Section 7 -- Other Terms and Conditions. - - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - - -Section 8 -- Interpretation. - - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - - -======================================================================= - -Creative Commons is not a party to its public -licenses. Notwithstanding, Creative Commons may elect to apply one of -its public licenses to material it publishes and in those instances -will be considered the “Licensor.” The text of the Creative Commons -public licenses is dedicated to the public domain under the CC0 Public -Domain Dedication. Except for the limited purpose of indicating that -material is shared under a Creative Commons public license or as -otherwise permitted by the Creative Commons policies published at -creativecommons.org/policies, Creative Commons does not authorize the -use of the trademark "Creative Commons" or any other trademark or logo -of Creative Commons without its prior written consent including, -without limitation, in connection with any unauthorized modifications -to any of its public licenses or any other arrangements, -understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the -public licenses. - -Creative Commons may be contacted at creativecommons.org. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4a9ee286..87bd4e32 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,7 @@ # Contributing to Erg +English | 日本語 | 简体中文 | 繁體中文 + Beginners should read the instructions [here](https://github.com/erg-lang/erg/issues/31#issuecomment-1217505198). ## Documents @@ -25,4 +27,14 @@ We also welcome people who find that the documentation is outdated compared to o If you have any questions, please feel free to ask them on the [Discord channel](https://discord.gg/zfAAUbgGr4). +## Development + +Requests are always welcome, but please keep in mind that they will not always be accepted. Many issues have trade-offs. + +Don't intercept issues that others have been assigned (Check assignees on GitHub). If it is considered too difficult for one person to handle it, we will call for more support. + +Before proposing a new feature, consider whether that feature could be easily solved by combining existing features. + +Please write code in a style that is standardized by the Erg team and languages. + ## [Code of conduct](./CODE_OF_CONDUCT.md) diff --git a/README.md b/README.md index b05a0372..65187b44 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,6 @@ If you have any questions, please feel free to ask them on the [Discord channel] ## License -All files in the [CODE_OF_CONDUCT](./CODE_OF_CONDUCT), [assets](./assets) and [doc](./doc) folders are licensed with [CC-BY-4.0](./doc/LICENSE). The rest of the files in this repository are licensed with [Apache License 2.0](./LICENSE-APACHE) + [MIT License](./LICENSE-MIT). +All files in the [assets](./assets) and [doc](./doc) folders are licensed with [CC-BY-4.0](./doc/LICENSE). The rest of the files in this repository are licensed with [Apache License 2.0](./LICENSE-APACHE) + [MIT License](./LICENSE-MIT). For credits about third party crates, see [THIRD_PARTY_CREDITS.md](./THIRD_PARTY_CREDITS.md). diff --git a/README_JA.md b/README_JA.md index c51931a2..0e0f06b8 100644 --- a/README_JA.md +++ b/README_JA.md @@ -10,7 +10,6 @@ Build status Build status
- English | 日本語 | 简体中文 | 繁體中文

[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D585ebe9d59fb2190c8c3aeca49d53385a5f7e256) @@ -230,6 +229,6 @@ nix build ## License -[CODE_OF_CONDUCT](./CODE_OF_CONDUCT)、[assets](./assets)、および[doc](./doc)内のすべてのファイルは、[CC-BY-4.0](./doc/LICENSE)でライセンスされています。残りのファイルは、[Apache License 2.0](./LICENSE-APACHE) + [MIT License](./LICENSE-MIT) でライセンスされています。 +[assets](./assets)、および[doc](./doc)内のすべてのファイルは、[CC-BY-4.0](./doc/LICENSE)でライセンスされています。残りのファイルは、[Apache License 2.0](./LICENSE-APACHE) + [MIT License](./LICENSE-MIT) でライセンスされています。 サードパーティーの依存ライブラリのクレジットについては、[THIRD_PARTY_CREDITS.md](./THIRD_PARTY_CREDITS.md) (英語) をご覧ください。 diff --git a/README_zh-CN.md b/README_zh-CN.md index 51c678a0..2d1fd815 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -10,7 +10,6 @@ Build status Build status
- English | 日本語 | 简体中文 | 繁體中文

[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D585ebe9d59fb2190c8c3aeca49d53385a5f7e256) @@ -233,6 +232,6 @@ nix build ## License -在此存储库[CODE_OF_CONDUCT](./CODE_OF_CONDUCT),[assets](./assets)和[doc](./doc)文件夹内的所有文件使用[CC-BY-4.0](./doc/LICENSE)授权。其余文件使用[Apache License 2.0](./LICENSE-APACHE) + [MIT License](./LICENSE-MIT)授权 +在此存储库[assets](./assets)和[doc](./doc)文件夹内的所有文件使用[CC-BY-4.0](./doc/LICENSE)授权。其余文件使用[Apache License 2.0](./LICENSE-APACHE) + [MIT License](./LICENSE-MIT)授权 关于第三方crates的制作人员,请参阅:[THIRD_PARTY_CREDITS.md](./THIRD_PARTY_CREDITS.md)(英文) diff --git a/README_zh-TW.md b/README_zh-TW.md index c649ded3..b3459dc7 100644 --- a/README_zh-TW.md +++ b/README_zh-TW.md @@ -10,7 +10,6 @@ Build status Build status
- English | 日本語 | 简体中文 | 繁體中文

[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D585ebe9d59fb2190c8c3aeca49d53385a5f7e256) @@ -233,6 +232,6 @@ nix build ## License -在此存儲庫[CODE_OF_CONDUCT](./CODE_OF_CONDUCT),[assets](./assets)和[doc](./doc)文件夾內的所有文件使用[CC-BY-4.0](./doc/LICENSE)授權。其余文件使用[Apache License 2.0](./LICENSE-APACHE) + [MIT License](./LICENSE-MIT)授權 +在此存儲庫[assets](./assets)和[doc](./doc)文件夾內的所有文件使用[CC-BY-4.0](./doc/LICENSE)授權。其余文件使用[Apache License 2.0](./LICENSE-APACHE) + [MIT License](./LICENSE-MIT)授權 關於第三方crates的製作人員,請參閱:[THIRD_PARTY_CREDITS.md](./THIRD_PARTY_CREDITS.md)(英文) diff --git a/CODE_OF_CONDUCT/CODE_OF_CONDUCT_JA.md b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_JA.md similarity index 62% rename from CODE_OF_CONDUCT/CODE_OF_CONDUCT_JA.md rename to doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_JA.md index 3de39472..69b8a57e 100644 --- a/CODE_OF_CONDUCT/CODE_OF_CONDUCT_JA.md +++ b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_JA.md @@ -17,14 +17,4 @@ スパム、釣り、荒らし行為を行わないでください。 -この行動規範に違反していると思われる人物を見かけた場合、すぐに[管理者](mailto:moderation.erglang@gmail.com)に連絡してください。然るべき処置を行います。 - -## 開発・実装に関して - -リクエストは常に受け付けますが、常に採用されるとは限らないと心に留めておいてください。多くの問題には、トレードオフが存在します。 - -他者がアサインされたイシューを横取りするのはやめましょう(GitHubでassigneesを確認してください)。一人では手に余ると判断された場合は、さらに応援を募ります。 - -機能の提案をする前に、その機能が既存の機能を組み合わせて容易に解決できないか考えてください。 - -Ergチームや言語で標準とされるスタイルのコードを書いてください。 +この行動規範に違反していると思われる人物を見かけた場合、すぐに[管理者](mailto:moderation.erglang@gmail.com)に連絡してください。然るべき処置を行います。 \ No newline at end of file diff --git a/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-CN.md b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-CN.md similarity index 67% rename from CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-CN.md rename to doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-CN.md index 71284255..a1568da5 100644 --- a/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-CN.md +++ b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-CN.md @@ -17,14 +17,4 @@ 不要发布垃圾邮件,钓鱼消息或恶意挑衅的帖子 -如果您发现有人违反了本行为准则,请立即联系 [管理员](mailto:moderation.erglang@gmail.com)。我们将采取适当的行动 - -## 开发 - -请求总是受欢迎的,但请记住,它们不会总是被接受。许多问题都有取舍 - -不要拦截其他人已分配的问题(检查 GitHub 上的受理人)。如果认为一个人处理起来太困难,我们会呼吁更多的支持 - -在提出新功能之前,请考虑通过组合现有功能是否可以轻松解决该功能 - -请以 Erg 团队和语言标准化的风格编写代码 +如果您发现有人违反了本行为准则,请立即联系 [管理员](mailto:moderation.erglang@gmail.com)。我们将采取适当的行动 \ No newline at end of file diff --git a/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-TW.md b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-TW.md similarity index 68% rename from CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-TW.md rename to doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-TW.md index 9b244a8d..facd4238 100644 --- a/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-TW.md +++ b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-TW.md @@ -18,13 +18,3 @@ 不要發布垃圾郵件,釣魚消息或惡意挑釁的帖子 如果您發現有人違反了本行為準則,請立即聯繫 [管理員](mailto:moderation.erglang@gmail.com)。我們將採取適當的行動 - -## 開發 - -請求總是受歡迎的,但請記住,它們不會總是被接受。許多問題都有取捨 - -不要攔截其他人已分配的問題(檢查 GitHub 上的受理人)。如果認為一個人處理起來太困難,我們會呼籲更多的支持 - -在提出新功能之前,請考慮通過組合現有功能是否可以輕鬆解決該功能 - -請以 Erg 團隊和語言標準化的風格編寫代碼 diff --git a/doc/CONTRIBUTING/CONTRIBUTING_JA.md b/doc/CONTRIBUTING/CONTRIBUTING_JA.md new file mode 100644 index 00000000..b963d270 --- /dev/null +++ b/doc/CONTRIBUTING/CONTRIBUTING_JA.md @@ -0,0 +1,38 @@ +# Erg への貢献 + +初心者は[こちら](https://github.com/erg-lang/erg/issues/31#issuecomment-1217505198)の説明を読んでください。 + +## ドキュメント + +Erg への貢献を考えている場合は、[doc/dev_guide](./doc/EN/dev_guide/) にあるドキュメントを読む必要があります。 +または、Erg の内部構造に興味がある場合は、[doc/compiler](/doc/JA/compiler/) が役立つ情報を提供する可能性があります (現在は日本語のみ)。 + +## バグレポート + +Erg のバグだと思われる動作を見つけた場合は、[報告](https://github.com/erg-lang/erg/issues/new/choose)していただければ幸いです。同じバグがまだ問題として報告されていないことを確認してください。 + +「cargo run --features debug」と入力すると、Erg はデバッグ モードでビルドされます。このモードでは、バグの調査に役立つ情報がダンプされる場合があります。このモードでエラーログを報告していただければ幸いです。 + +また、バグが発生した環境が原因ではないことが明らかな場合は、バグが発生した環境を報告する必要はありません。 + +## ドキュメントの翻訳 + +私たちは常に、ドキュメントをさまざまな言語バージョンに翻訳してくれる人を探しています。 + +ドキュメントが他の言語に比べて古くなっていることに気づき、内容を更新したいという方も歓迎します ([こちら](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362) を参照)。これを行う方法について)。 + +## 質問する + +ご不明な点がございましたら、[Discord チャンネル](https://discord.gg/zfAAUbgGr4)までお気軽にお問い合わせください。 + +## 開発・実装に関して + +リクエストは常に受け付けますが、常に採用されるとは限らないと心に留めておいてください。多くの問題には、トレードオフが存在します。 + +他者がアサインされたイシューを横取りするのはやめましょう(GitHubでassigneesを確認してください)。一人では手に余ると判断された場合は、さらに応援を募ります。 + +機能の提案をする前に、その機能が既存の機能を組み合わせて容易に解決できないか考えてください。 + +Ergチームや言語で標準とされるスタイルのコードを書いてください。 + +## [行動規範](./CODE_OF_CONDUCT.md) \ No newline at end of file diff --git a/doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md b/doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md new file mode 100644 index 00000000..dde5ed1c --- /dev/null +++ b/doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md @@ -0,0 +1,38 @@ +# 为Erg做贡献 + +初学者应阅读说明 [此处](https://github.com/erg-lang/erg/issues/31#issuecomment-1217505198)。 + +## 文件 + +如果您正在考虑为 Erg 做贡献,您应该阅读 [doc/dev_guide](./doc/EN/dev_guide/) 下的文档。 +或者您对 Erg 的内部结构感兴趣,[doc/compiler](/doc/JA/compiler/) 可能会提供有用的信息(目前只有日语)。 + +## 错误报告 + +如果您发现任何您认为是 Erg 中的错误的行为,如果您愿意 [report](https://github.com/erg-lang/erg/issues/new/choose),我将不胜感激。请确保尚未将相同的错误报告为问题。 + +如果你输入 `cargo run --features debug`,Erg 将在调试模式下构建。此模式可能会转储可能对调查错误有用的信息。如果您能在此模式下报告错误日志,我将不胜感激。 + +此外,如果错误明确不是由环境引起的,则不需要报告错误发生的环境。 + +## 文档翻译 + +我们一直在寻找将我们的文件翻译成各种语言版本的人。 + +我们也欢迎那些发现文档与其他语言相比已经过时并希望更新内容的人(请参阅[此处](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)如何做到这一点)。 + +## 提问 + +如果您有任何问题,请随时在 [Discord 频道](https://discord.gg/zfAAUbgGr4) 上提问。 + +## 开发 + +请求总是受欢迎的,但请记住,它们不会总是被接受。许多问题都有取舍。 + +不要拦截其他人已分配的问题(检查 GitHub 上的受理人)。如果认为一个人处理起来太困难,我们会呼吁更多的支持。 + +在提出新功能之前,请考虑通过组合现有功能是否可以轻松解决该功能。 + +请以 Erg 团队和语言标准化的风格编写代码。 + +## [行为准则](./CODE_OF_CONDUCT.md) \ No newline at end of file diff --git a/doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md b/doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md new file mode 100644 index 00000000..ef34e51c --- /dev/null +++ b/doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md @@ -0,0 +1,38 @@ +# 為Erg做貢獻 + +初學者應閱讀說明 [此處](https://github.com/erg-lang/erg/issues/31#issuecomment-1217505198)。 + +## 文件 + +如果您正在考慮為 Erg 做貢獻,您應該閱讀 [doc/dev_guide](./doc/EN/dev_guide/) 下的文檔。 +或者您對 Erg 的內部結構感興趣,[doc/compiler](/doc/JA/compiler/) 可能會提供有用的信息(目前只有日語)。 + +## 錯誤報告 + +如果您發現任何您認為是 Erg 中的錯誤的行為,如果您願意 [report](https://github.com/erg-lang/erg/issues/new/choose),我將不勝感激。請確保尚未將相同的錯誤報告為問題。 + +如果你輸入 `cargo run --features debug`,Erg 將在調試模式下構建。此模式可能會轉儲可能對調查錯誤有用的信息。如果您能在此模式下報告錯誤日誌,我將不勝感激。 + +此外,如果錯誤明確不是由環境引起的,則不需要報告錯誤發生的環境。 + +## 文檔翻譯 + +我們一直在尋找將我們的文件翻譯成各種語言版本的人。 + +我們也歡迎那些發現文檔與其他語言相比已經過時並希望更新內容的人(請參閱[此處](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)如何做到這一點)。 + +## 提問 + +如果您有任何問題,請隨時在 [Discord 頻道](https://discord.gg/zfAAUbgGr4) 上提問。 + +## 開發 + +請求總是受歡迎的,但請記住,它們不會總是被接受。許多問題都有取捨。 + +不要攔截其他人已分配的問題(檢查 GitHub 上的受理人)。如果認為一個人處理起來太困難,我們會呼籲更多的支持。 + +在提出新功能之前,請考慮通過組合現有功能是否可以輕鬆解決該功能。 + +請以 Erg 團隊和語言標準化的風格編寫代碼。 + +## [行為準則](./CODE_OF_CONDUCT.md) \ No newline at end of file From a86bd4cd1bef4035a1ad23676c8324ab74f7b674 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Tue, 6 Sep 2022 20:29:55 +0800 Subject: [PATCH 35/42] trifle --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 87bd4e32..3dbff02b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to Erg -English | 日本語 | 简体中文 | 繁體中文 +English | 日本語 | 简体中文 | 繁體中文 Beginners should read the instructions [here](https://github.com/erg-lang/erg/issues/31#issuecomment-1217505198). From 03dd29fa209e207327fbccf7c92f15385f337944 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <62678643+C-BJ@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:31:25 +0800 Subject: [PATCH 36/42] Updata commit hash --- doc/CONTRIBUTING/CONTRIBUTING_JA.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/CONTRIBUTING/CONTRIBUTING_JA.md b/doc/CONTRIBUTING/CONTRIBUTING_JA.md index b963d270..1528281d 100644 --- a/doc/CONTRIBUTING/CONTRIBUTING_JA.md +++ b/doc/CONTRIBUTING/CONTRIBUTING_JA.md @@ -1,5 +1,8 @@ # Erg への貢献 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DCONTRIBUTING.md%26commit_hash%3Da86bd4cd1bef4035a1ad23676c8324ab74f7b674) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=CONTRIBUTING.md&commit_hash=a86bd4cd1bef4035a1ad23676c8324ab74f7b674) + 初心者は[こちら](https://github.com/erg-lang/erg/issues/31#issuecomment-1217505198)の説明を読んでください。 ## ドキュメント @@ -35,4 +38,4 @@ Erg のバグだと思われる動作を見つけた場合は、[報告](https:/ Ergチームや言語で標準とされるスタイルのコードを書いてください。 -## [行動規範](./CODE_OF_CONDUCT.md) \ No newline at end of file +## [行動規範](./CODE_OF_CONDUCT.md) From f21b281bde1ca6c5006dfc80a936b705e69ab18a Mon Sep 17 00:00:00 2001 From: Cai Bingjun <62678643+C-BJ@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:32:14 +0800 Subject: [PATCH 37/42] Updata commit hash --- doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md b/doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md index dde5ed1c..62e17038 100644 --- a/doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md +++ b/doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md @@ -1,5 +1,8 @@ # 为Erg做贡献 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DCONTRIBUTING.md%26commit_hash%3Da86bd4cd1bef4035a1ad23676c8324ab74f7b674) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=CONTRIBUTING.md&commit_hash=a86bd4cd1bef4035a1ad23676c8324ab74f7b674) + 初学者应阅读说明 [此处](https://github.com/erg-lang/erg/issues/31#issuecomment-1217505198)。 ## 文件 @@ -35,4 +38,4 @@ 请以 Erg 团队和语言标准化的风格编写代码。 -## [行为准则](./CODE_OF_CONDUCT.md) \ No newline at end of file +## [行为准则](./CODE_OF_CONDUCT.md) From 82f3a1d8dc812c4ed6cc43534f3caf71188777ba Mon Sep 17 00:00:00 2001 From: Cai Bingjun <62678643+C-BJ@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:32:26 +0800 Subject: [PATCH 38/42] Updata commit hash --- doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md b/doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md index ef34e51c..d2af7b5d 100644 --- a/doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md +++ b/doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md @@ -1,5 +1,8 @@ # 為Erg做貢獻 +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DCONTRIBUTING.md%26commit_hash%3Da86bd4cd1bef4035a1ad23676c8324ab74f7b674) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=CONTRIBUTING.md&commit_hash=a86bd4cd1bef4035a1ad23676c8324ab74f7b674) + 初學者應閱讀說明 [此處](https://github.com/erg-lang/erg/issues/31#issuecomment-1217505198)。 ## 文件 @@ -35,4 +38,4 @@ 請以 Erg 團隊和語言標準化的風格編寫代碼。 -## [行為準則](./CODE_OF_CONDUCT.md) \ No newline at end of file +## [行為準則](./CODE_OF_CONDUCT.md) From bb523a116ef0a183673c106f289dd7ea45351962 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Tue, 6 Sep 2022 20:35:08 +0800 Subject: [PATCH 39/42] Updata commit hash --- README_JA.md | 4 ++-- README_zh-CN.md | 4 ++-- README_zh-TW.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README_JA.md b/README_JA.md index 0e0f06b8..c2d22a2f 100644 --- a/README_JA.md +++ b/README_JA.md @@ -12,8 +12,8 @@

-[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D585ebe9d59fb2190c8c3aeca49d53385a5f7e256) -](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=585ebe9d59fb2190c8c3aeca49d53385a5f7e256) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3Df2118ff45d9e46ca8fa44242363223be43b046dd) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=f2118ff45d9e46ca8fa44242363223be43b046dd) ## Ergはこんな人におすすめです: diff --git a/README_zh-CN.md b/README_zh-CN.md index 2d1fd815..ec21a147 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -12,8 +12,8 @@

-[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D585ebe9d59fb2190c8c3aeca49d53385a5f7e256) -](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=585ebe9d59fb2190c8c3aeca49d53385a5f7e256) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3Df2118ff45d9e46ca8fa44242363223be43b046dd) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=f2118ff45d9e46ca8fa44242363223be43b046dd) ## Erg可以推荐给以下人员: diff --git a/README_zh-TW.md b/README_zh-TW.md index b3459dc7..e51913ef 100644 --- a/README_zh-TW.md +++ b/README_zh-TW.md @@ -12,8 +12,8 @@

-[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3D585ebe9d59fb2190c8c3aeca49d53385a5f7e256) -](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=585ebe9d59fb2190c8c3aeca49d53385a5f7e256) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DREADME.md%26commit_hash%3Df2118ff45d9e46ca8fa44242363223be43b046dd) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=README.md&commit_hash=f2118ff45d9e46ca8fa44242363223be43b046dd) ## Erg可以推薦給以下人員: From 375ed0c7a168c94b282755f27161e3136ef4e7d7 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <1945458160@qq.com> Date: Tue, 6 Sep 2022 20:35:48 +0800 Subject: [PATCH 40/42] Updata commit hash --- doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_JA.md | 4 ++-- doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-CN.md | 4 ++-- doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-TW.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_JA.md b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_JA.md index 69b8a57e..2eee327f 100644 --- a/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_JA.md +++ b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_JA.md @@ -1,7 +1,7 @@ # 行動規範 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DCODE_OF_CONDUCT.md%26commit_hash%3D3ace818c1055f22f9cbe71e00f31c0aa784d52b6) -](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=CODE_OF_CONDUCT.md&commit_hash=3ace818c1055f22f9cbe71e00f31c0aa784d52b6) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DCODE_OF_CONDUCT.md%26commit_hash%3Df2118ff45d9e46ca8fa44242363223be43b046dd) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=CODE_OF_CONDUCT.md&commit_hash=f2118ff45d9e46ca8fa44242363223be43b046dd) ## 全般 diff --git a/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-CN.md b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-CN.md index a1568da5..fbf4a76b 100644 --- a/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-CN.md +++ b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-CN.md @@ -1,7 +1,7 @@ # 行为准则 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DCODE_OF_CONDUCT.md%26commit_hash%3D3ace818c1055f22f9cbe71e00f31c0aa784d52b6) -](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=CODE_OF_CONDUCT.md&commit_hash=3ace818c1055f22f9cbe71e00f31c0aa784d52b6) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DCODE_OF_CONDUCT.md%26commit_hash%3Df2118ff45d9e46ca8fa44242363223be43b046dd) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=CODE_OF_CONDUCT.md&commit_hash=f2118ff45d9e46ca8fa44242363223be43b046dd) ## 常规 diff --git a/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-TW.md b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-TW.md index facd4238..1f863fcf 100644 --- a/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-TW.md +++ b/doc/CODE_OF_CONDUCT/CODE_OF_CONDUCT_zh-TW.md @@ -1,7 +1,7 @@ # 行為守則 -[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DCODE_OF_CONDUCT.md%26commit_hash%3D3ace818c1055f22f9cbe71e00f31c0aa784d52b6) -](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=CODE_OF_CONDUCT.md&commit_hash=3ace818c1055f22f9cbe71e00f31c0aa784d52b6) +[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3DCODE_OF_CONDUCT.md%26commit_hash%3Df2118ff45d9e46ca8fa44242363223be43b046dd) +](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=CODE_OF_CONDUCT.md&commit_hash=f2118ff45d9e46ca8fa44242363223be43b046dd) ## 常規 From 2bd29be4e66c65ddc7800f7f79462d94b26d469f Mon Sep 17 00:00:00 2001 From: Cai Bingjun <62678643+C-BJ@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:39:26 +0800 Subject: [PATCH 41/42] Update CONTRIBUTING_zh-CN.md --- doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md b/doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md index 62e17038..3479666c 100644 --- a/doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md +++ b/doc/CONTRIBUTING/CONTRIBUTING_zh-CN.md @@ -5,7 +5,7 @@ 初学者应阅读说明 [此处](https://github.com/erg-lang/erg/issues/31#issuecomment-1217505198)。 -## 文件 +## 文档 如果您正在考虑为 Erg 做贡献,您应该阅读 [doc/dev_guide](./doc/EN/dev_guide/) 下的文档。 或者您对 Erg 的内部结构感兴趣,[doc/compiler](/doc/JA/compiler/) 可能会提供有用的信息(目前只有日语)。 From 35b6fd5736b0f2ef1487c97cd428a1a32e824c91 Mon Sep 17 00:00:00 2001 From: Cai Bingjun <62678643+C-BJ@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:39:43 +0800 Subject: [PATCH 42/42] Update CONTRIBUTING_zh-TW.md --- doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md b/doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md index d2af7b5d..c1e54c6f 100644 --- a/doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md +++ b/doc/CONTRIBUTING/CONTRIBUTING_zh-TW.md @@ -5,7 +5,7 @@ 初學者應閱讀說明 [此處](https://github.com/erg-lang/erg/issues/31#issuecomment-1217505198)。 -## 文件 +## 文檔 如果您正在考慮為 Erg 做貢獻,您應該閱讀 [doc/dev_guide](./doc/EN/dev_guide/) 下的文檔。 或者您對 Erg 的內部結構感興趣,[doc/compiler](/doc/JA/compiler/) 可能會提供有用的信息(目前只有日語)。