본문으로 건너뛰기
토파즈6.0 · 출시 전
다운로드 →

문서 검색

명세 6.0

방향키로 결과를 고르고 Enter를 눌러 여세요.

API 이름, 진단 번호, 규칙 또는 프로젝트 주제를 입력하세요.

    언어 · 4장 · 21개 규칙

    바인딩과 범위

    Defines how names are introduced, resolved, and reassigned.

    Scope and status

    링크

    Use this page to declare bindings and understand name lookup, assignment, and lexical capture.

    Types covers compatibility and shared inference. Functions and generics covers calls and generic specialization. Pattern forms, module lookup, and protocol resolution belong to their respective chapters.

    Declaration syntax

    링크
    EBNF
    1. NamedLet = "let" "mut"? Identifier (":" Type)? "=" Expression ;
    2. Const = "const" Identifier (":" Type)? "=" Expression ;
    3. Assignment = AssignmentTarget "=" Expression ;
    4. AssignmentTarget = Identifier | MemberAccess | IndexAccess ;

    This transcribed excerpt shows named declarations and plain assignment. Pattern forms, compound operators, and statement boundaries have separate grammar productions.

    Declaration source observations

    링크
    규칙topaz.rule.bindings-and-scope.declaration-forms

    Binding declaration forms

    Each declaration requires an initializer after = and permits a type annotation. A named binding accepts at most one annotation, including an exported binding. Repeating the annotation produces TPZ2001 during parsing.

    DeclarationBinding form
    letA pattern
    let mutA single name
    constA single name

    이유

    An initializer gives every binding a value. One type annotation supplies one expectation without a second spelling or a competing annotation for the same name.

    규칙topaz.rule.bindings-and-scope.declaration-mutability

    Binding mutability

    DeclarationBinding mutability
    letImmutable
    let mutMutable
    constImmutable

    이유

    Reassignment is an explicit choice in the declaration. Immutable bindings let readers rely on one assigned value.

    규칙topaz.rule.bindings-and-scope.const-literals

    Literal const initializers

    Integer literals and untagged string literals without interpolation satisfy the constant-expression requirement for const initializers.

    이유

    A literal supplies its value without consulting runtime state, so it can be used wherever a constant expression is required.

    규칙topaz.rule.bindings-and-scope.const-runtime-reference

    Const references to let bindings

    A const initializer must be a constant expression. Referencing an ordinary let or let mut binding is rejected with TPZ5001.

    이유

    An immutable runtime binding can still depend on runtime computation. Rejecting such references keeps constant-expression admission independent of runtime state.

    규칙topaz.rule.bindings-and-scope.none-binding-name

    Reserved None binding name

    None cannot be a binding name. This includes let mut, const, typed binding patterns, and bare untyped patterns. The parser reports TPZ2012. Write None() for the Option constructor in patterns and values.

    이유

    Reserving None keeps absence recognizable in expressions and patterns. A local name cannot silently replace the Option constructor.

    규칙topaz.rule.bindings-pending.constant-evaluation

    Constant expressions and retained values

    A const initializer must pass ordinary name and type checking and the constant-expression check. Admitted forms include scalar and Length literals, None(), untagged strings with constant interpolations, available constant bindings, function values, parentheses, unary expressions, binary expressions other than in, arrays without spread, and record literals whose fields are constant expressions. A reference to a let binding, an ordinary function call, or a later constant in the same module is rejected. Const makes the binding immutable. Its data follows collection value semantics. Grouping a callee preserves its operation and receiver. The grouping does not change whether the call is a constant expression.

    The numeric call forms are int.and, int.or, int.xor, and int.shift with one constant integer operand, and float.trunc, float.floor, float.ceil, and float.round with no arguments and a constant float receiver. These calls take no explicit type arguments or spreads. Integer operands are supplied positionally. Integer and float arithmetic expressions may supply their receivers.

    Compiler-recognized std.typeset.fromScaledPoints and fromMilliPoints calls, Length conversion methods toPt, toMm, toCm, toIn and toScaledPoints, Pt.toMilliPoints, and Em.resolve admit constant operands. The std.typeset constructor recognition requires the generated standard module. Normal type and argument checks still apply. The implementation issue below preserves the permitted function-value expectation. Initialization-pass ordering is not a new language timing guarantee.

    이유

    A constant must not depend on runtime state. Grouping a callee preserves its operation and receiver, so it must preserve the same constant-expression decision.

    Assignment source observations

    링크
    규칙topaz.rule.bindings-and-scope.collection-value-semantics

    Collection values

    Since 6.0.0, Array, Map, Set, and ByteBuffer are values. Assignment, argument passing, return, and immutable capture each produce an independent value. Storing a value in a record field, collection element, or Map key or value does the same. Changing one value leaves the others unchanged.

    The rule applies recursively inside records, enum payloads, Option, and Result. ByteBuffer contains data without host state and follows the same rule.

    A write requires one let mut root binding, including writes through nested fields, indices, and collection operations. An immutable binding's data cannot change through an alias. The immutable assignment rule governs the write path. A function cannot change a caller's collection through a parameter. Bind a mutable local and return the changed value when the caller needs it.

    An implementation may share storage and copy when a write occurs. A program cannot observe this storage sharing. The rule makes no promise about allocation, time, or space costs.

    Shared handles represent host resources. File retains its shared cursor and closed state. A mutable capture shares one variable. A closure's write to that variable is visible outside the closure. A value assigned to another variable before the write remains unchanged.

    See immutable assignment, capture observation, parameter bindings, and collection keys. The existing File cursor example and closed handle example show the resource exception.

    이유

    Each intent has one representation. Data uses values and host resources use handles. Independent values prevent hidden changes, so results are reproducible and easy to verify. Concurrent work on separate collection values has no data race through shared collection storage. Collections map directly to value representations such as Rust Vec and HashMap.

    규칙topaz.rule.bindings-and-scope.assignment-forms

    Assignment target syntax

    An assignment target must be an identifier, member access, or index access. Other expression shapes produce TPZ2003 during parsing. The target also undergoes receiver and mutability checks.

    이유

    Assignment must identify a location that can receive a value. A temporary result has no binding or element to update.

    규칙topaz.rule.bindings-and-scope.immutable-assignment

    Assignment requires a mutable root

    Direct replacement of an imported binding is rejected during resolution under the import assignment rule. After resolution succeeds, assignment to an immutable binding, or to a member or index rooted in that binding, is rejected with TPZ5003.

    이유

    Mutability follows the root binding through field and index access. Adding an access step must not bypass the declaration's mutation rule.

    규칙topaz.rule.bindings-and-scope.assignment-type

    Expected type of assignment

    For =, the target type is the expected type of the right-hand expression.

    이유

    The destination already determines which values an assignment can store. Reusing that type gives empty or generic values the context they need.

    규칙topaz.rule.bindings-and-scope.optional-assignment

    Assignment through optional access

    A member or index assignment target whose receiver chain contains optional access ?. is rejected during checking with TPZ5001.

    이유

    An optional receiver can be absent, leaving no location to update. An explicit branch makes the skipped update and value evaluation visible.

    규칙topaz.rule.bindings-and-scope.map-assignment

    Assignment through Map indexing

    Assignment through a Map index is rejected with TPZ5001. Use the Map mutation API to update that binding's value under collection value semantics.

    이유

    Map insertion can add a key as well as replace a value. A named mutation operation makes that behavior explicit without another update spelling.

    Scope and capture source observations

    링크
    규칙topaz.rule.bindings-and-scope.lexical-lookup

    Lexical name lookup

    Local name lookup searches active scopes from the innermost outward and selects the first matching binding. Value and type namespaces are searched separately.

    이유

    Lexical nesting determines what a name means without depending on the caller. Separate namespaces keep value lookup from selecting a type declaration.

    규칙topaz.rule.bindings-and-scope.block-scope

    Nested block scope

    A nested block introduces a scope. After an inner binding is declared, later references inside the block resolve to it instead of an outer binding of the same name. References outside that block continue to resolve to the outer binding.

    이유

    A block bounds the visibility of local names. Temporary names inside it cannot replace the bindings used by surrounding code.

    규칙topaz.rule.bindings-and-scope.local-initializer-scope

    Local initializer scope

    Local let, const names become visible after their initializers have been resolved. An existing outer binding of the same name remains visible in the initializer.

    이유

    The initializer can use an existing outer value while computing its replacement. The new name becomes usable after that value exists.

    규칙topaz.rule.bindings-and-scope.unbound-name

    Unbound value names

    An ordinary value identifier with no binding or built-in definition is rejected with TPZ5002. Namespace heads follow the module lookup rules.

    이유

    Every ordinary reference needs a declaration that determines its value. Static rejection prevents execution with an unspecified binding.

    Direct top-level forward reads

    A top-level let initializer that directly reads a later let binding in the same module is rejected with TPZ3018 during resolution, for both entry and imported files. Declaration order is the statement order in that module.

    이유

    A declaration cannot read a runtime value that has not been initialized. Resolving direct reads before execution catches this mistake with the same TPZ3018 identity in entry and imported files. Local unbound-name errors and delayed runtime reads retain their separate TPZ5002 contract.

    규칙topaz.rule.bindings-and-scope.lexical-capture

    Lexical capture identity

    A function or lambda reference to an outer lexical binding in the same module resolves to that binding’s original declaration.

    이유

    A closure's references keep the meaning they had where it was defined. Calling it from a different scope must not retarget those names.

    규칙topaz.rule.bindings-pending.capture-observation

    Values observed by existing and escaping closures

    Closures that capture the same mutable binding observe its later assignments, including assignments made by another closure. An immutable capture retains its assigned value and cannot be rebound inside the closure. Collection values follow value semantics. Captured values and shared bindings remain available after the creating function returns while a closure retains them.

    이유

    A mutable captured binding represents one shared variable. Retaining captured storage while closures exist prevents references from outliving their values.

    규칙topaz.rule.bindings-pending.initialization-order

    Initialization through branches, calls, and closures

    Module-level let bindings become ready after their initializers complete, and function bindings become ready at their declaration position. A direct initializer read of the same or a later runtime binding is rejected with TPZ3018 during resolution in entry and imported files alike. The direct check follows an if or while condition, a match scrutinee, a for iterator, and the first comprehension source. It does not enter function, lambda, branch, arm, or loop bodies. Short-circuit right operands and optional-call arguments are delayed as well. A delayed reference reads the binding when execution reaches it. Reading before initialization faults with TPZ5002; reading after initialization returns the current value. Merely storing a closure does not evaluate its body.

    이유

    Module initialization can perform effects, so source order determines when runtime values become available. Delayed code must check the value when it actually executes.

    규칙topaz.rule.bindings-pending.same-scope-redeclarations

    Redeclaration and nested shadowing

    A module-level name may be declared once. Let, const, function, type, and imported declarations participate in the same module name table, and a second declaration is rejected with TPZ3008. Reusing a name in a nested scope is shadowing. A repeated local const is rejected with TPZ5008. The same local scope must also reject a second let or let mut name; the current let pattern path bypasses the checker guard, which is recorded as an implementation limitation. The local let regression retains TPZ5008 as its intended rejection contract.

    이유

    A name should identify one declaration within a scope. Rejecting duplicates prevents silent replacement, while nested scopes make shadowing explicit.

    Examples and expected results

    링크

    Each example is a complete example.tpz file. The expected success or rejection is independent of future observed output. All examples remain Pending. A source-backed expectation is not an executed result. Negative examples specify the intended cause and phase; their exact diagnostic locations remain unmeasured.

    Immutable, mutable, and constant bindings

    링크
    example.tpzImmutable, mutable, and constant bindings플레이그라운드 열기 →
    1. import std.io
    2. let start: int = 1
    3. let mut count: int = start
    4. count = 2
    5. const label = "Topaz"
    6. io.writeLine("{label}:{start}:{count}")
    기록된 출력종료 코드 0
    Topaz:1:2
    
    $ topaz run example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. Topaz:1:2
    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    관측한 표준 출력
    1. Topaz:1:2

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0
    • 통과 · stdout matches the authored expectation
    • 통과 · stderr matches the authored expectation
    • 통과 · stdout matches the authored expectation
    • 통과 · stdout matches the authored expectation
    • 통과 · stdout matches the authored expectation
    • 통과 · stdout matches the authored expectation

    An immutable binding cannot be reassigned

    링크
    example.tpzAn immutable binding cannot be reassigned플레이그라운드 열기 →
    1. let count: int = 1
    2. count = 2
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ5003]: `count` is immutable; declare it with `let mut`
     --> example.tpz:2:1
      |
    2 | count = 2
      | ^^^^^
    
    example.tpz: 1 type diagnostic
    
    $ topaz check example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5003 →

      bindings-assignment-to-immutable at example.tpz:2:1

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ5003]: `count` is immutable; declare it with `let mut`
    2. --> example.tpz:2:1
    3. |
    4. 2 | count = 2
    5. | ^^^^^
    6. example.tpz: 1 type diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ5003; cause bindings-assignment-to-immutable; primary location asserted; additional diagnostics allow
    • 통과 · checking TPZ5003; cause bindings-assignment-to-immutable; primary location asserted; additional diagnostics allow

    An ordinary let reference is not a const initializer

    링크
    example.tpzAn ordinary let reference is not a const initializer플레이그라운드 열기 →
    1. let source: int = 1
    2. const frozen: int = source
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ5001]: `const` initializers must be constant expressions (§4)
     --> example.tpz:2:21
      |
    2 | const frozen: int = source
      |                     ^^^^^^
    
    example.tpz: 1 type diagnostic
    
    $ topaz check example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      bindings-const-runtime-reference at example.tpz:2:21

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ5001]: `const` initializers must be constant expressions (§4)
    2. --> example.tpz:2:21
    3. |
    4. 2 | const frozen: int = source
    5. | ^^^^^^
    6. example.tpz: 1 type diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ5001; cause bindings-const-runtime-reference; primary location asserted; additional diagnostics allow

    None cannot name a mutable binding

    링크
    example.tpzNone cannot name a mutable binding플레이그라운드 열기 →
    1. let mut None = 1
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ2012]: `None` is the Option constructor (§22.1) and cannot be a binding name
     --> example.tpz:1:9
      |
    1 | let mut None = 1
      |         ^^^^
    
    example.tpz: 1 diagnostic
    
    $ topaz check example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ2012]: `None` is the Option constructor (§22.1) and cannot be a binding name
    2. --> example.tpz:1:9
    3. |
    4. 1 | let mut None = 1
    5. | ^^^^
    6. example.tpz: 1 diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ2012; cause bindings-none-name; primary location asserted; additional diagnostics allow

    A nested binding shadows the outer one

    링크
    example.tpzA nested binding shadows the outer one플레이그라운드 열기 →
    1. import std.io
    2. let value: int = 1
    3. let nested: string = {
    4. let value: string = "inner"
    5. value
    6. }
    7. let original: int = value
    8. io.writeLine("{nested}:{original}")
    기록된 출력종료 코드 0
    inner:1
    
    $ topaz run example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. inner:1
    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    관측한 표준 출력
    1. inner:1

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0
    • 통과 · stdout matches the authored expectation
    • 통과 · stderr matches the authored expectation
    • 통과 · stdout matches the authored expectation

    An ordinary unbound name is rejected

    링크
    example.tpzAn ordinary unbound name is rejected플레이그라운드 열기 →
    1. let copied: int = missing
    기록된 출력종료 코드 1
    표준 출력 없음.
    error[TPZ5002]: `missing` is not bound
     --> example.tpz:1:19
      |
    1 | let copied: int = missing
      |                   ^^^^^^^
    
    example.tpz: 1 type diagnostic
    
    $ topaz check example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    관측한 단언 · 통과 · 5.21.3

    종료 코드 1.

    표준 출력 없음.

    관측한 표준 오류 출력
    1. error[TPZ5002]: `missing` is not bound
    2. --> example.tpz:1:19
    3. |
    4. 1 | let copied: int = missing
    5. | ^^^^^^^
    6. example.tpz: 1 type diagnostic
    • 통과 · expected nonzero; observed 1
    • 통과 · stdout matches the authored expectation
    • 통과 · checking TPZ5002; cause bindings-unbound-read; primary location asserted; additional diagnostics allow

    A later top-level let is unavailable to a direct initializer

    링크
    example.tpzA later top-level let is unavailable to a direct initializer플레이그라운드 열기 →
    1. let before: int = after
    2. let after: int = 1
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz --compiler self · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3018 →

      module-initializer-not-ready at example.tpz:1:19

    The direct module initializer uses the same TPZ3018 resolve contract in entry and imported files. Current SELF rejects this entry source with TPZ5002; the existing receipt remains historical evidence for that earlier identity. The expected rejection and location are retained, and only the diagnostic assertion is limited.

    A lambda refers to an outer binding

    링크
    example.tpzA lambda refers to an outer binding플레이그라운드 열기 →
    1. import std.io
    2. let anchor: int = 7
    3. let reader: (int) -> int = (value) => anchor
    4. let observed: int = {
    5. let anchor: int = 99
    6. reader(0)
    7. }
    8. io.writeLine("{observed}")
    기록된 출력종료 코드 0
    7
    
    $ topaz run example.tpz --compiler self · 기록에 사용한 토파즈 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 7
    관측한 단언 · 통과 · 5.21.3

    종료 코드 0.

    관측한 표준 출력
    1. 7

    표준 오류 출력 없음.

    • 통과 · expected 0; observed 0
    • 통과 · stdout matches the authored expectation
    • 통과 · stderr matches the authored expectation

    Two escaping closures share one mutable binding

    링크
    example.tpzTwo escaping closures share one mutable binding
    1. import std.io
    2. function makeCounters() -> { advance: () -> int, read: () -> int } {
    3. let mut count: int = 0
    4. let advance: () -> int = () => {
    5. count += 1
    6. count
    7. }
    8. let read: () -> int = () => count
    9. count = 4
    10. { advance: advance, read: read }
    11. }
    12. let counters = makeCounters()
    13. io.writeLine("{counters.read()}:{counters.advance()}:{counters.read()}")
    기대 출력종료 코드 0
    4:5:5
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 4:5:5

    Immutable captures retain independent collection values

    링크
    example.tpzImmutable captures retain independent collection values
    1. import std.io
    2. function makeReader() -> () -> string {
    3. let mut current: int = 1
    4. let snapshot: int = current
    5. let items: Array<int> = [10]
    6. let mut alias: Array<int> = items
    7. let read: () -> string = () => "{current}:{snapshot}:{items[0]}"
    8. current = 2
    9. alias[0] = 30
    10. read
    11. }
    12. let read = makeReader()
    13. io.writeLine(read())
    기대 출력종료 코드 0
    2:1:10
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 2:1:10

    A closure cannot reassign an immutable capture

    링크
    example.tpzA closure cannot reassign an immutable capture플레이그라운드 열기 →
    1. function makeReader() -> () -> int {
    2. let count: int = 1
    3. () => {
    4. count = 2
    5. count
    6. }
    7. }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5003 →

      bindings-assignment-to-immutable at example.tpz:4:9

    Call a stored closure after its later binding initializes

    링크
    example.tpzCall a stored closure after its later binding initializes
    1. import std.io
    2. let read: () -> int = () => later
    3. let later: int = 7
    4. io.writeLine("{read()}")
    기대 출력종료 코드 0
    7
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 7

    A skipped branch does not read a later binding

    링크
    example.tpzA skipped branch does not read a later binding
    1. import std.io
    2. let chosen: int = if (false) { after } else { 2 }
    3. let after: int = 7
    4. io.writeLine("{chosen}:{after}")
    기대 출력종료 코드 0
    2:7
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 2:7

    The condition is an immediate initializer read

    링크
    example.tpzThe condition is an immediate initializer read플레이그라운드 열기 →
    1. let chosen: int = if (after) { 1 } else { 2 }
    2. let after: bool = true
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3018 →

      module-initializer-not-ready at example.tpz:1:23

    The direct module initializer uses the same TPZ3018 resolve contract in entry and imported files. Current SELF rejects this entry source with TPZ5002; the existing receipt remains historical evidence for that earlier identity. The expected rejection and location are retained, and only the diagnostic assertion is limited.

    An executed branch faults before a later binding initializes

    링크
    example.tpzAn executed branch faults before a later binding initializes
    1. let chosen: int = if (true) { after } else { 0 }
    2. let after: int = 7
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5002 →

      bindings-direct-forward-read at example.tpz:1:31

    An inner scope may reuse an outer name

    링크
    example.tpzAn inner scope may reuse an outer name
    1. import std.io
    2. let value: int = 1
    3. let inner: int = {
    4. let value: int = 2
    5. value
    6. }
    7. io.writeLine("{value}:{inner}")
    기대 출력종료 코드 0
    1:2
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 1:2

    Module declarations cannot reuse an existing name

    링크
    example.tpzModule declarations cannot reuse an existing name플레이그라운드 열기 →
    1. let value: int = 1
    2. const value: int = 2
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 resolve. 종료 코드가 0이 아닙니다.

    • TPZ3008 →

      bindings-same-scope-redeclaration at example.tpz:2:7

    A local let duplicate retains the intended static rejection

    링크
    example.tpzA local let duplicate retains the intended static rejection플레이그라운드 열기 →
    1. function invalid() -> int {
    2. let value: int = 1
    3. let value: int = 2
    4. value
    5. }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5008 →

      bindings-local-same-scope-redeclaration at example.tpz:3:9

    Constant expressions retain independent collection values

    링크
    example.tpzConstant expressions retain independent collection values
    1. import std.io
    2. const base: int = 2
    3. const bits: int = base.shift(1).or(1)
    4. const rounded: int = (2.2).ceil()
    5. const data = { label: "value-{base}", values: [base, bits] }
    6. let mut alias: Array<int> = data.values
    7. alias[0] = 9
    8. io.writeLine("{data.label}:{bits}:{rounded}:{data.values[0]}")
    기대 출력종료 코드 0
    value-2:5:3:2
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. value-2:5:3:2

    A constant cannot read a later same-module constant

    링크
    example.tpzA constant cannot read a later same-module constant플레이그라운드 열기 →
    1. const before: int = after
    2. const after: int = 7
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5002 →

      bindings-direct-forward-read at example.tpz:1:21

    A permitted named function value remains the expected constant value

    링크
    example.tpzA permitted named function value remains the expected constant value
    1. import std.io
    2. function answer() -> int { 7 }
    3. const saved: () -> int = answer
    4. io.writeLine("{saved()}")
    기대 출력종료 코드 0
    7
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 7

    Store the function value after its declaration executes

    링크
    example.tpzStore the function value after its declaration executes
    1. import std.io
    2. function answer() -> int { 7 }
    3. let saved: () -> int = answer
    4. io.writeLine("{saved()}")
    기대 출력종료 코드 0
    7
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 7

    The local const path checks duplicate names

    링크
    example.tpzThe local const path checks duplicate names플레이그라운드 열기 →
    1. function invalid() -> int {
    2. const value: int = 1
    3. const value: int = 2
    4. value
    5. }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5008 →

      bindings-local-same-scope-redeclaration at example.tpz:3:11

    Repeat a let annotation

    링크
    example.tpzRepeat a let annotation플레이그라운드 열기 →
    1. let answer: int: int = 1
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2001 →

      bindings-duplicate-type-annotation at example.tpz:1:16

    Repeat an exported let annotation

    링크
    example.tpzRepeat an exported let annotation플레이그라운드 열기 →
    1. export let answer: int: int = 1
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2001 →

      bindings-duplicate-type-annotation at example.tpz:1:23

    Repeat a mutable binding annotation

    링크
    example.tpzRepeat a mutable binding annotation플레이그라운드 열기 →
    1. let mut answer: int: int = 1
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2001 →

      bindings-duplicate-type-annotation at example.tpz:1:20

    Repeat a constant annotation

    링크
    example.tpzRepeat a constant annotation플레이그라운드 열기 →
    1. const answer: int: int = 1
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 parse. 종료 코드가 0이 아닙니다.

    • TPZ2001 →

      bindings-duplicate-type-annotation at example.tpz:1:18

    Annotate each binding once

    링크
    example.tpzAnnotate each binding once플레이그라운드 열기 →
    1. let local: int = 1
    2. export let published: int = local
    3. let mut count: int = local
    4. const label: string = "Topaz"
    5. export const publishedLabel: string = label
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Group admitted numeric callees

    링크
    example.tpzGroup admitted numeric callees플레이그라운드 열기 →
    1. const bits: int = ((5).and)(3)
    2. const rounded: int = ((2.2).ceil)()
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Group admitted length callees

    링크
    example.tpzGroup admitted length callees플레이그라운드 열기 →
    1. import std.typeset
    2. const physical: Length<Pt> = ((1in).toPt)()
    3. const relative: Length<Pt> = ((2em).resolve)(12pt)
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    Use admitted calls and a grouped length constructor

    링크
    example.tpzUse admitted calls and a grouped length constructor플레이그라운드 열기 →
    1. import std.typeset
    2. const bits: int = (5).and(3)
    3. const rounded: int = (2.2).ceil()
    4. const physical: Length<Pt> = (1in).toPt()
    5. const relative: Length<Pt> = (2em).resolve(12pt)
    6. const constructed: Length<Pt> = (typeset.fromMilliPoints)(1000)
    기대 출력종료 코드 0
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    검사가 프로그램을 받아들입니다. 종료 코드 0.

    An ordinary call remains a runtime computation

    링크
    example.tpzAn ordinary call remains a runtime computation플레이그라운드 열기 →
    1. function answer() -> int { 3 }
    2. const direct: int = answer()
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      bindings-const-ordinary-call at example.tpz:2:21

    Grouping does not make an ordinary call constant

    링크
    example.tpzGrouping does not make an ordinary call constant플레이그라운드 열기 →
    1. function answer() -> int { 3 }
    2. const grouped: int = (answer)()
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check example.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5001 →

      bindings-const-ordinary-call at example.tpz:2:22

    Assignment keeps array values independent

    링크
    example.tpzAssignment keeps array values independent
    1. import std.io
    2. let a = [1, 2]
    3. let mut b = a
    4. b.push(3)
    5. io.writeLine("{a.length}:{b.length}")
    기대 출력종료 코드 0
    2:3
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 2:3

    Return a changed local value from a function

    링크
    example.tpzReturn a changed local value from a function
    1. import std.io
    2. function appended(values: Array<int>) -> Array<int> {
    3. let mut local = values
    4. local.push(3)
    5. local
    6. }
    7. let items = [1, 2]
    8. let changed = appended(items)
    9. io.writeLine("{items.length}:{changed.length}")
    기대 출력종료 코드 0
    2:3
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 2:3

    A saved record keeps its collection field

    링크
    example.tpzA saved record keeps its collection field
    1. import std.io
    2. let mut r = { items: [1, 2] }
    3. let saved = r
    4. r.items[0] = 5
    5. io.writeLine("{saved.items[0]}:{r.items[0]}")
    기대 출력종료 코드 0
    1:5
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 1:5

    Insert and remove entries in an independent Map value

    링크
    example.tpzInsert and remove entries in an independent Map value
    1. import std.io
    2. let entries = map { "one": 1 }
    3. let mut changed = entries
    4. changed.insert("two", 2)
    5. io.writeLine("{entries.length}:{changed.length}")
    6. changed.remove("one")
    7. io.writeLine("{entries.keys[0]}:{changed.keys[0]}")
    기대 출력종료 코드 0
    1:2
    one:two
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 1:2
    2. one:two

    Add and remove members in an independent Set value

    링크
    example.tpzAdd and remove members in an independent Set value
    1. import std.io
    2. let values = set { 1 }
    3. let mut changed = values
    4. changed.add(2)
    5. io.writeLine("{values.length}:{changed.length}")
    6. changed.remove(1)
    7. io.writeLine("{1 in values}:{1 in changed}")
    기대 출력종료 코드 0
    1:2
    true:false
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 1:2
    2. true:false

    A mutable capture changes one variable and preserves earlier values

    링크
    example.tpzA mutable capture changes one variable and preserves earlier values
    1. import std.io
    2. let mut items = [1]
    3. let before = items
    4. let append: () -> () = () => { items.push(2) }
    5. append()
    6. io.writeLine("{items.length}:{before.length}")
    기대 출력종료 코드 0
    2:1
    
    $ topaz run example.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 2:1

    Pending

    링크

    Related references

    링크

    Types →

    Functions and generics →

    TPZ5001 →

    Reserved binding name →

    Invalid assignment target →

    Immutable binding mutation →

    Unbound name →

    Module namespace collision →

    Redeclaration →

    Unexpected token →

    Initializer reads a later binding →

    메뉴

    다운로드 →